chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:32:25 +08:00
commit e014feafe1
2285 changed files with 1131979 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
// 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 tables
import (
"github.com/dolthub/dolt/go/libraries/doltcore/sqle"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/utils"
)
// Database is a wrapper around Dolt's database object, allowing for functionality specific to Doltgres (such as system
// tables).
type Database struct {
db sqle.Database
}
var _ sql.DatabaseSchema = Database{}
// GetTableInsensitive implements the interface sql.DatabaseSchema.
func (d Database) GetTableInsensitive(ctx *sql.Context, tblName string) (sql.Table, bool, error) {
// Even though this is named "GetTableInsensitive", due to differences in Postgres and MySQL, this should perform an
// exact search.
if tableMap, ok := handlers[d.db.Schema()]; ok {
if handler, ok := tableMap[tblName]; ok {
return NewVirtualTable(handler, d.db), true, nil
}
}
return nil, false, nil
}
// GetTableNames implements the interface sql.DatabaseSchema.
func (d Database) GetTableNames(ctx *sql.Context) ([]string, error) {
tableMap := handlers[d.db.Schema()]
return utils.GetMapKeysSorted(tableMap), nil
}
// Name implements the interface sql.DatabaseSchema.
func (d Database) Name() string {
return d.db.Name()
}
func (d Database) SchemaName() string {
return d.db.SchemaName()
}
@@ -0,0 +1,75 @@
// 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 dtables
import (
"github.com/dolthub/dolt/go/store/prolly"
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// getDoltConstraintViolationsSchema returns the base schema for the dolt_constraint_violations_* table.
func getDoltConstraintViolationsBaseSqlSchema() sql.Schema {
return []*sql.Column{
{Name: "from_root_ish", Type: pgtypes.Text, PrimaryKey: false, Nullable: true},
{Name: "violation_type", Type: pgtypes.MustCreateNewVarCharType(16), PrimaryKey: true},
}
}
// mapCVType maps a prolly.ArtifactType to a string.
func mapCVType(artifactType prolly.ArtifactType) any {
return mapCVTypeString(artifactType)
}
func mapCVTypeString(artifactType prolly.ArtifactType) (outType string) {
switch artifactType {
case prolly.ArtifactTypeForeignKeyViol:
outType = "foreign key"
case prolly.ArtifactTypeUniqueKeyViol:
outType = "unique index"
case prolly.ArtifactTypeChkConsViol:
outType = "check constraint"
case prolly.ArtifactTypeNullViol:
outType = "not null"
default:
panic("unhandled cv type")
}
return
}
// unmapCVType unmaps a string to a prolly.ArtifactType.
func unmapCVType(in any) (out prolly.ArtifactType) {
if cv, ok := in.(string); ok {
return unmapCVTypeString(cv)
}
panic("invalid type")
}
func unmapCVTypeString(in string) (out prolly.ArtifactType) {
switch in {
case "foreign key":
out = prolly.ArtifactTypeForeignKeyViol
case "unique index":
out = prolly.ArtifactTypeUniqueKeyViol
case "check constraint":
out = prolly.ArtifactTypeChkConsViol
case "not null":
out = prolly.ArtifactTypeNullViol
default:
panic("unhandled cv type")
}
return
}
+43
View File
@@ -0,0 +1,43 @@
// 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 dtables
import (
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// getUnscopedDoltDiffSchema returns the schema for the diff table.
func getUnscopedDoltDiffSchema(dbName, tableName string) sql.Schema {
return []*sql.Column{
{Name: "commit_hash", Type: pgtypes.Text, Source: tableName, PrimaryKey: true, DatabaseSource: dbName},
{Name: "table_name", Type: pgtypes.Text, Source: tableName, PrimaryKey: true, DatabaseSource: dbName},
{Name: "committer", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "email", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "date", Type: pgtypes.Timestamp, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "message", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "data_change", Type: pgtypes.Bool, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "schema_change", Type: pgtypes.Bool, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "author", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "author_email", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
{Name: "author_date", Type: pgtypes.Timestamp, Source: tableName, PrimaryKey: false, DatabaseSource: dbName},
}
}
// getDiffTableName returns the name of the diff table.
func getDiffTableName() string {
return "diff"
}
+36
View File
@@ -0,0 +1,36 @@
// 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 dtables
import (
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
)
// getDocsSchema returns the schema for the docs table.
func getDocsSchema() sql.Schema {
return []*sql.Column{
{Name: doltdb.DocPkColumnName, Type: pgtypes.Text, Source: getDocTableName(), PrimaryKey: true, Nullable: false},
{Name: doltdb.DocTextColumnName, Type: pgtypes.Text, Source: getDocTableName(), PrimaryKey: false},
}
}
// getDocTableName returns the name of the docs table.
func getDocTableName() string {
return "docs"
}
+81
View File
@@ -0,0 +1,81 @@
// 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 dtables
import (
"context"
"fmt"
"github.com/cockroachdb/errors"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/store/val"
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// getDoltIgnoreSchema returns the schema for the dolt_ignore table.
func getDoltIgnoreSchema() sql.Schema {
return []*sql.Column{
{Name: "pattern", Type: pgtypes.Text, Source: doltdb.IgnoreTableName, PrimaryKey: true},
{Name: "ignored", Type: pgtypes.Bool, Source: doltdb.IgnoreTableName, PrimaryKey: false, Nullable: false},
}
}
// convertTupleToIgnoreBoolean reads a boolean from a tuple and returns it.
func convertTupleToIgnoreBoolean(ctx context.Context, valueDesc *val.TupleDesc, valueTuple val.Tuple) (bool, error) {
extendedTuple := val.NewTupleDescriptorWithArgs(
val.TupleDescriptorArgs{Comparator: valueDesc.Comparator(), Handlers: valueDesc.Handlers},
val.Type{Enc: val.ExtendedEnc, Nullable: false},
)
if !valueDesc.Equals(extendedTuple) {
return false, errors.Errorf("dolt_ignore had unexpected value type, this should never happen")
}
extended, ok := valueDesc.GetExtended(0, valueTuple)
if !ok {
return false, errors.Errorf("could not read boolean")
}
val, err := valueDesc.Handlers[0].DeserializeValue(ctx, extended)
if err != nil {
return false, err
}
ignore, ok := val.(bool)
if !ok {
return false, errors.Errorf("could not read boolean")
}
return ignore, nil
}
// getIgnoreTablePatternKey reads the pattern key from a tuple and returns it.
func getIgnoreTablePatternKey(ctx context.Context, keyDesc *val.TupleDesc, keyTuple val.Tuple) (string, error) {
key, ok, err := keyDesc.GetStringAdaptiveValue(ctx, 0, nil, keyTuple)
if err != nil {
return "", err
}
if !ok {
return "", fmt.Errorf("could not read pattern")
}
unwrapped, ok, err := sql.Unwrap[string](ctx, key)
if err != nil {
return "", err
}
if !ok {
return "", fmt.Errorf("could not read pattern")
}
return unwrapped, nil
}
+119
View File
@@ -0,0 +1,119 @@
// 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 dtables
import (
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/merge"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/adapters"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dprocedures"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
)
// Init handles initialization of all Postgres-specific and Doltgres-specific Dolt system tables.
func Init() {
adapters.DoltTableAdapterRegistry.AddAdapter(doltdb.StatusTableName, DoltgresDoltStatusTableAdapter{}, DoltgresDoltStatusTableName)
adapters.DoltTableAdapterRegistry.AddAdapter(doltdb.StatusIgnoredTableName, DoltgresDoltStatusIgnoredTableAdapter{}, DoltgresDoltStatusIgnoredTableName)
// Table names
doltdb.GetBranchesTableName = getBranchesTableName
doltdb.GetDocTableName = getDocTableName
doltdb.GetColumnDiffTableName = getColumnDiffTableName
doltdb.GetCommitAncestorsTableName = getCommitAncestorsTableName
doltdb.GetCommitsTableName = getCommitsTableName
doltdb.GetDiffTableName = getDiffTableName
doltdb.GetLogTableName = getLogTableName
doltdb.GetMergeStatusTableName = getMergeStatusTableName
doltdb.GetRebaseTableName = getRebaseTableName
doltdb.GetRemoteBranchesTableName = getRemoteBranchesTableName
doltdb.GetRemotesTableName = getRemotesTableName
doltdb.GetSchemaConflictsTableName = getSchemaConflictsTableName
doltdb.GetTableOfTablesInConflictName = getTableOfTablesInConflictName
doltdb.GetTableOfTablesWithViolationsName = getTableOfTablesWithViolationsName
doltdb.GetTagsTableName = getTagsTableName
// Schemas
dtables.GetDocsSchema = getDocsSchema
dtables.GetDoltConstraintViolationsBaseSqlSchema = getDoltConstraintViolationsBaseSqlSchema
dtables.GetDoltIgnoreSchema = getDoltIgnoreSchema
dtables.GetDoltMergeStatusSchema = getDoltMergeStatusSchema
dprocedures.GetDoltRebaseSystemTableSchema = getRebaseSchema
dtables.GetUnscopedDoltDiffSchema = getUnscopedDoltDiffSchema
dtables.GetDoltWorkspaceBaseSqlSchema = getDoltWorkspaceBaseSqlSchema
// Conversions
doltdb.ConvertTupleToIgnoreBoolean = convertTupleToIgnoreBoolean
doltdb.GetIgnoreTablePatternKey = getIgnoreTablePatternKey
sqle.ConvertRebasePlanStepToRow = convertRebasePlanStepToRow
sqle.ConvertRowToRebasePlanStep = convertRowToRebasePlanStep
merge.MapCVType = mapCVType
merge.UnmapCVType = unmapCVType
}
// getBranchesTableName returns the name of the branches table.
func getBranchesTableName() string {
return "branches"
}
// getColumnDiffTableName returns the name of the column diff table.
func getColumnDiffTableName() string {
return "column_diff"
}
// getCommitAncestorsTableName returns the name of the commit ancestors table.
func getCommitAncestorsTableName() string {
return "commit_ancestors"
}
// getCommitsTableName returns the name of the commits table.
func getCommitsTableName() string {
return "commits"
}
// getLogTableName returns the name of the branches table.
func getLogTableName() string {
return "log"
}
// getRemoteBranchesTableName returns the name of the remote branches table.
func getRemoteBranchesTableName() string {
return "remote_branches"
}
// getRemotesTableName returns the name of the remotes table.
func getRemotesTableName() string {
return "remotes"
}
// getSchemaConflictsTableName returns the name of the schema conflicts table.
func getSchemaConflictsTableName() string {
return "schema_conflicts"
}
// getTableOfTablesInConflictName returns the name of the conflicts table.
func getTableOfTablesInConflictName() string {
return "conflicts"
}
// getTableOfTablesWithViolationsName returns the name of the constraint violations table.
func getTableOfTablesWithViolationsName() string {
return "constraint_violations"
}
// getTagsTableName returns the name of the tags table.
func getTagsTableName() string {
return "tags"
}
+37
View File
@@ -0,0 +1,37 @@
// 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 dtables
import (
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// getDoltMergeStatusSchema returns the schema for the merge_status table.
func getDoltMergeStatusSchema(dbName, tableName string) sql.Schema {
return []*sql.Column{
{Name: "is_merging", Type: pgtypes.Bool, Source: tableName, PrimaryKey: false, Nullable: false, DatabaseSource: dbName},
{Name: "source", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, Nullable: true, DatabaseSource: dbName},
{Name: "source_commit", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, Nullable: true, DatabaseSource: dbName},
{Name: "target", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, Nullable: true, DatabaseSource: dbName},
{Name: "unmerged_tables", Type: pgtypes.Text, Source: tableName, PrimaryKey: false, Nullable: true, DatabaseSource: dbName},
}
}
// getMergeStatusTableName returns the name of the merge status table.
func getMergeStatusTableName() string {
return "merge_status"
}
+102
View File
@@ -0,0 +1,102 @@
// 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 dtables
import (
"context"
"strings"
"github.com/cockroachdb/errors"
"github.com/dolthub/dolt/go/libraries/doltcore/rebase"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dprocedures"
"github.com/dolthub/go-mysql-server/sql"
gmstypes "github.com/dolthub/go-mysql-server/sql/types"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// getRebaseSchema returns the schema for the rebase table.
func getRebaseSchema() sql.Schema {
return []*sql.Column{
{Name: "rebase_order", Type: pgtypes.Float32, Nullable: false, PrimaryKey: true}, // TODO: cannot have numeric key
{Name: "action", Type: pgtypes.MustCreateNewVarCharType(6), Nullable: false}, // TODO: Should be enum(pick, squash, fixup, drop, reword)
{Name: "commit_hash", Type: pgtypes.Text, Nullable: false},
{Name: "commit_message", Type: pgtypes.Text, Nullable: false},
}
}
// convertRebasePlanStepToRow converts a RebasePlanStep to a sql.Row.
func convertRebasePlanStepToRow(planMember rebase.RebasePlanStep) (sql.Row, error) {
actionEnumValue := dprocedures.RebaseActionEnumType.IndexOf(strings.ToLower(planMember.Action))
if actionEnumValue == -1 {
return nil, errors.Errorf("invalid rebase action: %s", planMember.Action)
}
return sql.Row{
planMember.RebaseOrderAsFloat(),
planMember.Action,
planMember.CommitHash,
planMember.CommitMsg,
}, nil
}
// convertRowToRebasePlanStep converts a sql.Row to a RebasePlanStep.
func convertRowToRebasePlanStep(ctx context.Context, row sql.Row) (rebase.RebasePlanStep, error) {
order, ok := row[0].(float32)
if !ok {
return rebase.RebasePlanStep{}, errors.Errorf("invalid order value in rebase plan: %v (%T)", row[0], row[0])
}
rebaseAction, ok, err := sql.Unwrap[string](ctx, row[1])
if err != nil {
return rebase.RebasePlanStep{}, err
}
if !ok {
return rebase.RebasePlanStep{}, errors.Errorf("unexpected type for rebase action: expected string, got: %v (%T)", row[1], row[1])
}
rebaseIdx := dprocedures.RebaseActionEnumType.IndexOf(rebaseAction)
if rebaseIdx < 0 {
return rebase.RebasePlanStep{}, errors.Errorf("invalid enum value in rebase plan: %v (%T)", row[1], row[1])
}
commitHash, ok, err := sql.Unwrap[string](ctx, row[2])
if err != nil {
return rebase.RebasePlanStep{}, err
}
if !ok {
return rebase.RebasePlanStep{}, errors.Errorf("unexpected type for commit hash: expected string, got: %v (%T)", row[2], row[2])
}
commitMsg, ok, err := sql.Unwrap[string](ctx, row[3])
if err != nil {
return rebase.RebasePlanStep{}, err
}
if !ok {
return rebase.RebasePlanStep{}, errors.Errorf("unexpected type for commit message: expected string, got: %v (%T)", row[3], row[3])
}
return rebase.RebasePlanStep{
RebaseOrder: gmstypes.DecimalFromFloat32(order),
Action: rebaseAction,
CommitHash: commitHash,
CommitMsg: commitMsg,
}, nil
}
// getRebaseTableName returns the name of the rebase table.
func getRebaseTableName() string {
return "rebase"
}
+144
View File
@@ -0,0 +1,144 @@
// 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 dtables
import (
"fmt"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/adapters"
doltdtables "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// DoltgresDoltStatusTableAdapter adapts the [doltdtables.StatusTable] into a Doltgres-compatible version.
//
// DoltgresDoltStatusTableAdapter implements the [adapters.TableAdapter] interface.
type DoltgresDoltStatusTableAdapter struct{}
var _ adapters.TableAdapter = DoltgresDoltStatusTableAdapter{}
// NewTable returns a new [sql.Table] for Doltgres' version of [doltdtables.StatusTable].
func (a DoltgresDoltStatusTableAdapter) NewTable(ctx *sql.Context, tableName string, ddb *doltdb.DoltDB, ws *doltdb.WorkingSet, rp env.RootsProvider[*sql.Context]) sql.Table {
doltTable := doltdtables.NewStatusTableWithNoAdapter(ctx, tableName, ddb, ws, rp)
return &doltgresDoltStatusTable{
srcDoltStatus: doltTable.(*doltdtables.StatusTable),
}
}
// TableName returns the table name for Doltgres' version of [doltdtables.StatusTable].
func (a DoltgresDoltStatusTableAdapter) TableName() string {
return DoltgresDoltStatusTableName
}
// DoltgresDoltStatusTableName is the name of Dolt's status table following Doltgres' naming conventions.
const DoltgresDoltStatusTableName = "status"
// doltgresDoltStatusTable translates the [doltdtables.StatusTable] into a Doltgres-compatible version.
//
// doltgresDoltStatusTable implements the [sql.Table] and [sql.StatisticsTable] interfaces.
type doltgresDoltStatusTable struct {
srcDoltStatus *doltdtables.StatusTable
}
var _ sql.Table = (*doltgresDoltStatusTable)(nil)
var _ sql.StatisticsTable = (*doltgresDoltStatusTable)(nil)
// Name returns the name of Doltgres' version of the Dolt status table.
func (w *doltgresDoltStatusTable) Name() string {
return w.srcDoltStatus.Name()
}
// Schema returns the schema for Doltgres' version of the Dolt status table.
func (w *doltgresDoltStatusTable) Schema(ctx *sql.Context) sql.Schema {
return []*sql.Column{
{Name: "table_name", Type: pgtypes.Text, Source: DoltgresDoltStatusTableName, PrimaryKey: true, Nullable: false},
{Name: "staged", Type: pgtypes.Bool, Source: DoltgresDoltStatusTableName, PrimaryKey: true, Nullable: false},
{Name: "status", Type: pgtypes.Text, Source: DoltgresDoltStatusTableName, PrimaryKey: true, Nullable: false},
}
}
// String returns the string representation of [doltdtables.StatusTable].
func (w *doltgresDoltStatusTable) String() string {
return w.srcDoltStatus.String()
}
// Collation returns the [sql.CollationID] from [doltdtables.StatusTable].
func (w *doltgresDoltStatusTable) Collation() sql.CollationID {
return w.srcDoltStatus.Collation()
}
// Partitions returns a [sql.PartitionIter] on the partitions of [doltdtables.StatusTable].
func (w *doltgresDoltStatusTable) Partitions(ctx *sql.Context) (sql.PartitionIter, error) {
return w.srcDoltStatus.Partitions(ctx)
}
// PartitionRows returns a wrapped [sql.RowIter] for the rows in |partition| from
// [doltdtables.StatusTable.PartitionRows] to later apply column transformations that match Doltgres' version of the
// Dolt status table schema.
func (w *doltgresDoltStatusTable) PartitionRows(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
iter, err := w.srcDoltStatus.PartitionRows(ctx, partition)
if err != nil {
return nil, err
}
return &doltgresDoltStatusRowIter{w, iter}, nil
}
// DataLength returns the length of the data in bytes from [doltdtables.StatusTable].
func (w *doltgresDoltStatusTable) DataLength(ctx *sql.Context) (uint64, error) {
return w.srcDoltStatus.DataLength(ctx)
}
// RowCount returns exact (true) or estimate (false) number of rows from [doltdtables.StatusTable].
func (w *doltgresDoltStatusTable) RowCount(ctx *sql.Context) (uint64, bool, error) {
return w.srcDoltStatus.RowCount(ctx)
}
// doltgresDoltStatusRowIter wraps [doltdtables.StatusTable] [sql.RowIter] and applies transformations before returning
// its rows to make sure they're compatible with Doltgres' version of Dolt's status table.
type doltgresDoltStatusRowIter struct {
doltStatusTable sql.Table
rowIter sql.RowIter
}
var _ sql.RowIter = (*doltgresDoltStatusRowIter)(nil)
// Next converts the 'staged' column from [doltdtables.StatusTable.Schema] from a byte into a bool since, unlike the
// MySQL wire protocol, Doltgres has a real bool type.
func (i *doltgresDoltStatusRowIter) Next(ctx *sql.Context) (sql.Row, error) {
row, err := i.rowIter.Next(ctx)
if err != nil {
return nil, err
}
// Dolt uses byte to avoid MySQL wire protocol ambiguity on tinyint(1) and bool.
// See: https://github.com/dolthub/dolt/pull/10117
stagedIndex := i.doltStatusTable.Schema(ctx).IndexOfColName("staged")
stagedVal, ok := row[stagedIndex].(byte)
if !ok {
return nil, fmt.Errorf("expected staged column at index %d to be byte, got %T", stagedIndex, row[stagedIndex])
}
row[stagedIndex] = stagedVal != 0
return row, nil
}
// Close closes the wrapped [doltdtables.StatusTable] [sql.RowIter].
func (i *doltgresDoltStatusRowIter) Close(ctx *sql.Context) error {
return i.rowIter.Close(ctx)
}
+145
View File
@@ -0,0 +1,145 @@
// Copyright 2026 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 dtables
import (
"fmt"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/env"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/adapters"
doltdtables "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables"
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// DoltgresDoltStatusIgnoredTableAdapter adapts the [doltdtables.StatusIgnoredTable] into a Doltgres-compatible version.
//
// DoltgresDoltStatusIgnoredTableAdapter implements the [adapters.TableAdapter] interface.
type DoltgresDoltStatusIgnoredTableAdapter struct{}
var _ adapters.TableAdapter = DoltgresDoltStatusIgnoredTableAdapter{}
// NewTable returns a new [sql.Table] for Doltgres' version of [doltdtables.StatusIgnoredTable].
func (a DoltgresDoltStatusIgnoredTableAdapter) NewTable(ctx *sql.Context, tableName string, ddb *doltdb.DoltDB, ws *doltdb.WorkingSet, rp env.RootsProvider[*sql.Context]) sql.Table {
doltTable := doltdtables.NewStatusIgnoredTableWithNoAdapter(ctx, tableName, ddb, ws, rp)
return &doltgresDoltStatusIgnoredTable{
srcDoltStatusIgnored: doltTable.(*doltdtables.StatusIgnoredTable),
}
}
// TableName returns the table name for Doltgres' version of [doltdtables.StatusIgnoredTable].
func (a DoltgresDoltStatusIgnoredTableAdapter) TableName() string {
return DoltgresDoltStatusIgnoredTableName
}
// DoltgresDoltStatusIgnoredTableName is the name of Dolt's status_ignored table following Doltgres' naming conventions.
const DoltgresDoltStatusIgnoredTableName = "status_ignored"
// doltgresDoltStatusIgnoredTable translates the [doltdtables.StatusIgnoredTable] into a Doltgres-compatible version.
//
// doltgresDoltStatusIgnoredTable implements the [sql.Table] and [sql.StatisticsTable] interfaces.
type doltgresDoltStatusIgnoredTable struct {
srcDoltStatusIgnored *doltdtables.StatusIgnoredTable
}
var _ sql.Table = (*doltgresDoltStatusIgnoredTable)(nil)
var _ sql.StatisticsTable = (*doltgresDoltStatusIgnoredTable)(nil)
// Name returns the name of Doltgres' version of the Dolt status_ignored table.
func (w *doltgresDoltStatusIgnoredTable) Name() string {
return w.srcDoltStatusIgnored.Name()
}
// Schema returns the schema for Doltgres' version of the Dolt status_ignored table.
func (w *doltgresDoltStatusIgnoredTable) Schema(ctx *sql.Context) sql.Schema {
return []*sql.Column{
{Name: "table_name", Type: pgtypes.Text, Source: DoltgresDoltStatusIgnoredTableName, PrimaryKey: true, Nullable: false},
{Name: "staged", Type: pgtypes.Bool, Source: DoltgresDoltStatusIgnoredTableName, PrimaryKey: true, Nullable: false},
{Name: "status", Type: pgtypes.Text, Source: DoltgresDoltStatusIgnoredTableName, PrimaryKey: true, Nullable: false},
{Name: "ignored", Type: pgtypes.Bool, Source: DoltgresDoltStatusIgnoredTableName, PrimaryKey: false, Nullable: false},
}
}
// String returns the string representation of [doltdtables.StatusIgnoredTable].
func (w *doltgresDoltStatusIgnoredTable) String() string {
return w.srcDoltStatusIgnored.String()
}
// Collation returns the [sql.CollationID] from [doltdtables.StatusIgnoredTable].
func (w *doltgresDoltStatusIgnoredTable) Collation() sql.CollationID {
return w.srcDoltStatusIgnored.Collation()
}
// Partitions returns a [sql.PartitionIter] on the partitions of [doltdtables.StatusIgnoredTable].
func (w *doltgresDoltStatusIgnoredTable) Partitions(ctx *sql.Context) (sql.PartitionIter, error) {
return w.srcDoltStatusIgnored.Partitions(ctx)
}
// PartitionRows returns a wrapped [sql.RowIter] for the rows in |partition| from
// [doltdtables.StatusIgnoredTable.PartitionRows] to later apply column transformations that match Doltgres' version of the
// Dolt status_ignored table schema.
func (w *doltgresDoltStatusIgnoredTable) PartitionRows(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
iter, err := w.srcDoltStatusIgnored.PartitionRows(ctx, partition)
if err != nil {
return nil, err
}
return &doltgresDoltStatusIgnoredRowIter{w, iter}, nil
}
// DataLength returns the length of the data in bytes from [doltdtables.StatusIgnoredTable].
func (w *doltgresDoltStatusIgnoredTable) DataLength(ctx *sql.Context) (uint64, error) {
return w.srcDoltStatusIgnored.DataLength(ctx)
}
// RowCount returns exact (true) or estimate (false) number of rows from [doltdtables.StatusIgnoredTable].
func (w *doltgresDoltStatusIgnoredTable) RowCount(ctx *sql.Context) (uint64, bool, error) {
return w.srcDoltStatusIgnored.RowCount(ctx)
}
// doltgresDoltStatusIgnoredRowIter wraps [doltdtables.StatusIgnoredTable] [sql.RowIter] and applies transformations before returning
// its rows to make sure they're compatible with Doltgres' version of Dolt's status_ignored table.
type doltgresDoltStatusIgnoredRowIter struct {
doltStatusIgnoredTable sql.Table
rowIter sql.RowIter
}
var _ sql.RowIter = (*doltgresDoltStatusIgnoredRowIter)(nil)
// Next converts the 'staged' column from [doltdtables.StatusIgnoredTable.Schema] from byte into bool since,
// unlike the MySQL wire protocol, Doltgres has a real bool type.
func (i *doltgresDoltStatusIgnoredRowIter) Next(ctx *sql.Context) (sql.Row, error) {
row, err := i.rowIter.Next(ctx)
if err != nil {
return nil, err
}
// Dolt uses byte to avoid MySQL wire protocol ambiguity on tinyint(1) and bool.
// See: https://github.com/dolthub/dolt/pull/10117
stagedIndex := i.doltStatusIgnoredTable.Schema(ctx).IndexOfColName("staged")
stagedVal, ok := row[stagedIndex].(byte)
if !ok {
return nil, fmt.Errorf("expected staged column at index %d to be byte, got %T", stagedIndex, row[stagedIndex])
}
row[stagedIndex] = stagedVal != 0
return row, nil
}
// Close closes the wrapped [doltdtables.StatusIgnoredTable] [sql.RowIter].
func (i *doltgresDoltStatusIgnoredRowIter) Close(ctx *sql.Context) error {
return i.rowIter.Close(ctx)
}
+30
View File
@@ -0,0 +1,30 @@
// 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 dtables
import (
"github.com/dolthub/go-mysql-server/sql"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// getDoltWorkspaceBaseSqlSchema returns the base sql schema for the dolt_workspace_* table.
func getDoltWorkspaceBaseSqlSchema() sql.Schema {
return []*sql.Column{
{Name: "id", Type: pgtypes.Int64, PrimaryKey: true, Nullable: false},
{Name: "staged", Type: pgtypes.Bool, Nullable: false},
{Name: "diff_type", Type: pgtypes.Text, Nullable: false},
}
}
+48
View File
@@ -0,0 +1,48 @@
// 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 tables
import "github.com/dolthub/go-mysql-server/sql"
// Handler is an interface that controls how data is represented for some table.
type Handler interface {
// Name returns the name of the table.
Name() string
// RowIter returns a sql.RowIter that returns the rows of the table.
RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error)
// PkSchema returns the table's schema.
PkSchema() sql.PrimaryKeySchema
}
type IndexedTableHandler interface {
Handler
// Indexes returns the table's indexes.
Indexes() ([]sql.Index, error)
// LookupPartitions returns a sql.PartitionIter that can be used to look up rows in the table using the given lookup
LookupPartitions(context *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error)
}
// handlers is a map from the schema name, to the table name, to the handler.
var handlers = map[string]map[string]Handler{}
// AddHandler adds the given handler to the handler set.
func AddHandler(schemaName string, tableName string, handler Handler) {
tableMap, ok := handlers[schemaName]
if !ok {
tableMap = make(map[string]Handler)
handlers[schemaName] = tableMap
}
tableMap[tableName] = handler
}
@@ -0,0 +1,400 @@
// 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 information_schema
import (
"strings"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
"github.com/dolthub/go-mysql-server/sql/types"
"github.com/dolthub/vitess/go/sqltypes"
"github.com/dolthub/vitess/go/vt/proto/query"
"github.com/lib/pq/oid"
"github.com/dolthub/doltgresql/core/id"
partypes "github.com/dolthub/doltgresql/postgres/parser/types"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// maxCharacterLength is the maximum character length for a column.
const maxCharacterOctetLength = 1073741824
// typeToNumericPrecision is a map of sqltypes to their respective numeric precision.
var typeToNumericPrecision = map[query.Type]int32{
sqltypes.Int8: 3,
sqltypes.Int16: 16,
sqltypes.Int32: 32,
sqltypes.Int64: 64,
sqltypes.Float32: 24,
sqltypes.Float64: 53,
}
// newColumnsTable creates a new information_schema.COLUMNS table.
func newColumnsTable() *information_schema.ColumnsTable {
return &information_schema.ColumnsTable{
TableName: information_schema.ColumnsTableName,
TableSchema: columnsSchema,
RowIter: columnsRowIter,
}
}
// columnsSchema is the schema for the information_schema.columns table.
var columnsSchema = sql.Schema{
{Name: "table_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "table_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "table_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "column_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "ordinal_position", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "column_default", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "is_nullable", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "data_type", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "character_maximum_length", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "character_octet_length", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "numeric_precision", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "numeric_precision_radix", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "numeric_scale", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "datetime_precision", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "interval_type", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "interval_precision", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "character_set_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "character_set_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "character_set_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "collation_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "collation_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "collation_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "domain_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "domain_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "domain_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "udt_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "udt_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "udt_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "scope_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "scope_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "scope_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "maximum_cardinality", Type: cardinal_number, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "dtd_identifier", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "is_self_referencing", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "is_identity", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "identity_generation", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "identity_start", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "identity_increment", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "identity_maximum", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "identity_minimum", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "identity_cycle", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "is_generated", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "generation_expression", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
{Name: "is_updatable", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ColumnsTableName},
}
// columnsRowIter implements the custom sql.RowIter for the information_schema.columns table.
func columnsRowIter(ctx *sql.Context, catalog sql.Catalog, allColsWithDefaultValue sql.Schema) (sql.RowIter, error) {
var rows []sql.Row
databases, err := information_schema.AllDatabasesWithNames(ctx, catalog, false)
if err != nil {
return nil, err
}
for _, db := range databases {
rs, err := getRowsFromDatabase(ctx, db, allColsWithDefaultValue)
if err != nil {
return nil, err
}
rows = append(rows, rs...)
rs, err = getRowsFromViews(ctx, db)
if err != nil {
return nil, err
}
rows = append(rows, rs...)
}
return sql.RowsToRowIter(rows...), nil
}
// getRowFromColumn returns a single row for given column. The arguments passed
// are used to define all row values. These include the current ordinal
// position, so this column will get the next position number, sql.Column
// object, database name, and table name.
func getRowFromColumn(ctx *sql.Context, curOrdPos int, col *sql.Column, catName, schName, tblName string) sql.Row {
var (
ordinalPos = int32(curOrdPos + 1)
nullable = "NO"
isGenerated = "NEVER"
)
dataType, udtName := getDataAndUdtType(col.Type, col.Name)
if col.Nullable {
nullable = "YES"
}
if col.Generated != nil {
isGenerated = "ALWAYS"
}
charName, collName, charMaxLen, charOctetLen := getCharAndCollNamesAndCharMaxAndOctetLens(ctx, col.Type)
numericPrecision, numericPrecisionRadix, numericScale := getColumnPrecisionAndScale(col.Type)
datetimePrecision := getDatetimePrecision(col.Type)
columnDefault := information_schema.GetColumnDefault(ctx, col.Default)
return sql.Row{
catName, // table_catalog
schName, // table_schema
tblName, // table_name
col.Name, // column_name
ordinalPos, // ordinal_position
columnDefault, // column_default
nullable, // is_nullable
dataType, // data_type
charMaxLen, // character_maximum_length
charOctetLen, // character_octet_length
numericPrecision, // numeric_precision
numericPrecisionRadix, // numeric_precision_radix
numericScale, // numeric_scale
datetimePrecision, // datetime_precision
nil, // interval_type TODO
nil, // interval_precision TODO
nil, // character_set_catalog TODO
nil, // character_set_schema TODO
charName, // character_set_name
nil, // collation_catalog TODO
nil, // collation_schema TODO
collName, // collation_name
nil, // domain_catalog TODO
nil, // domain_schema TODO
nil, // domain_name TODO
catName, // udt_catalog
"pg_catalog", // udt_schema
udtName, // udt_name
nil, // scope_catalog TODO
nil, // scope_schema TODO
nil, // scope_name TODO
nil, // maximum_cardinality TODO
nil, // dtd_identifier TODO
"NO", // is_self_referencing TODO
"NO", // is_identity TODO
nil, // identity_generation TODO
nil, // identity_start TODO
nil, // identity_increment TODO
nil, // identity_maximum TODO
nil, // identity_minimum TODO
"NO", // identity_cycle TODO
isGenerated, // is_generated
nil, // generation_expression TODO
"YES", // is_updatable
}
}
// getRowsFromTable returns array of rows for all accessible columns of the given table.
func getRowsFromTable(ctx *sql.Context, db information_schema.DbWithNames, t sql.Table, allColsWithDefaultValue sql.Schema) ([]sql.Row, error) {
var rows []sql.Row
tblName := t.Name()
for i, col := range information_schema.SchemaForTable(t, db.Database, allColsWithDefaultValue) {
if col.HiddenSystem {
continue
}
r := getRowFromColumn(ctx, i, col, db.CatalogName, db.SchemaName, tblName)
if r != nil {
rows = append(rows, r)
}
}
return rows, nil
}
// getRowsFromViews returns array or rows for columns for all views for given database.
func getRowsFromViews(ctx *sql.Context, db information_schema.DbWithNames) ([]sql.Row, error) {
var rows []sql.Row
// TODO: View Definition is lacking information to properly fill out these table
// TODO: Should somehow get reference to table(s) view is referencing
// TODO: Each column that view references should also show up as unique entries as well
views, err := information_schema.ViewsInDatabase(ctx, db.Database)
if err != nil {
return nil, err
}
for _, view := range views {
rows = append(rows, sql.Row{
db.CatalogName, // table_catalog
db.SchemaName, // table_schema
view.Name, // table_name
"", // column_name
int32(0), // ordinal_position
nil, // column_default
"YES", // is_nullable
nil, // data_type
nil, // character_maximum_length
nil, // character_octet_length
nil, // numeric_precision
nil, // numeric_precision_radix
nil, // numeric_scale
nil, // datetime_precision
nil, // interval_type
nil, // interval_precision
nil, // character_set_catalog
nil, // character_set_schema
nil, // character_set_name
nil, // collation_catalog
nil, // collation_schema
nil, // collation_name
nil, // domain_catalog
nil, // domain_schema
nil, // domain_name
nil, // udt_catalog
nil, // udt_schema
nil, // udt_name
nil, // scope_catalog
nil, // scope_schema
nil, // scope_name
nil, // maximum_cardinality
nil, // dtd_identifier
"NO", // is_self_referencing
"NO", // is_identity
nil, // identity_generation
nil, // identity_start
nil, // identity_increment
nil, // identity_maximum
nil, // identity_minimum
"NO", // identity_cycle
"NO", // is_generated
nil, // generation_expression
"YES", // is_updatable
})
}
return rows, nil
}
// getRowsFromDatabase returns array of rows for all accessible columns of accessible table of the given database.
func getRowsFromDatabase(ctx *sql.Context, db information_schema.DbWithNames, allColsWithDefaultValue sql.Schema) ([]sql.Row, error) {
var rows []sql.Row
err := sql.DBTableIter(ctx, db.Database, func(t sql.Table) (cont bool, err error) {
rs, err := getRowsFromTable(ctx, db, t, allColsWithDefaultValue)
if err != nil {
return false, err
}
rows = append(rows, rs...)
return true, nil
})
if err != nil {
return nil, err
}
return rows, nil
}
// getDataAndUdtType returns data types for given DoltgresType. udt_name is the
// base name of the type (i.e. "varchar"). data_type is the SQL standard name of
// the type (i.e. "character varying").
func getDataAndUdtType(colType sql.Type, colName string) (string, string) {
udtName := ""
dataType := ""
dgType, ok := colType.(*pgtypes.DoltgresType)
if ok {
udtName = dgType.Name()
if t, ok := partypes.OidToType[oid.Oid(id.Cache().ToOID(dgType.ID.AsId()))]; ok {
dataType = t.SQLStandardName()
}
} else {
dtdId := strings.Split(strings.Split(colType.String(), " COLLATE")[0], " CHARACTER SET")[0]
// The DATA_TYPE value is the type name only with no other information
dataType = strings.Split(dtdId, "(")[0]
dataType = strings.Split(dataType, " ")[0]
udtName = dataType
}
return dataType, udtName
}
// getColumnPrecisionAndScale returns the precision or a number of postgres type. For non-numeric or decimal types this
// function should return nil,nil.
func getColumnPrecisionAndScale(colType sql.Type) (interface{}, interface{}, interface{}) {
dgt, ok := colType.(*pgtypes.DoltgresType)
if ok {
switch dgt.ID {
// TODO: BitType
case pgtypes.Float32.ID, pgtypes.Float64.ID:
return typeToNumericPrecision[colType.Type()], int32(2), nil
case pgtypes.Int16.ID, pgtypes.Int32.ID, pgtypes.Int64.ID:
return typeToNumericPrecision[colType.Type()], int32(2), int32(0)
case pgtypes.Numeric.ID:
var precision interface{}
var scale interface{}
tm := dgt.GetAttTypMod()
if tm != -1 {
precision, scale = pgtypes.GetPrecisionAndScaleFromTypmod(tm)
}
return precision, int32(10), scale
default:
return nil, nil, nil
}
}
return nil, nil, nil
}
// getCharAndCollNamesAndCharMaxAndOctetLens returns the character set name,
// collation name, character maximum length and character octet length
func getCharAndCollNamesAndCharMaxAndOctetLens(ctx *sql.Context, colType sql.Type) (interface{}, interface{}, interface{}, interface{}) {
var (
charName interface{}
collName interface{}
charMaxLen interface{}
charOctetLen interface{}
)
// TODO: This doesn't work for doltgres types
if twc, ok := colType.(sql.TypeWithCollation); ok && !types.IsBinaryType(colType) {
colColl := twc.Collation()
collName = colColl.Name()
charName = colColl.CharacterSet().String()
if types.IsEnum(colType) || types.IsSet(colType) {
charOctetLen = int32(colType.MaxTextResponseByteLength(ctx))
charMaxLen = int32(colType.MaxTextResponseByteLength(ctx)) / int32(colColl.CharacterSet().MaxLength())
}
}
switch t := colType.(type) {
case *pgtypes.DoltgresType:
if t.TypCategory == pgtypes.TypeCategory_StringTypes {
tm := t.GetAttTypMod()
if tm == -1 {
charOctetLen = int32(maxCharacterOctetLength)
} else {
l := pgtypes.GetCharLengthFromTypmod(tm)
charOctetLen = l * 4
charMaxLen = l
}
}
}
return charName, collName, charMaxLen, charOctetLen
}
func getDatetimePrecision(colType sql.Type) interface{} {
if dgType, ok := colType.(*pgtypes.DoltgresType); ok {
switch dgType.ID {
case pgtypes.Date.ID:
return int32(0)
case pgtypes.Time.ID, pgtypes.TimeTZ.ID, pgtypes.Timestamp.ID, pgtypes.TimestampTZ.ID:
// TODO: TIME length not yet supported
return int32(6)
default:
return nil
}
}
return nil
}
@@ -0,0 +1,72 @@
// Copyright 2026 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 information_schema
import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
"github.com/dolthub/doltgresql/server/functions"
)
// ConstraintColumnUsageViewName is the name of the CONSTRAINT_COLUMN_USAGE view.
const ConstraintColumnUsageViewName = "constraint_column_usage"
// newConstraintColumnUsageView creates a new information_schema.CONSTRAINT_COLUMN_USAGE view.
func newConstraintColumnUsageView() *information_schema.InformationSchemaTable {
return &information_schema.InformationSchemaTable{
TableName: ConstraintColumnUsageViewName,
TableSchema: constraintColumnUsageSchema,
Reader: constraintColumnUsageRowIter,
}
}
// constraintColumnUsage is the schema for the information_schema.CONSTRAINT_COLUMN_USAGE view.
var constraintColumnUsageSchema = sql.Schema{
{Name: "table_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: ConstraintColumnUsageViewName},
{Name: "table_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: ConstraintColumnUsageViewName},
{Name: "table_name", Type: sql_identifier, Default: nil, Nullable: true, Source: ConstraintColumnUsageViewName},
{Name: "column_name", Type: character_data, Default: nil, Nullable: true, Source: ConstraintColumnUsageViewName},
{Name: "constraint_catalog", Type: character_data, Default: nil, Nullable: true, Source: ConstraintColumnUsageViewName},
{Name: "constraint_schema", Type: yes_or_no, Default: nil, Nullable: true, Source: ConstraintColumnUsageViewName},
{Name: "constraint_name", Type: yes_or_no, Default: nil, Nullable: true, Source: ConstraintColumnUsageViewName},
}
// constraintColumnUsageRowIter implements the sql.RowIter for the information_schema.CONSTRAINT_COLUMN_USAGE view.
func constraintColumnUsageRowIter(ctx *sql.Context, catalog sql.Catalog) (sql.RowIter, error) {
var rows []sql.Row
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Check: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, check functions.ItemCheck) (cont bool, err error) {
// TODO: Fill out the rest of the columns.
rows = append(rows, sql.Row{
schema.Item.Name(), // table_catalog
schema.Item.SchemaName(), // table_schema
table.Item.Name(), // table_name
nil, // column_name
nil, // constraint_catalog
nil, // constraint_schema
check.Item.Name, // constraint_name
})
return true, nil
},
})
if err != nil {
return nil, err
}
return sql.RowsToRowIter(rows...), nil
}
@@ -0,0 +1,65 @@
// 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 information_schema
import (
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
"github.com/dolthub/go-mysql-server/sql/mysql_db"
)
// allDatabasesWithNames returns the current database(s) and their catalog and schema names.
func allDatabasesWithNames(ctx *sql.Context, cat sql.Catalog, privCheck bool) ([]information_schema.DbWithNames, error) {
var dbs []information_schema.DbWithNames
currentDB := ctx.GetCurrentDatabase()
currentRevDB, _ := doltdb.SplitRevisionDbName(currentDB)
allDbs := cat.AllDatabases(ctx)
for _, db := range allDbs {
// Always unwrap PrivilegedDatabase to reach the underlying SchemaDatabase implementation.
// PrivilegedDatabase does not implement sql.SchemaDatabase; unwrapping is required for
// schema iteration regardless of privilege-check mode.
if privDatabase, ok := db.(mysql_db.PrivilegedDatabase); ok {
db = privDatabase.Unwrap()
}
sdb, ok := db.(sql.SchemaDatabase)
if ok {
var dbsForSchema []information_schema.DbWithNames
schemas, err := sdb.AllSchemas(ctx)
if err != nil {
return nil, err
}
for _, schema := range schemas {
dbName := db.Name()
revDb, _ := doltdb.SplitRevisionDbName(dbName)
// Add database it is the current database/revision database and if SchemaName exists
if schema.SchemaName() != "" && (dbName == currentDB || revDb == currentRevDB) {
dbsForSchema = append(dbsForSchema, information_schema.DbWithNames{
Database: schema,
CatalogName: schema.Name(),
SchemaName: schema.SchemaName(),
})
}
}
dbs = append(dbs, dbsForSchema...)
}
}
return dbs, nil
}
+35
View File
@@ -0,0 +1,35 @@
// 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 information_schema
import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
)
// Init handles initialization of all Postgres-specific and Doltgres-specific information_schema tables.
func Init() {
information_schema.AllDatabasesWithNames = allDatabasesWithNames
information_schema.NewColumnsTable = newColumnsTable
information_schema.NewSchemataTable = newSchemataTable
information_schema.NewTablesTable = newTablesTable
information_schema.NewViewsTable = newViewsTable
// Postgres-specific tables/views to be added to information_schema database
information_schema.NewInformationSchemaTablesToAdd = map[string]sql.Table{
ConstraintColumnUsageViewName: newConstraintColumnUsageView(),
SequencesTableName: newSequencesTable(),
}
}
@@ -0,0 +1,64 @@
// 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 information_schema
import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
)
// newSchemataTable creates a new information_schema.SCHEMATA table.
func newSchemataTable() *information_schema.InformationSchemaTable {
return &information_schema.InformationSchemaTable{
TableName: information_schema.SchemataTableName,
TableSchema: schemataSchema,
Reader: schemataRowIter,
}
}
// schemataSchema is the schema for the information_schema.SCHEMATA table.
var schemataSchema = sql.Schema{
{Name: "catalog_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.SchemataTableName},
{Name: "schema_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.SchemataTableName},
{Name: "schema_owner", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.SchemataTableName},
{Name: "default_character_set_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.SchemataTableName},
{Name: "default_character_set_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.SchemataTableName},
{Name: "default_character_set_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.SchemataTableName},
{Name: "sql_path", Type: character_data, Default: nil, Nullable: true, Source: information_schema.SchemataTableName},
}
// schemataRowIter implements the sql.RowIter for the information_schema.SCHEMATA table.
func schemataRowIter(ctx *sql.Context, c sql.Catalog) (sql.RowIter, error) {
dbs, err := allDatabasesWithNames(ctx, c, false)
if err != nil {
return nil, err
}
var rows []sql.Row
for _, db := range dbs {
rows = append(rows, sql.Row{
db.CatalogName, // catalog_name
db.SchemaName, // schema_name
"", // schema_owner
nil, // default_character_set_catalog
nil, // default_character_set_schema
nil, // default_character_set_name
nil, // sql_path
})
}
return sql.RowsToRowIter(rows...), nil
}
@@ -0,0 +1,94 @@
// Copyright 2026 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 information_schema
import (
"strconv"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
"github.com/dolthub/doltgresql/server/functions"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
const SequencesTableName = "sequences"
// newSequencesTable returns a InformationSchemaTable for MySQL.
func newSequencesTable() *information_schema.InformationSchemaTable {
return &information_schema.InformationSchemaTable{
TableName: SequencesTableName,
TableSchema: sequencesSchema,
Reader: sequencesRowIter,
}
}
// tablesSchema is the schema for the information_schema.TABLES table.
var sequencesSchema = sql.Schema{
{Name: "sequence_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "sequence_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "sequence_name", Type: sql_identifier, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "data_type", Type: character_data, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "numeric_precision", Type: cardinal_number, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "numeric_precision_radix", Type: cardinal_number, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "numeric_scale", Type: cardinal_number, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "start_value", Type: character_data, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "minimum_value", Type: character_data, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "maximum_value", Type: character_data, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "increment", Type: character_data, Default: nil, Nullable: true, Source: SequencesTableName},
{Name: "cycle_option", Type: yes_or_no, Default: nil, Nullable: true, Source: SequencesTableName},
}
// sequencesRowIter implements the sql.RowIter for the information_schema.Sequences table.
func sequencesRowIter(ctx *sql.Context, _ sql.Catalog) (sql.RowIter, error) {
var rows []sql.Row
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Sequence: func(_ *sql.Context, schema functions.ItemSchema, sequence functions.ItemSequence) (cont bool, err error) {
sequenceType := pgtypes.GetTypeByID(sequence.Item.DataTypeID)
var precision, radix, scale interface{}
if sequenceType != nil {
precision, radix, scale = getColumnPrecisionAndScale(sequenceType)
}
cycleOption := "NO"
if sequence.Item.Cycle {
cycleOption = "YES"
}
rows = append(rows, sql.Row{
schema.Item.Name(), //sequence_catalog
schema.Item.SchemaName(), //sequence_schema
sequence.Item.Id.SequenceName(), //sequence_name
sequenceType.String(), //data_type
precision, //numeric_precision
radix, //numeric_precision_radix
scale, //numeric_scale
strconv.FormatInt(sequence.Item.Start, 10), //start_value
strconv.FormatInt(sequence.Item.Minimum, 10), //minimum_value
strconv.FormatInt(sequence.Item.Maximum, 10), //maximum_value
strconv.FormatInt(sequence.Item.Increment, 10), //increment
cycleOption, //cycle_option
})
return true, nil
},
})
if err != nil {
return nil, err
}
return sql.RowsToRowIter(rows...), nil
}
@@ -0,0 +1,96 @@
// Copyright 2022 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 information_schema
import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
"github.com/dolthub/doltgresql/server/functions"
)
// newTablesTable returns a InformationSchemaTable for MySQL.
func newTablesTable() *information_schema.InformationSchemaTable {
return &information_schema.InformationSchemaTable{
TableName: information_schema.TablesTableName,
TableSchema: tablesSchema,
Reader: tablesRowIter,
}
}
// tablesSchema is the schema for the information_schema.TABLES table.
var tablesSchema = sql.Schema{
{Name: "table_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "table_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "table_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "table_type", Type: character_data, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "self_referencing_column_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "reference_generation", Type: character_data, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "user_defined_type_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "user_defined_type_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "user_defined_type_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "is_insertable_into", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "is_typed", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
{Name: "commit_action", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.TablesTableName},
}
// tablesRowIter implements the sql.RowIter for the information_schema.TABLES table.
func tablesRowIter(ctx *sql.Context, cat sql.Catalog) (sql.RowIter, error) {
var rows []sql.Row
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Table: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable) (cont bool, err error) {
// TODO: Foreign and temporary tables.
rows = append(rows, sql.Row{
schema.Item.Name(), // table_catalog
schema.Item.SchemaName(), // table_schema
table.Item.Name(), // table_name
"BASE TABLE", // table_type
nil, // self_referencing_column_name
nil, // reference_generation
nil, // user_defined_type_catalog
nil, // user_defined_type_schema
nil, // user_defined_type_name
"YES", // is_insertable_into
"NO", // is_typed
nil, // commit_action
})
return true, nil
},
View: func(ctx *sql.Context, schema functions.ItemSchema, view functions.ItemView) (cont bool, err error) {
// TODO: Fill out the rest of the columns.
rows = append(rows, sql.Row{
schema.Item.Name(), // table_catalog
schema.Item.SchemaName(), // table_schema
view.Item.Name, // table_name
"VIEW", // table_type
nil, // self_referencing_column_name
nil, // reference_generation
nil, // user_defined_type_catalog
nil, // user_defined_type_schema
nil, // user_defined_type_name
nil, // is_insertable_into
"NO", // is_typed
nil, // commit_action
})
return true, nil
},
})
if err != nil {
return nil, err
}
return sql.RowsToRowIter(rows...), nil
}
+25
View File
@@ -0,0 +1,25 @@
// 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 information_schema
import (
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// information_schema columns are one of these 5 types https://www.postgresql.org/docs/current/infoschema-datatypes.html
var cardinal_number = pgtypes.Int32
var character_data = pgtypes.Text
var sql_identifier = pgtypes.MustCreateNewVarCharType(64)
var yes_or_no = pgtypes.MustCreateNewVarCharType(3)
@@ -0,0 +1,99 @@
// Copyright 2022 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 information_schema
import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/information_schema"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/postgres/parser/parser"
"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
)
// newViewsTable creates a new information_schema.VIEWS table.
func newViewsTable() *information_schema.InformationSchemaTable {
return &information_schema.InformationSchemaTable{
TableName: information_schema.ViewsTableName,
TableSchema: viewsSchema,
Reader: viewsRowIter,
}
}
// viewsSchema is the schema for the information_schema.VIEWS table.
var viewsSchema = sql.Schema{
{Name: "table_catalog", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "table_schema", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "table_name", Type: sql_identifier, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "view_definition", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "check_option", Type: character_data, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "is_updatable", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "is_insertable_into", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "is_trigger_updatable", Type: yes_or_no, Default: nil, Nullable: true, Source: information_schema.ViewsTableName},
{Name: "is_trigger_deletable", Type: yes_or_no, Default: nil, Nullable: false, Source: information_schema.ViewsTableName},
{Name: "is_trigger_insertable_into", Type: yes_or_no, Default: nil, Nullable: false, Source: information_schema.ViewsTableName},
}
// viewsRowIter implements the sql.RowIter for the information_schema.VIEWS table.
func viewsRowIter(ctx *sql.Context, catalog sql.Catalog) (sql.RowIter, error) {
var rows []sql.Row
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
View: func(ctx *sql.Context, schema functions.ItemSchema, view functions.ItemView) (cont bool, err error) {
stmts, err := parser.Parse(view.Item.CreateViewStatement)
if err != nil {
return false, err
}
if len(stmts) == 0 {
return false, sql.ErrViewCreateStatementInvalid.New(view.Item.CreateViewStatement)
}
cv, ok := stmts[0].AST.(*tree.CreateView)
if !ok {
return false, sql.ErrViewCreateStatementInvalid.New(view.Item.CreateViewStatement)
}
viewDef := cv.AsSource.String()
checkOpt := "NONE"
if cv.CheckOption == tree.ViewCheckOptionCascaded {
checkOpt = "CASCADED"
}
if cv.CheckOption == tree.ViewCheckOptionLocal {
checkOpt = "LOCAL"
}
// TODO: Fill out the rest of the columns.
rows = append(rows, sql.Row{
schema.Item.Name(), // table_catalog
schema.Item.SchemaName(), // table_schema
view.Item.Name, // table_name
viewDef, // view_definition
checkOpt, // check_option
nil, // is_updatable
nil, // is_insertable_into
nil, // is_trigger_updatable
nil, // is_trigger_deletable
nil, // is_trigger_insertable_into
})
return true, nil
},
})
if err != nil {
return nil, err
}
return sql.RowsToRowIter(rows...), nil
}
+26
View File
@@ -0,0 +1,26 @@
// 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 tables
import (
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/doltgresql/core"
)
// Init handles initialization of all Postgres-specific and Doltgres-specific tables.
func Init() {
doltdb.IsValidIdentifier = core.IsValidPostgresIdentifier
}
+52
View File
@@ -0,0 +1,52 @@
// 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 tables
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
)
// partitionIter is a partition iterator that returns a single partition.
type partitionIter struct {
used bool
}
var _ sql.PartitionIter = (*partitionIter)(nil)
// Close implements the interface sql.PartitionIter.
func (iter *partitionIter) Close(ctx *sql.Context) error {
return nil
}
// Next implements the interface sql.PartitionIter.
func (iter *partitionIter) Next(ctx *sql.Context) (sql.Partition, error) {
if iter.used {
return nil, io.EOF
}
iter.used = true
return partition{}, nil
}
// partition is a dummy value that is returned from partitionIter.
type partition struct{}
var _ sql.Partition = partition{}
// Key implements the interface sql.Partition.
func (p partition) Key() []byte {
return nil
}
+372
View File
@@ -0,0 +1,372 @@
// Copyright 2026 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 tables
import (
"fmt"
"strings"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/resolve"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core"
"github.com/dolthub/doltgresql/core/id"
)
// PgDatabase wraps a sqle.Database to add PostgreSQL-specific behavior.
type PgDatabase struct {
sqle.Database
}
var _ sql.DatabaseSchema = &PgDatabase{}
var _ sql.SchemaDatabase = &PgDatabase{}
var _ sql.SchemaObjectNameValidator = &PgDatabase{}
var _ sql.IndexNameGenerator = &PgDatabase{}
// PgReadOnlyDatabase is the read-only variant of PgDatabase, used for revision databases
// such as "postgres/main" returned by sqle.DoltDatabaseProvider for detached-HEAD sessions.
// It applies the same schema-wrapping logic as PgDatabase.
type PgReadOnlyDatabase struct {
sqle.ReadOnlyDatabase
}
var _ sql.DatabaseSchema = &PgReadOnlyDatabase{}
var _ sql.SchemaDatabase = &PgReadOnlyDatabase{}
// WrapSqleDatabase creates a PgDatabase from a sqle.Database.
func WrapSqleDatabase(db sqle.Database) *PgDatabase {
return &PgDatabase{db}
}
// WrapSqlDatabase wraps any Dolt database variant as a Pg-aware database.
// ReadOnlyDatabase embeds sqle.Database by value, so a plain sqle.Database type
// assertion does not match it; this function handles both cases.
func WrapSqlDatabase(db sql.Database) sql.Database {
if rodb, ok := db.(sqle.ReadOnlyDatabase); ok {
return &PgReadOnlyDatabase{rodb}
}
if sdb, ok := db.(sqle.Database); ok {
return WrapSqleDatabase(sdb)
}
return db
}
// applySchemaWrap wraps a single schema returned by the underlying sqle.Database methods.
// System schemas (those with registered virtual-table handlers) get a Database wrapper
// that exposes only virtual tables; all others get a PgDatabase wrapper.
func applySchemaWrap(requestedName string, schema sql.DatabaseSchema) sql.DatabaseSchema {
sdb, ok := schema.(sqle.Database)
if !ok {
// information_schema and any other non-sqle schema: leave as-is.
return schema
}
if _, isSystem := handlers[requestedName]; isSystem {
return Database{sdb}
}
return &PgDatabase{sdb}
}
// AllSchemas overrides sqle.Database.AllSchemas to apply Doltgres schema wrapping.
func (d *PgDatabase) AllSchemas(ctx *sql.Context) ([]sql.DatabaseSchema, error) {
schemas, err := d.Database.AllSchemas(ctx)
if err != nil {
return nil, err
}
for i, s := range schemas {
schemas[i] = applySchemaWrap(s.SchemaName(), s)
}
return schemas, nil
}
// GetSchema overrides sqle.Database.GetSchema to apply Doltgres schema wrapping.
func (d *PgDatabase) GetSchema(ctx *sql.Context, schemaName string) (sql.DatabaseSchema, bool, error) {
schema, ok, err := d.Database.GetSchema(ctx, schemaName)
if !ok || err != nil {
return schema, ok, err
}
return applySchemaWrap(schemaName, schema), true, nil
}
// GetTableInsensitive overrides sqle.Database.GetTableInsensitive to check the pg_catalog
// virtual schema before falling back to user tables.
func (d *PgDatabase) GetTableInsensitive(ctx *sql.Context, tblName string) (sql.Table, bool, error) {
if resolve.UseSearchPath && d.Database.Schema() == "" && strings.HasPrefix(strings.ToLower(tblName), "pg_") {
sdb, found, err := d.GetSchema(ctx, "pg_catalog")
if err != nil {
return nil, false, err
}
if found {
tbl, foundTbl, err := sdb.GetTableInsensitive(ctx, tblName)
if err != nil {
return nil, false, err
}
if foundTbl {
return tbl, true, nil
}
}
}
return d.Database.GetTableInsensitive(ctx, tblName)
}
// DropTable overrides sqle.Database.DropTable to prevent dropping virtual pg_catalog tables.
func (d *PgDatabase) DropTable(ctx *sql.Context, tableName string) error {
if resolve.UseSearchPath && d.Database.Schema() == "" && strings.HasPrefix(strings.ToLower(tableName), "pg_") {
sdb, found, err := d.GetSchema(ctx, "pg_catalog")
if err != nil {
return err
}
if found {
_, foundTbl, err := sdb.GetTableInsensitive(ctx, tableName)
if err != nil {
return err
}
if foundTbl {
return sql.ErrDropTableNotSupported.New("pg_catalog")
}
}
}
return d.Database.DropTable(ctx, tableName)
}
// AllSchemas overrides sqle.ReadOnlyDatabase.AllSchemas to apply Doltgres schema wrapping.
func (d *PgReadOnlyDatabase) AllSchemas(ctx *sql.Context) ([]sql.DatabaseSchema, error) {
schemas, err := d.ReadOnlyDatabase.AllSchemas(ctx)
if err != nil {
return nil, err
}
for i, s := range schemas {
schemas[i] = applySchemaWrap(s.SchemaName(), s)
}
return schemas, nil
}
// GetSchema overrides sqle.ReadOnlyDatabase.GetSchema to apply Doltgres schema wrapping.
func (d *PgReadOnlyDatabase) GetSchema(ctx *sql.Context, schemaName string) (sql.DatabaseSchema, bool, error) {
schema, ok, err := d.ReadOnlyDatabase.GetSchema(ctx, schemaName)
if !ok || err != nil {
return schema, ok, err
}
return applySchemaWrap(schemaName, schema), true, nil
}
// GetTableInsensitive overrides sqle.Database.GetTableInsensitive to check the pg_catalog
// virtual schema before falling back to user tables.
func (d *PgReadOnlyDatabase) GetTableInsensitive(ctx *sql.Context, tblName string) (sql.Table, bool, error) {
if resolve.UseSearchPath && d.ReadOnlyDatabase.Schema() == "" && strings.HasPrefix(strings.ToLower(tblName), "pg_") {
sdb, found, err := d.GetSchema(ctx, "pg_catalog")
if err != nil {
return nil, false, err
}
if found {
tbl, foundTbl, err := sdb.GetTableInsensitive(ctx, tblName)
if err != nil {
return nil, false, err
}
if foundTbl {
return tbl, true, nil
}
}
}
return d.ReadOnlyDatabase.GetTableInsensitive(ctx, tblName)
}
// ValidateNewIndexName implements the sql.SchemaObjectNameValidator interface
func (d *PgDatabase) ValidateNewIndexName(ctx *sql.Context, newIndexName string, skipIfExists bool) (nameAlreadyUsed bool, err error) {
nameAlreadyUsed, _, err = d.doesRelationExist(ctx, newIndexName)
if err != nil {
return false, err
}
if !nameAlreadyUsed {
return false, nil
}
if skipIfExists {
return true, nil
}
return nameAlreadyUsed, fmt.Errorf(`relation "%s" already exists`, newIndexName)
}
// ValidateNewSequenceName implements the sql.SchemaObjectNameValidator interface
func (d *PgDatabase) ValidateNewSequenceName(ctx *sql.Context, newSequenceName string, skipIfExists bool) (nameAlreadyUsed bool, err error) {
nameAlreadyUsed, _, err = d.doesRelationExist(ctx, newSequenceName)
if err != nil {
return false, err
}
if !nameAlreadyUsed {
return false, nil
}
if skipIfExists {
return true, nil
}
return nameAlreadyUsed, fmt.Errorf(`relation "%s" already exists`, newSequenceName)
}
// ValidateNewViewName implements the sql.SchemaObjectNameValidator interface
func (d *PgDatabase) ValidateNewViewName(ctx *sql.Context, newViewName string, replaceAllowed bool) error {
relationExists, relationType, err := d.doesRelationExist(ctx, newViewName)
if err != nil {
return err
}
if !relationExists {
return nil
}
// When REPLACE is used, Postgres sends a different error message
if replaceAllowed {
if relationType == "view" {
return nil
} else {
return fmt.Errorf(`"%s" is not a view`, newViewName)
}
}
return fmt.Errorf(`relation "%s" already exists`, newViewName)
}
// ValidateNewTableName implements the sql.SchemaObjectNameValidator interface
func (d *PgDatabase) ValidateNewTableName(ctx *sql.Context, newTableName string, skipIfExists bool) (nameAlreadyUsed bool, err error) {
relationExists, _, err := d.doesRelationExist(ctx, newTableName)
if err != nil {
return false, err
}
if !relationExists {
return false, nil
}
if skipIfExists {
return true, nil
}
return true, fmt.Errorf(`relation "%s" already exists`, newTableName)
}
// GenerateIndexName implements the sql.IndexNameGenerator interface with PostgreSQL-compatible naming conventions:
// - UNIQUE indexes: <table>_<col1>[_col2...]_key
// - All other indexes: <table>_<col1>[_col2...]_idx
//
// Collisions are resolved by appending a numeric suffix (1, 2, …) to the base name.
// The collision check uses doesRelationExist so that any schema-level relation — table,
// view, sequence, or another index — blocks a candidate name, matching PostgreSQL's
// behavior where all relations in a schema share one namespace.
func (d *PgDatabase) GenerateIndexName(ctx *sql.Context, tableName string, idxDef sql.IndexDef, _ sql.Table) (string, error) {
colPart := strings.Join(idxDef.ColumnNames(), "_")
suffix := "_idx"
if idxDef.IsUnique() {
suffix = "_key"
}
base := tableName + "_" + colPart + suffix
exists, _, err := d.doesRelationExist(ctx, base)
if err != nil {
return "", err
}
if !exists {
return base, nil
}
for i := 1; ; i++ {
candidate := fmt.Sprintf("%s%d", base, i)
exists, _, err = d.doesRelationExist(ctx, candidate)
if err != nil {
return "", err
}
if !exists {
return candidate, nil
}
}
}
// doesRelationExist tests if a relation with the specified |name| exists in this database. If any relation with that
// name exists, this function returns true for |exists|, the relation type (e.g. index, view, table, sequence) for
// |relationType|. If any problems are encountered looking up a relation, an error is returned in |err|.
func (d *PgDatabase) doesRelationExist(ctx *sql.Context, name string) (exists bool, relationType string, err error) {
lowerName := strings.ToLower(name)
// Resolve the effective schema: when the database was obtained without a schema qualifier
// (e.g. from GMS's plan builder for CREATE INDEX), schemaName is "" and we must fall back to
// the session's current schema so that sequence/view checks use the right namespace.
schema := d.Database.Schema()
if schema == "" {
var err error
schema, err = core.GetCurrentSchema(ctx)
if err != nil || schema == "" {
schema = "public"
}
}
// Tables: use GetTableNames which reads the session's working root directly.
tableNames, err := d.Database.GetTableNames(ctx)
if err != nil {
return false, "", err
}
for _, tableName := range tableNames {
if strings.ToLower(tableName) == lowerName {
return true, "table", nil
}
}
// Sequences: use the session-cached collection so uncommitted sequences are visible.
seqCollection, err := core.GetSequencesCollectionFromContext(ctx, d.Database.Name())
if err != nil {
return false, "", err
}
if seqCollection.HasSequence(ctx, id.NewSequence(schema, name)) {
return true, "sequence", nil
}
// Views: sqle.Database implements sql.ViewDatabase, so call AllViews directly.
views, err := d.Database.AllViews(ctx)
if err != nil {
return false, "", err
}
for _, view := range views {
if strings.ToLower(view.Name) == lowerName {
return true, "view", nil
}
}
// Indexes are per-table; reuse the tableNames slice from the table check above.
for _, tableName := range tableNames {
tbl, ok, err := d.Database.GetTableInsensitive(ctx, tableName)
if err != nil {
return false, "", err
}
if !ok {
continue
}
idxTbl, ok := tbl.(sql.IndexAddressableTable)
if !ok {
continue
}
indexes, err := idxTbl.GetIndexes(ctx)
if err != nil {
return false, "", err
}
for _, idx := range indexes {
if strings.ToLower(idx.ID()) == lowerName {
return true, "index", nil
}
}
}
return false, "", nil
}
+161
View File
@@ -0,0 +1,161 @@
// 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 pgcatalog
// PgCatalogName is a constant to the pg_catalog name.
const PgCatalogName = "pg_catalog"
// Init initializes everything necessary for the pg_catalog tables.
func Init() {
InitPgAggregate()
InitPgAm()
InitPgAmop()
InitPgAmproc()
InitPgAttrdef()
InitPgAttribute()
InitPgAuthMembers()
InitPgAuthid()
InitPgAvailableExtensionVersions()
InitPgAvailableExtensions()
InitPgBackendMemoryContexts()
InitPgCast()
InitPgClass()
InitPgCollation()
InitPgConfig()
InitPgConstraint()
InitPgConversion()
InitPgCursors()
InitPgDatabase()
InitPgDbRoleSetting()
InitPgDefaultAcl()
InitPgDepend()
InitPgDescription()
InitPgEnum()
InitPgEventTrigger()
InitPgExtension()
InitPgFileSettings()
InitPgForeignDataWrapper()
InitPgForeignServer()
InitPgForeignTable()
InitPgGroup()
InitPgHbaFileRules()
InitPgIdentFileMappings()
InitPgIndex()
InitPgIndexes()
InitPgInherits()
InitPgInitPrivs()
InitPgLanguage()
InitPgLargeobject()
InitPgLargeobjectMetadata()
InitPgLocks()
InitPgMatviews()
InitPgNamespace()
InitPgOpclass()
InitPgOperator()
InitPgOpfamily()
InitPgParameterAcl()
InitPgPartitionedTable()
InitPgPolicies()
InitPgPolicy()
InitPgPreparedStatements()
InitPgPreparedXacts()
InitPgProc()
InitPgPublication()
InitPgPublicationNamespace()
InitPgPublicationRel()
InitPgPublicationTables()
InitPgRange()
InitPgReplicationOrigin()
InitPgReplicationOriginStatus()
InitPgReplicationSlots()
InitPgRewrite()
InitPgRoles()
InitPgRules()
InitPgSeclabel()
InitPgSeclabels()
InitPgSequence()
InitPgSequences()
InitPgSettings()
InitPgShadow()
InitPgShdepend()
InitPgShdescription()
InitPgShmemAllocations()
InitPgShseclabel()
InitPgStatActivity()
InitPgStatAllIndexes()
InitPgStatAllTables()
InitPgStatArchiver()
InitPgStatBgwriter()
InitPgStatDatabase()
InitPgStatDatabaseConflicts()
InitPgStatGssapi()
InitPgStatProgressAnalyze()
InitPgStatProgressBasebackup()
InitPgStatProgressCluster()
InitPgStatProgressCopy()
InitPgStatProgressCreateIndex()
InitPgStatProgressVacuum()
InitPgStatRecoveryPrefetch()
InitPgStatReplication()
InitPgStatReplicationSlots()
InitPgStatSlru()
InitPgStatSsl()
InitPgStatSubscription()
InitPgStatSubscriptionStats()
InitPgStatSysIndexes()
InitPgStatSysTables()
InitPgStatUserFunctions()
InitPgStatUserIndexes()
InitPgStatUserTables()
InitPgStatWal()
InitPgStatWalReceiver()
InitPgStatXactAllTables()
InitPgStatXactSysTables()
InitPgStatXactUserFunctions()
InitPgStatXactUserTables()
InitPgStatioAllIndexes()
InitPgStatioAllSequences()
InitPgStatioAllTables()
InitPgStatioSysIndexes()
InitPgStatioSysSequences()
InitPgStatioSysTables()
InitPgStatioUserIndexes()
InitPgStatioUserSequences()
InitPgStatioUserTables()
InitPgStatistic()
InitPgStatisticExt()
InitPgStatisticExtData()
InitPgStats()
InitPgStatsExt()
InitPgStatsExtExprs()
InitPgSubscription()
InitPgSubscriptionRel()
InitPgTables()
InitPgTablespace()
InitPgTimezoneAbbrevs()
InitPgTimezoneNames()
InitPgTransform()
InitPgTrigger()
InitPgTsConfig()
InitPgTsConfigMap()
InitPgTsDict()
InitPgTsParser()
InitPgTsTemplate()
InitPgType()
InitPgUser()
InitPgUserMapping()
InitPgUserMappings()
InitPgViews()
}
+331
View File
@@ -0,0 +1,331 @@
// 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 pgcatalog
import (
"io"
"iter"
"github.com/dolthub/go-mysql-server/sql"
"github.com/google/btree"
)
// inMemIndexScanIter is a sql.RowIter that uses an in-memory btree index to satisfy index lookups
// on pg_catalog tables.
type inMemIndexScanIter[T any] struct {
lookup sql.IndexLookup
rangeConverter RangeConverter[T]
btreeAccess BTreeStorageAccess[T]
rowConverter rowConverter[T]
rangeIdx int
next func() (T, bool)
stop func()
}
var _ sql.RowIter = (*inMemIndexScanIter[any])(nil)
// RangeConverter knows how to convert a Range to bounds for a btree scan. The two values returned are the
// greater-than-or-equal lower bound, and the less-than upper bound for this index.
type RangeConverter[T any] interface {
getIndexScanRange(rng sql.Range, index sql.Index) (T, bool, T, bool)
}
// BTreeStorageAccess knows how to get a btree index by name. This interface needs two methods because
// unique and non-unique indexes have different types as stored in the btree package.
type BTreeStorageAccess[T any] interface {
getIndex(name string) *inMemIndexStorage[T]
}
// rowConverter converts a value of type T to a sql.Row.
type rowConverter[T any] func(T) sql.Row
// Next implements the sql.RowIter interface.
func (l *inMemIndexScanIter[T]) Next(ctx *sql.Context) (sql.Row, error) {
nextClass, err := l.nextItem()
if err != nil {
return nil, err
}
return l.rowConverter(*nextClass), nil
}
// Close implements the sql.RowIter interface.
func (l *inMemIndexScanIter[T]) Close(ctx *sql.Context) error {
if l.stop != nil {
l.stop()
}
return nil
}
// nextItem returns the next item from the index lookup, or io.EOF if there are no more items.
// Needs to return a pointer to T so that we can return nil for EOF.
func (l *inMemIndexScanIter[T]) nextItem() (*T, error) {
if l.rangeIdx >= l.lookup.Ranges.Len() {
return nil, io.EOF
}
if l.next != nil {
next, ok := l.next()
if !ok {
l.stop()
l.next = nil
l.stop = nil
l.rangeIdx++
return l.nextItem()
}
return &next, nil
}
inMemIndex := l.lookup.Index.(pgCatalogInMemIndex)
rng := l.lookup.Ranges.ToRanges()[l.rangeIdx]
gte, hasLowerBound, lt, hasUpperBound := l.rangeConverter.getIndexScanRange(rng, l.lookup.Index)
idx := l.btreeAccess.getIndex(inMemIndex.name)
if hasLowerBound && hasUpperBound {
l.next, l.stop = idx.IterRange(gte, lt)
} else if hasLowerBound {
l.next, l.stop = idx.IterGreaterThanEqual(gte)
} else if hasUpperBound {
l.next, l.stop = idx.IterLessThan(lt)
} else {
// We don't support nil lookups for this kind of index, there are never nillable elements
return nil, io.EOF
}
return l.nextItem()
}
// pgCatalogInMemIndex is an in-memory implementation of sql.Index for pg_catalog tables.
type pgCatalogInMemIndex struct {
name string
tblName string
dbName string
uniq bool
columnExprs []sql.ColumnExpressionType
}
var _ sql.Index = (*pgCatalogInMemIndex)(nil)
// ID implements the interface sql.Index.
func (p pgCatalogInMemIndex) ID() string {
return p.name
}
// Database implements the interface sql.Index.
func (p pgCatalogInMemIndex) Database() string {
return p.dbName
}
// Table implements the interface sql.Index.
func (p pgCatalogInMemIndex) Table() string {
return p.tblName
}
// Expressions implements the interface sql.Index.
func (p pgCatalogInMemIndex) Expressions() []string {
exprs := make([]string, len(p.columnExprs))
for i, expr := range p.columnExprs {
exprs[i] = expr.Expression
}
return exprs
}
// IsUnique implements the interface sql.Index.
func (p pgCatalogInMemIndex) IsUnique() bool {
return p.uniq
}
// IsSpatial implements the interface sql.Index.
func (p pgCatalogInMemIndex) IsSpatial() bool {
return false
}
// IsFullText implements the interface sql.Index.
func (p pgCatalogInMemIndex) IsFullText() bool {
return false
}
// IsVector implements the interface sql.Index.
func (p pgCatalogInMemIndex) IsVector() bool {
return false
}
// Comment implements the interface sql.Index.
func (p pgCatalogInMemIndex) Comment() string {
return ""
}
// IndexType implements the interface sql.Index.
func (p pgCatalogInMemIndex) IndexType() string {
return "BTREE"
}
// IsGenerated implements the interface sql.Index.
func (p pgCatalogInMemIndex) IsGenerated() bool {
return false
}
// ColumnExpressionTypes implements the interface sql.Index.
func (p pgCatalogInMemIndex) ColumnExpressionTypes(ctx *sql.Context) []sql.ColumnExpressionType {
return p.columnExprs
}
// CanSupport implements the interface sql.Index.
func (p pgCatalogInMemIndex) CanSupport(context *sql.Context, r ...sql.Range) bool {
return true
}
// CanSupportOrderBy implements the interface sql.Index.
func (p pgCatalogInMemIndex) CanSupportOrderBy(expr sql.Expression) bool {
return true
}
// PrefixLengths implements the interface sql.Index.
func (p pgCatalogInMemIndex) PrefixLengths() []uint16 {
return make([]uint16, len(p.columnExprs))
}
var _ sql.Index = (*pgCatalogInMemIndex)(nil)
// inMemIndexPartition is a sql.Partition that represents the single partition for an in memory index lookup.
type inMemIndexPartition struct {
idxName string
lookup sql.IndexLookup
}
var _ sql.Partition = (*inMemIndexPartition)(nil)
// Key implements the interface sql.Partition.
func (p inMemIndexPartition) Key() []byte {
return []byte(p.idxName)
}
// inMemIndexPartIter is a sql.PartitionIter that returns a single partition for an in memory index lookup.
type inMemIndexPartIter struct {
used bool
part inMemIndexPartition
}
var _ sql.PartitionIter = (*inMemIndexPartIter)(nil)
// Close implements the interface sql.PartitionIter.
func (p inMemIndexPartIter) Close(context *sql.Context) error {
return nil
}
// Next implements the interface sql.PartitionIter.
func (p *inMemIndexPartIter) Next(context *sql.Context) (sql.Partition, error) {
if p.used {
return nil, io.EOF
}
p.used = true
return p.part, nil
}
// inMemIndexStorage is an in-memory storage for an index using a btree, abstracting away the differences between
// unique and non-unique indexes.
type inMemIndexStorage[T any] struct {
uniqTree *btree.BTreeG[T]
nonUniqTree *btree.BTreeG[[]T]
}
// NewUniqueInMemIndexStorage creates a new in-memory index storage for a unique index.
func NewUniqueInMemIndexStorage[T any](lessFunc func(a, b T) bool) *inMemIndexStorage[T] {
return &inMemIndexStorage[T]{
uniqTree: btree.NewG[T](2, lessFunc),
}
}
// NewNonUniqueInMemIndexStorage creates a new in-memory index storage for a non-unique index.
func NewNonUniqueInMemIndexStorage[T any](lessFunc func(a, b []T) bool) *inMemIndexStorage[T] {
return &inMemIndexStorage[T]{
nonUniqTree: btree.NewG[[]T](2, lessFunc),
}
}
// Add adds a value to the in-memory index storage.
func (s *inMemIndexStorage[T]) Add(val T) {
if s.uniqTree != nil {
s.uniqTree.ReplaceOrInsert(val)
} else {
existing, replaced := s.nonUniqTree.ReplaceOrInsert([]T{val})
if replaced {
existing = append(existing, val)
s.nonUniqTree.ReplaceOrInsert(existing)
}
}
}
// IterRange implements an in-order iteration over the index values in the range [gte, lt). All values in the
// index in the range are sent to the channel
func (s *inMemIndexStorage[T]) IterRange(gte, lt T) (next func() (T, bool), stop func()) {
if s.uniqTree != nil {
return iter.Pull(func(yield func(T) bool) {
s.uniqTree.AscendRange(gte, lt, yield)
})
} else {
next, stop := iter.Pull(func(yield func([]T) bool) {
s.nonUniqTree.AscendRange([]T{gte}, []T{lt}, yield)
})
return s.unnestIter(next, stop)
}
}
// IterGreaterThanEqual implements an in-order iteration over the index values greater than or equal to the given value.
// All values in the index greater than or equal to the given value are sent to the channel.
func (s *inMemIndexStorage[T]) IterGreaterThanEqual(gte T) (next func() (T, bool), stop func()) {
if s.uniqTree != nil {
return iter.Pull(func(yield func(T) bool) {
s.uniqTree.AscendGreaterOrEqual(gte, yield)
})
} else {
next, stop := iter.Pull(func(yield func([]T) bool) {
s.nonUniqTree.AscendGreaterOrEqual([]T{gte}, yield)
})
return s.unnestIter(next, stop)
}
}
// IterLessThan implements an in-order iteration over the index values less than the given value.
// All values in the index less than or equal to the given value are sent to the channel.
func (s *inMemIndexStorage[T]) IterLessThan(lt T) (next func() (T, bool), stop func()) {
if s.uniqTree != nil {
return iter.Pull(func(yield func(T) bool) {
s.uniqTree.AscendLessThan(lt, yield)
})
} else {
next, stop := iter.Pull(func(yield func([]T) bool) {
s.nonUniqTree.AscendLessThan([]T{lt}, yield)
})
return s.unnestIter(next, stop)
}
}
// unnestIter takes an iterator that returns slices of T, and returns an iterator that returns individual T values.
func (s *inMemIndexStorage[T]) unnestIter(sNext func() ([]T, bool), sStop func()) (next func() (T, bool), stop func()) {
return iter.Pull(func(yield func(T) bool) {
defer sStop()
for {
items, ok := sNext()
if !ok {
return
}
for _, item := range items {
if !yield(item) {
return
}
}
}
})
}
+22
View File
@@ -0,0 +1,22 @@
// 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 pgcatalog
import "github.com/dolthub/go-mysql-server/sql"
// emptyRowIter implements the sql.RowIter for empty table.
func emptyRowIter() (sql.RowIter, error) {
return sql.RowsToRowIter(), nil
}
+98
View File
@@ -0,0 +1,98 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAggregateName is a constant to the pg_aggregate name.
const PgAggregateName = "pg_aggregate"
// InitPgAggregate handles registration of the pg_aggregate handler.
func InitPgAggregate() {
tables.AddHandler(PgCatalogName, PgAggregateName, PgAggregateHandler{})
}
// PgAggregateHandler is the handler for the pg_aggregate table.
type PgAggregateHandler struct{}
var _ tables.Handler = PgAggregateHandler{}
// Name implements the interface tables.Handler.
func (p PgAggregateHandler) Name() string {
return PgAggregateName
}
// RowIter implements the interface tables.Handler.
func (p PgAggregateHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_aggregate row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgAggregateHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAggregateSchema,
PkOrdinals: nil,
}
}
// pgAggregateSchema is the schema for pg_aggregate.
var pgAggregateSchema = sql.Schema{
{Name: "aggfnoid", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggkind", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggnumdirectargs", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggtransfn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggfinalfn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggcombinefn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggserialfn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggdeserialfn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggmtransfn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggminvtransfn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggmfinalfn", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAggregateName}, // TODO: regproc type
{Name: "aggfinalextra", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggmfinalextra", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggfinalmodify", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggmfinalmodify", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggsortop", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggtranstype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggtransspace", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggmtranstype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "aggmtransspace", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgAggregateName},
{Name: "agginitval", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAggregateName}, // TODO: collation C
{Name: "aggminitval", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAggregateName}, // TODO: collation C
}
// pgAggregateRowIter is the sql.RowIter for the pg_aggregate table.
type pgAggregateRowIter struct {
}
var _ sql.RowIter = (*pgAggregateRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAggregateRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgAggregateRowIter) Close(ctx *sql.Context) error {
return nil
}
+114
View File
@@ -0,0 +1,114 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAmName is a constant to the pg_am name.
const PgAmName = "pg_am"
// InitPgAm handles registration of the pg_am handler.
func InitPgAm() {
tables.AddHandler(PgCatalogName, PgAmName, PgAmHandler{})
}
// PgAmHandler is the handler for the pg_am table.
type PgAmHandler struct{}
var _ tables.Handler = PgAmHandler{}
// Name implements the interface tables.Handler.
func (p PgAmHandler) Name() string {
return PgAmName
}
// RowIter implements the interface tables.Handler.
func (p PgAmHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
return &pgAmRowIter{
ams: defaultPostgresAms,
idx: 0,
}, nil
}
// PkSchema implements the interface tables.Handler.
func (p PgAmHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAmSchema,
PkOrdinals: nil,
}
}
// pgAmSchema is the schema for pg_am.
var pgAmSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmName},
{Name: "amname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgAmName},
{Name: "amhandler", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAmName}, // TODO: type regproc
{Name: "amtype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAmName},
}
// pgAmRowIter is the sql.RowIter for the pg_am table.
type pgAmRowIter struct {
ams []accessMethod
idx int
}
var _ sql.RowIter = (*pgAmRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAmRowIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.ams) {
return nil, io.EOF
}
iter.idx++
am := iter.ams[iter.idx-1]
return sql.Row{
am.oid, // oid
am.name, // amname
am.handler, // amhandler
am.typ, // amtype
}, nil
}
// Close implements the interface sql.RowIter.
func (iter *pgAmRowIter) Close(ctx *sql.Context) error {
return nil
}
type accessMethod struct {
oid id.Id
name string
handler string
typ string
}
// defaultPostgresAms is the list of default access methods available in Postgres.
var defaultPostgresAms = []accessMethod{
{oid: id.NewAccessMethod("heap").AsId(), name: "heap", handler: "heap_tableam_handler", typ: "t"},
{oid: id.NewAccessMethod("btree").AsId(), name: "btree", handler: "bthandler", typ: "i"},
{oid: id.NewAccessMethod("hash").AsId(), name: "hash", handler: "hashhandler", typ: "i"},
{oid: id.NewAccessMethod("gist").AsId(), name: "gist", handler: "gisthandler", typ: "i"},
{oid: id.NewAccessMethod("gin").AsId(), name: "gin", handler: "ginhandler", typ: "i"},
{oid: id.NewAccessMethod("spgist").AsId(), name: "spgist", handler: "spghandler", typ: "i"},
{oid: id.NewAccessMethod("brin").AsId(), name: "brin", handler: "brinhandler", typ: "i"},
}
+85
View File
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAmopName is a constant to the pg_amop name.
const PgAmopName = "pg_amop"
// InitPgAmop handles registration of the pg_amop handler.
func InitPgAmop() {
tables.AddHandler(PgCatalogName, PgAmopName, PgAmopHandler{})
}
// PgAmopHandler is the handler for the pg_amop table.
type PgAmopHandler struct{}
var _ tables.Handler = PgAmopHandler{}
// Name implements the interface tables.Handler.
func (p PgAmopHandler) Name() string {
return PgAmopName
}
// RowIter implements the interface tables.Handler.
func (p PgAmopHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_amop row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgAmopHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAmopSchema,
PkOrdinals: nil,
}
}
// pgAmopSchema is the schema for pg_amop.
var pgAmopSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amopfamily", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amoplefttype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amoprighttype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amopstrategy", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amoppurpose", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amopopr", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amopmethod", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmopName},
{Name: "amopsortfamily", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmopName},
}
// pgAmopRowIter is the sql.RowIter for the pg_amop table.
type pgAmopRowIter struct {
}
var _ sql.RowIter = (*pgAmopRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAmopRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgAmopRowIter) Close(ctx *sql.Context) error {
return nil
}
+82
View File
@@ -0,0 +1,82 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAmprocName is a constant to the pg_amproc name.
const PgAmprocName = "pg_amproc"
// InitPgAmproc handles registration of the pg_amproc handler.
func InitPgAmproc() {
tables.AddHandler(PgCatalogName, PgAmprocName, PgAmprocHandler{})
}
// PgAmprocHandler is the handler for the pg_amproc table.
type PgAmprocHandler struct{}
var _ tables.Handler = PgAmprocHandler{}
// Name implements the interface tables.Handler.
func (p PgAmprocHandler) Name() string {
return PgAmprocName
}
// RowIter implements the interface tables.Handler.
func (p PgAmprocHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_amproc row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgAmprocHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAmprocSchema,
PkOrdinals: nil,
}
}
// pgAmprocSchema is the schema for pg_amproc.
var pgAmprocSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmprocName},
{Name: "amprocfamily", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmprocName},
{Name: "amproclefttype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmprocName},
{Name: "amprocrighttype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAmprocName},
{Name: "amprocnum", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAmprocName},
{Name: "amproc", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAmprocName}, // TODO: regproc type
}
// pgAmprocRowIter is the sql.RowIter for the pg_amproc table.
type pgAmprocRowIter struct {
}
var _ sql.RowIter = (*pgAmprocRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAmprocRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgAmprocRowIter) Close(ctx *sql.Context) error {
return nil
}
+124
View File
@@ -0,0 +1,124 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAttrdefName is a constant to the pg_attrdef name.
const PgAttrdefName = "pg_attrdef"
// InitPgAttrdef handles registration of the pg_attrdef handler.
func InitPgAttrdef() {
tables.AddHandler(PgCatalogName, PgAttrdefName, PgAttrdefHandler{})
}
// PgAttrdefHandler is the handler for the pg_attrdef table.
type PgAttrdefHandler struct{}
var _ tables.Handler = PgAttrdefHandler{}
// Name implements the interface tables.Handler.
func (p PgAttrdefHandler) Name() string {
return PgAttrdefName
}
// RowIter implements the interface tables.Handler.
func (p PgAttrdefHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// Use cached data from this process if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.attrdefCols == nil {
var attrdefCols []functions.ItemColumnDefault
var attrdefTableOIDs []id.Id
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.AsId())
return true, nil
},
})
if err != nil {
return nil, err
}
pgCatalogCache.attrdefCols = attrdefCols
pgCatalogCache.attrdefTableOIDs = attrdefTableOIDs
}
return &pgAttrdefRowIter{
cols: pgCatalogCache.attrdefCols,
tableOIDs: pgCatalogCache.attrdefTableOIDs,
idx: 0,
}, nil
}
// PkSchema implements the interface tables.Handler.
func (p PgAttrdefHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAttrdefSchema,
PkOrdinals: nil,
}
}
// pgAttrdefSchema is the schema for pg_attrdef.
var pgAttrdefSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "adrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "adnum", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "adbin", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgAttributeName}, // TODO: collation C, type pg_node_tree
}
// pgAttrdefRowIter is the sql.RowIter for the pg_attrdef table.
type pgAttrdefRowIter struct {
cols []functions.ItemColumnDefault
tableOIDs []id.Id
idx int
}
var _ sql.RowIter = (*pgAttrdefRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAttrdefRowIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.cols) {
return nil, io.EOF
}
iter.idx++
col := iter.cols[iter.idx-1]
tableOid := iter.tableOIDs[iter.idx-1]
// TODO: Implement adbin when pg_node_tree exists
return sql.Row{
col.OID.AsId(), // oid
tableOid, // adrelid
int16(col.Item.ColumnIndex + 1), // adnum
nil, // adbin
}, nil
}
// Close implements the interface sql.RowIter.
func (iter *pgAttrdefRowIter) Close(ctx *sql.Context) error {
return nil
}
+491
View File
@@ -0,0 +1,491 @@
// 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 pgcatalog
import (
"io"
"math"
"github.com/dolthub/dolt/go/libraries/doltcore/sqlserver"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
pgparser "github.com/dolthub/doltgresql/postgres/parser/parser"
"github.com/dolthub/doltgresql/postgres/parser/sem/tree"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAttributeName is a constant to the pg_attribute name.
const PgAttributeName = "pg_attribute"
// InitPgAttribute handles registration of the pg_attribute handler.
func InitPgAttribute() {
tables.AddHandler(PgCatalogName, PgAttributeName, PgAttributeHandler{})
}
// PgAttributeHandler is the handler for the pg_attribute table.
type PgAttributeHandler struct{}
var _ tables.Handler = PgAttributeHandler{}
var _ tables.IndexedTableHandler = PgAttributeHandler{}
// Name implements the interface tables.Handler.
func (p PgAttributeHandler) Name() string {
return PgAttributeName
}
// RowIter implements the interface tables.Handler.
func (p PgAttributeHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// Use cached data from this session if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.pgAttributes == nil {
err = cachePgAttributes(ctx, pgCatalogCache)
if err != nil {
return nil, err
}
}
if attrIdxPart, ok := partition.(inMemIndexPartition); ok {
return &inMemIndexScanIter[*pgAttribute]{
lookup: attrIdxPart.lookup,
rangeConverter: p,
btreeAccess: pgCatalogCache.pgAttributes,
rowConverter: pgAttributeToRow,
}, nil
}
return &pgAttributeTableScanIter{
attributeCache: pgCatalogCache.pgAttributes,
idx: 0,
}, nil
}
// cachePgAttributes caches the pg_attribute data for the current database in the session.
func cachePgAttributes(ctx *sql.Context, pgCatalogCache *pgCatalogCache) error {
var attributes []*pgAttribute
attrelidIdx := NewUniqueInMemIndexStorage[*pgAttribute](lessAttNum)
attrelidAttnameIdx := NewUniqueInMemIndexStorage[*pgAttribute](lessAttName)
// Get the engine for resolving view column types. May be nil in some test environments.
type queryAnalyzer interface {
AnalyzeQuery(*sql.Context, string) (sql.Node, error)
}
var engine queryAnalyzer
if runningServer := sqlserver.GetRunningServer(); runningServer != nil && runningServer.Engine != nil {
engine = runningServer.Engine
}
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Table: func(ctx *sql.Context, _ functions.ItemSchema, table functions.ItemTable) (cont bool, err error) {
for i, col := range table.Item.Schema(ctx) {
typeOid := id.Null
if doltgresType, ok := col.Type.(*pgtypes.DoltgresType); ok {
typeOid = doltgresType.ID.AsId()
} else {
// TODO: Remove once all information_schema tables are converted to use DoltgresType
dt := pgtypes.FromGmsType(col.Type)
typeOid = dt.ID.AsId()
}
generated := ""
if col.Generated != nil {
generated = "s"
}
dimensions := int16(0)
if s, ok := col.Type.(sql.SetType); ok {
dimensions = int16(s.NumberOfElements())
}
hasDefault := col.Default != nil
attr := &pgAttribute{
attrelid: table.OID.AsId(),
attrelidNative: id.Cache().ToOID(table.OID.AsId()),
attname: col.Name,
atttypid: typeOid,
attnum: int16(i + 1),
attndims: dimensions,
attnotnull: !col.Nullable,
atthasdef: hasDefault,
attgenerated: generated,
}
attrelidIdx.Add(attr)
attrelidAttnameIdx.Add(attr)
attributes = append(attributes, attr)
}
return true, nil
},
View: func(ctx *sql.Context, _ functions.ItemSchema, view functions.ItemView) (cont bool, err error) {
if engine == nil {
return true, nil
}
// Get the SELECT body from the view definition.
selectBody := view.Item.TextDefinition
if selectBody == "" {
stmts, parseErr := pgparser.Parse(view.Item.CreateViewStatement)
if parseErr != nil || len(stmts) == 0 {
return true, nil
}
cv, ok := stmts[0].AST.(*tree.CreateView)
if !ok {
return true, nil
}
selectBody = cv.AsSource.String()
}
if selectBody == "" {
return true, nil
}
// Analyze the SELECT statement to get the view's output schema.
analyzed, analyzeErr := engine.AnalyzeQuery(ctx, selectBody)
if analyzeErr != nil {
return true, nil
}
for i, col := range analyzed.Schema(ctx) {
typeOid := id.Null
if doltgresType, ok := col.Type.(*pgtypes.DoltgresType); ok {
typeOid = doltgresType.ID.AsId()
} else {
dt := pgtypes.FromGmsType(col.Type)
typeOid = dt.ID.AsId()
}
attr := &pgAttribute{
attrelid: view.OID.AsId(),
attrelidNative: id.Cache().ToOID(view.OID.AsId()),
attname: col.Name,
atttypid: typeOid,
attnum: int16(i + 1),
}
attrelidIdx.Add(attr)
attrelidAttnameIdx.Add(attr)
attributes = append(attributes, attr)
}
return true, nil
},
})
if err != nil {
return err
}
pgCatalogCache.pgAttributes = &pgAttributeCache{
attributes: attributes,
attrelidIdx: attrelidIdx,
attrelidAttnameIdx: attrelidAttnameIdx,
}
return nil
}
// getIndexScanRange implements the interface RangeConverter.
func (p PgAttributeHandler) getIndexScanRange(rng sql.Range, index sql.Index) (*pgAttribute, bool, *pgAttribute, bool) {
var gte, lt *pgAttribute
var hasLowerBound, hasUpperBound bool
switch index.(pgCatalogInMemIndex).name {
case "pg_attribute_relid_attnum_index":
msrng := rng.(sql.MySQLRange)
oidRng := msrng[0]
attNumRng := msrng[1]
var oidLower, oidUpper id.Id
attnumLower := int16(math.MinInt16)
attnumUpper := int16(math.MaxInt16)
attNumUpperSet := false
if oidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(oidRng.LowerBound)
if lb != nil {
oidLower = lb.(id.Id)
hasLowerBound = true
}
}
if oidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(oidRng.UpperBound)
if ub != nil {
oidUpper = ub.(id.Id)
hasUpperBound = true
}
}
if attNumRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(attNumRng.LowerBound)
if lb != nil {
attnumLower = lb.(int16)
}
}
if attNumRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(attNumRng.UpperBound)
if ub != nil {
attnumUpper = ub.(int16)
attNumUpperSet = true
}
}
if hasLowerBound {
gte = &pgAttribute{
attrelidNative: idToOid(oidLower),
attnum: attnumLower,
}
}
if hasUpperBound {
// our less-than upper bound depends on whether one or both fields in the range were set
oid := idToOid(oidUpper)
if !attNumUpperSet {
oid += 1
} else {
attnumUpper += 1
}
lt = &pgAttribute{
attrelidNative: oid,
attnum: attnumUpper,
}
}
case "pg_attribute_relid_attnam_index":
msrng := rng.(sql.MySQLRange)
attrelidRange := msrng[0]
attnameRange := msrng[1]
var attrelidLower, attrelidUpper uint32
var attnameLower, attnameUpper string
if attrelidRange.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(attrelidRange.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
attrelidLower = idToOid(lowerRangeCutKey)
hasLowerBound = true
}
}
if attrelidRange.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(attrelidRange.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
attrelidUpper = idToOid(upperRangeCutKey)
hasUpperBound = true
}
}
if attnameRange.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(attnameRange.LowerBound)
if lb != nil {
attnameLower = lb.(string)
}
}
if attnameRange.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(attnameRange.UpperBound)
if ub != nil {
attnameUpper = ub.(string)
}
}
if attrelidRange.HasLowerBound() || attnameRange.HasLowerBound() {
gte = &pgAttribute{
attrelidNative: attrelidLower,
attname: attnameLower,
}
}
if attrelidRange.HasUpperBound() || attnameRange.HasUpperBound() {
// our less-than upper bound depends on whether one or both fields in the range were set
oidUpper := attrelidUpper
if attnameUpper == "" {
oidUpper += 1
} else {
attnameUpper += " "
}
lt = &pgAttribute{
attrelidNative: oidUpper,
attname: attnameUpper,
}
}
default:
panic("unknown index name: " + index.(pgCatalogInMemIndex).name)
}
return gte, hasLowerBound, lt, hasUpperBound
}
// PkSchema implements the interface tables.Handler.
func (p PgAttributeHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAttributeSchema,
PkOrdinals: nil,
}
}
// Indexes implements tables.IndexedTableHandler.
func (p PgAttributeHandler) Indexes() ([]sql.Index, error) {
return []sql.Index{
pgCatalogInMemIndex{
name: "pg_attribute_relid_attnum_index",
tblName: "pg_attribute",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{
{Expression: "pg_attribute.attrelid", Type: pgtypes.Oid},
{Expression: "pg_attribute.attnum", Type: pgtypes.Int16},
},
},
pgCatalogInMemIndex{
name: "pg_attribute_relid_attnam_index",
tblName: "pg_attribute",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{
{Expression: "pg_attribute.attrelid", Type: pgtypes.Oid},
{Expression: "pg_attribute.attname", Type: pgtypes.Name},
},
},
}, nil
}
// LookupPartitions implements tables.IndexedTableHandler.
func (p PgAttributeHandler) LookupPartitions(context *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error) {
return &inMemIndexPartIter{
part: inMemIndexPartition{
idxName: lookup.Index.(pgCatalogInMemIndex).name,
lookup: lookup,
},
}, nil
}
// pgAttributeSchema is the schema for pg_attribute.
var pgAttributeSchema = sql.Schema{
{Name: "attrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "atttypid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attlen", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attnum", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attcacheoff", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "atttypmod", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attndims", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attbyval", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attalign", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attstorage", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attcompression", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attnotnull", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "atthasdef", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "atthasmissing", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attidentity", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attgenerated", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attisdropped", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attislocal", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attinhcount", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attstattarget", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attcollation", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAttributeName},
{Name: "attacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgAttributeName}, // TODO: type aclitem[]
{Name: "attoptions", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgAttributeName}, // TODO: collation C
{Name: "attfdwoptions", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgAttributeName}, // TODO: collation C
{Name: "attmissingval", Type: pgtypes.AnyArray, Default: nil, Nullable: true, Source: PgAttributeName},
}
// pgAttribute represents a row in the pg_attribute table.
// We store oids in their native format as well so that we can do range scans on them.
type pgAttribute struct {
attrelid id.Id
attrelidNative uint32
attname string
atttypid id.Id
attnum int16
attndims int16
attnotnull bool
atthasdef bool
attgenerated string
}
// lessAttNum is a sort function for pgAttribute based on attrelid.
func lessAttNum(a, b *pgAttribute) bool {
if a.attrelidNative == b.attrelidNative {
return a.attnum < b.attnum
}
return a.attrelidNative < b.attrelidNative
}
// lessAttName is a sort function for pgAttribute based on attrelid, then attname.
func lessAttName(a, b *pgAttribute) bool {
if a.attrelidNative == b.attrelidNative {
return a.attname < b.attname
}
return a.attrelidNative < b.attrelidNative
}
// pgAttributeTableScanIter is the sql.RowIter for the pg_attribute table.
type pgAttributeTableScanIter struct {
attributeCache *pgAttributeCache
idx int
}
var _ sql.RowIter = (*pgAttributeTableScanIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAttributeTableScanIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.attributeCache.attributes) {
return nil, io.EOF
}
iter.idx++
attr := iter.attributeCache.attributes[iter.idx-1]
return pgAttributeToRow(attr), nil
}
// Close implements the interface sql.RowIter.
func (iter *pgAttributeTableScanIter) Close(ctx *sql.Context) error {
return nil
}
func pgAttributeToRow(attr *pgAttribute) sql.Row {
// TODO: Fill in the rest of the pg_attribute columns
return sql.Row{
attr.attrelid, // attrelid
attr.attname, // attname
attr.atttypid, // atttypid
int16(0), // attlen
attr.attnum, // attnum
int32(-1), // attcacheoff
int32(-1), // atttypmod
attr.attndims, // attndims
false, // attbyval
"i", // attalign
"p", // attstorage
"", // attcompression
attr.attnotnull, // attnotnull
attr.atthasdef, // atthasdef
false, // atthasmissing
"", // attidentity
attr.attgenerated, // attgenerated
false, // attisdropped
true, // attislocal
int16(0), // attinhcount
int16(-1), // attstattarget
id.Null, // attcollation
nil, // attacl
nil, // attoptions
nil, // attfdwoptions
nil, // attmissingval
}
}
@@ -0,0 +1,80 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAuthMembersName is a constant to the pg_auth_members name.
const PgAuthMembersName = "pg_auth_members"
// InitPgAuthMembers handles registration of the pg_auth_members handler.
func InitPgAuthMembers() {
tables.AddHandler(PgCatalogName, PgAuthMembersName, PgAuthMembersHandler{})
}
// PgAuthMembersHandler is the handler for the pg_auth_members table.
type PgAuthMembersHandler struct{}
var _ tables.Handler = PgAuthMembersHandler{}
// Name implements the interface tables.Handler.
func (p PgAuthMembersHandler) Name() string {
return PgAuthMembersName
}
// RowIter implements the interface tables.Handler.
func (p PgAuthMembersHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_auth_members row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgAuthMembersHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAuthMembersSchema,
PkOrdinals: nil,
}
}
// pgAuthMembersSchema is the schema for pg_auth_members.
var pgAuthMembersSchema = sql.Schema{
{Name: "roleid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAuthMembersName},
{Name: "member", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAuthMembersName},
{Name: "grantor", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAuthMembersName},
{Name: "admin_option", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthMembersName},
}
// pgAuthMembersRowIter is the sql.RowIter for the pg_auth_members table.
type pgAuthMembersRowIter struct {
}
var _ sql.RowIter = (*pgAuthMembersRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAuthMembersRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgAuthMembersRowIter) Close(ctx *sql.Context) error {
return nil
}
+88
View File
@@ -0,0 +1,88 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAuthidName is a constant to the pg_authid name.
const PgAuthidName = "pg_authid"
// InitPgAuthid handles registration of the pg_authid handler.
func InitPgAuthid() {
tables.AddHandler(PgCatalogName, PgAuthidName, PgAuthidHandler{})
}
// PgAuthidHandler is the handler for the pg_authid table.
type PgAuthidHandler struct{}
var _ tables.Handler = PgAuthidHandler{}
// Name implements the interface tables.Handler.
func (p PgAuthidHandler) Name() string {
return PgAuthidName
}
// RowIter implements the interface tables.Handler.
func (p PgAuthidHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_authid row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgAuthidHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAuthidSchema,
PkOrdinals: nil,
}
}
// pgAuthidSchema is the schema for pg_authid.
var pgAuthidSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolsuper", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolinherit", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolcreaterole", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolcreatedb", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolcanlogin", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolreplication", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolbypassrls", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolconnlimit", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgAuthidName},
{Name: "rolpassword", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAuthidName}, // TODO: collation C
{Name: "rolvaliduntil", Type: pgtypes.TimestampTZ, Default: nil, Nullable: true, Source: PgAuthidName},
}
// pgAuthidRowIter is the sql.RowIter for the pg_authid table.
type pgAuthidRowIter struct {
}
var _ sql.RowIter = (*pgAuthidRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAuthidRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgAuthidRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAvailableExtensionVersionsName is a constant to the pg_available_extension_versions name.
const PgAvailableExtensionVersionsName = "pg_available_extension_versions"
// InitPgAvailableExtensionVersions handles registration of the pg_available_extension_versions handler.
func InitPgAvailableExtensionVersions() {
tables.AddHandler(PgCatalogName, PgAvailableExtensionVersionsName, PgAvailableExtensionVersionsHandler{})
}
// PgAvailableExtensionVersionsHandler is the handler for the pg_available_extension_versions table.
type PgAvailableExtensionVersionsHandler struct{}
var _ tables.Handler = PgAvailableExtensionVersionsHandler{}
// Name implements the interface tables.Handler.
func (p PgAvailableExtensionVersionsHandler) Name() string {
return PgAvailableExtensionVersionsName
}
// RowIter implements the interface tables.Handler.
func (p PgAvailableExtensionVersionsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_available_extension_versions row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgAvailableExtensionVersionsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAvailableExtensionVersionsSchema,
PkOrdinals: nil,
}
}
// pgAvailableExtensionVersionsSchema is the schema for pg_available_extension_versions.
var pgAvailableExtensionVersionsSchema = sql.Schema{
{Name: "name", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "version", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "installed", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "superuser", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "trusted", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "relocatable", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "schema", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "requires", Type: pgtypes.NameArray, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
{Name: "comment", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAvailableExtensionVersionsName},
}
// pgAvailableExtensionVersionsRowIter is the sql.RowIter for the pg_available_extension_versions table.
type pgAvailableExtensionVersionsRowIter struct {
}
var _ sql.RowIter = (*pgAvailableExtensionVersionsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAvailableExtensionVersionsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgAvailableExtensionVersionsRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,80 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgAvailableExtensionsName is a constant to the pg_available_extensions name.
const PgAvailableExtensionsName = "pg_available_extensions"
// InitPgAvailableExtensions handles registration of the pg_available_extensions handler.
func InitPgAvailableExtensions() {
tables.AddHandler(PgCatalogName, PgAvailableExtensionsName, PgAvailableExtensionsHandler{})
}
// PgAvailableExtensionsHandler is the handler for the pg_available_extensions table.
type PgAvailableExtensionsHandler struct{}
var _ tables.Handler = PgAvailableExtensionsHandler{}
// Name implements the interface tables.Handler.
func (p PgAvailableExtensionsHandler) Name() string {
return PgAvailableExtensionsName
}
// RowIter implements the interface tables.Handler.
func (p PgAvailableExtensionsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_available_extensions row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgAvailableExtensionsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgAvailableExtensionsSchema,
PkOrdinals: nil,
}
}
// pgAvailableExtensionsSchema is the schema for pg_available_extensions.
var pgAvailableExtensionsSchema = sql.Schema{
{Name: "name", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgAvailableExtensionsName},
{Name: "default_version", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAvailableExtensionsName},
{Name: "installed_version", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAvailableExtensionsName}, // TODO: collation C
{Name: "comment", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgAvailableExtensionsName},
}
// pgAvailableExtensionsRowIter is the sql.RowIter for the pg_available_extensions table.
type pgAvailableExtensionsRowIter struct {
}
var _ sql.RowIter = (*pgAvailableExtensionsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgAvailableExtensionsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgAvailableExtensionsRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgBackendMemoryContextsName is a constant to the pg_backend_memory_contexts name.
const PgBackendMemoryContextsName = "pg_backend_memory_contexts"
// InitPgBackendMemoryContexts handles registration of the pg_backend_memory_contexts handler.
func InitPgBackendMemoryContexts() {
tables.AddHandler(PgCatalogName, PgBackendMemoryContextsName, PgBackendMemoryContextsHandler{})
}
// PgBackendMemoryContextsHandler is the handler for the pg_backend_memory_contexts table.
type PgBackendMemoryContextsHandler struct{}
var _ tables.Handler = PgBackendMemoryContextsHandler{}
// Name implements the interface tables.Handler.
func (p PgBackendMemoryContextsHandler) Name() string {
return PgBackendMemoryContextsName
}
// RowIter implements the interface tables.Handler.
func (p PgBackendMemoryContextsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_backend_memory_contexts row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgBackendMemoryContextsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgBackendMemoryContextsSchema,
PkOrdinals: nil,
}
}
// pgBackendMemoryContextsSchema is the schema for pg_backend_memory_contexts.
var pgBackendMemoryContextsSchema = sql.Schema{
{Name: "name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "ident", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "parent", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "level", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "total_bytes", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "total_nblocks", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "free_bytes", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "free_chunks", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
{Name: "used_bytes", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgBackendMemoryContextsName},
}
// pgBackendMemoryContextsRowIter is the sql.RowIter for the pg_backend_memory_contexts table.
type pgBackendMemoryContextsRowIter struct {
}
var _ sql.RowIter = (*pgBackendMemoryContextsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgBackendMemoryContextsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgBackendMemoryContextsRowIter) Close(ctx *sql.Context) error {
return nil
}
+129
View File
@@ -0,0 +1,129 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core"
"github.com/dolthub/doltgresql/core/casts"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgCastName is a constant to the pg_cast name.
const PgCastName = "pg_cast"
// InitPgCast handles registration of the pg_cast handler.
func InitPgCast() {
tables.AddHandler(PgCatalogName, PgCastName, PgCastHandler{})
}
// PgCastHandler is the handler for the pg_cast table.
type PgCastHandler struct{}
var _ tables.Handler = PgCastHandler{}
// Name implements the interface tables.Handler.
func (p PgCastHandler) Name() string {
return PgCastName
}
// RowIter implements the interface tables.Handler.
func (p PgCastHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
castsColl, err := core.GetCastsCollectionFromContext(ctx, "")
if err != nil {
return nil, err
}
var allCasts []casts.Cast
err = castsColl.IterateCasts(ctx, func(c casts.Cast) (stop bool, err error) {
allCasts = append(allCasts, c)
return false, nil
})
if err != nil {
return nil, err
}
return &pgCastRowIter{
allCasts: allCasts,
idx: 0,
}, nil
}
// PkSchema implements the interface tables.Handler.
func (p PgCastHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgCastSchema,
PkOrdinals: nil,
}
}
// pgCastSchema is the schema for pg_cast.
var pgCastSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgCastName},
{Name: "castsource", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgCastName},
{Name: "casttarget", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgCastName},
{Name: "castfunc", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgCastName},
{Name: "castcontext", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgCastName},
{Name: "castmethod", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgCastName},
}
// pgCastRowIter is the sql.RowIter for the pg_cast table.
type pgCastRowIter struct {
allCasts []casts.Cast
idx int
}
var _ sql.RowIter = (*pgCastRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgCastRowIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.allCasts) {
return nil, io.EOF
}
cast := iter.allCasts[iter.idx]
iter.idx++
var castContext string
switch cast.CastType {
case casts.CastType_Explicit:
castContext = "e"
case casts.CastType_Assignment:
castContext = "a"
case casts.CastType_Implicit:
castContext = "i"
}
var castMethod string
if cast.Function.IsValid() || cast.BuiltIn != nil {
castMethod = "f"
} else if cast.UseInOut {
castMethod = "i"
} else {
castMethod = "b"
}
return sql.Row{
cast.ID.AsId(),
cast.ID.SourceType().AsId(),
cast.ID.TargetType().AsId(),
cast.Function.AsId(),
castContext,
castMethod,
}, nil
}
// Close implements the interface sql.RowIter.
func (iter *pgCastRowIter) Close(ctx *sql.Context) error {
return nil
}
+250
View File
@@ -0,0 +1,250 @@
// 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 pgcatalog
import (
"github.com/cockroachdb/errors"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/functions"
)
// pgNamespace represents a row in the pg_namespace table.
// We store oids in their native format as well so that we can do range scans on them.
type pgNamespace struct {
oid id.Id
oidNative uint32
name string
}
// pgCatalogCache is a session cache that stores the contents of pg_catalog tables. Since this cache instance is only
// ever used by a single session, it does not include any synchronization for concurrent data access. A pgCatalogCache
// only caches data for the length of a single query, using |pid| to identify the current query. This means that the
// initial read of data from a pg_catalog table will always be generated fresh, then stored in this cache for any other
// table reads needed as part of that same query.
type pgCatalogCache struct {
// pid marks the process id for the query this cache data represents. pgCatalogCache instances currently only
// cache data within the context of a single query not across multiple queries.
pid uint64
// pg_classes
pgClasses *pgClassCache
// pg_type
pgTypes *pgTypeCache
// pg_constraints
pgConstraints *pgConstraintCache
// pg_namespace
pgNamespaces *pgNamespaceCache
// pg_attribute
pgAttributes *pgAttributeCache
// pg_index / pg_indexes
pgIndexes *pgIndexCache
// pg_sequence / pg_sequences
sequences []*pgSequence
// pg_attrdef
attrdefCols []functions.ItemColumnDefault
attrdefTableOIDs []id.Id
// pg_views
views []sql.ViewDefinition
viewSchemas []string
// pg_tables
tables []pgTableRow
}
// pgClassCache holds cached data for the pg_class table, including two btree indexes for fast lookups by OID and
// by relname
type pgClassCache struct {
classes []*pgClass
nameIdx *inMemIndexStorage[*pgClass]
oidIdx *inMemIndexStorage[*pgClass]
}
// getIndex implements BTreeStorageAccess.
func (p pgClassCache) getIndex(name string) *inMemIndexStorage[*pgClass] {
switch name {
case "pg_class_oid_index":
return p.oidIdx
case "pg_class_relname_nsp_index":
return p.nameIdx
default:
panic("unknown pg_class index: " + name)
}
}
var _ BTreeStorageAccess[*pgClass] = &pgClassCache{}
// pgTypeCache holds cached data for the pg_type table, including two btree indexes for fast lookups by OID and
// by typname
type pgTypeCache struct {
types []*pgType
nameIdx *inMemIndexStorage[*pgType]
oidIdx *inMemIndexStorage[*pgType]
}
// getIndex implements BTreeStorageAccess.
func (p pgTypeCache) getIndex(name string) *inMemIndexStorage[*pgType] {
switch name {
case pgTypeOidIndex:
return p.oidIdx
case pgTypnameIndex:
return p.nameIdx
default:
panic("unknown pg_type index: " + name)
}
}
var _ BTreeStorageAccess[*pgType] = &pgTypeCache{}
// pgIndexCache holds cached data for the pg_index table, including two btree indexes for fast lookups by index OID
type pgIndexCache struct {
indexes []*pgIndex
tableNames map[id.Id]string
indexOidIdx *inMemIndexStorage[*pgIndex]
indrelidIdx *inMemIndexStorage[*pgIndex]
}
var _ BTreeStorageAccess[*pgIndex] = &pgIndexCache{}
// pgConstraintCache holds cached data for the pg_constraint table, including three btree indexes for fast lookups
type pgConstraintCache struct {
constraints []*pgConstraint
oidIdx *inMemIndexStorage[*pgConstraint]
relidTypNameIdx *inMemIndexStorage[*pgConstraint]
nameSchemaIdx *inMemIndexStorage[*pgConstraint]
typIdx *inMemIndexStorage[*pgConstraint]
}
var _ BTreeStorageAccess[*pgConstraint] = &pgConstraintCache{}
// getIndex implements BTreeStorageAccess.
func (p pgConstraintCache) getIndex(name string) *inMemIndexStorage[*pgConstraint] {
switch name {
case "pg_constraint_oid_index":
return p.oidIdx
case "pg_constraint_conrelid_contypid_conname_index":
return p.relidTypNameIdx
case "pg_constraint_conname_nsp_index":
return p.nameSchemaIdx
case "pg_constraint_contypid_index":
return p.typIdx
default:
panic("unknown pg_constraint index: " + name)
}
}
// pgAttributeCache holds cached data for the pg_attribute table, including two btree indexes for fast lookups
type pgAttributeCache struct {
attributes []*pgAttribute
attrelidIdx *inMemIndexStorage[*pgAttribute]
attrelidAttnameIdx *inMemIndexStorage[*pgAttribute]
}
var _ BTreeStorageAccess[*pgAttribute] = &pgAttributeCache{}
// pgNamespaceCache holds cached data for the pg_namespace table, including two btree indexes for fast lookups by OID and by name
type pgNamespaceCache struct {
namespaces []*pgNamespace
oidIdx *inMemIndexStorage[*pgNamespace]
nameIdx *inMemIndexStorage[*pgNamespace]
}
var _ BTreeStorageAccess[*pgNamespace] = &pgNamespaceCache{}
// getIndex implements BTreeStorageAccess.
func (p pgNamespaceCache) getIndex(name string) *inMemIndexStorage[*pgNamespace] {
switch name {
case "pg_namespace_oid_index":
return p.oidIdx
case "pg_namespace_nspname_index":
return p.nameIdx
default:
panic("unknown pg_namespace index: " + name)
}
}
func (p pgAttributeCache) getIndex(name string) *inMemIndexStorage[*pgAttribute] {
switch name {
case "pg_attribute_relid_attnum_index":
return p.attrelidIdx
case "pg_attribute_relid_attnam_index":
return p.attrelidAttnameIdx
default:
panic("unknown pg_attribute index: " + name)
}
}
// getIndex implements BTreeStorageAccess.
func (p pgIndexCache) getIndex(name string) *inMemIndexStorage[*pgIndex] {
switch name {
case "pg_index_indexrelid_index":
return p.indexOidIdx
case "pg_index_indrelid_index":
return p.indrelidIdx
default:
panic("unknown pg_index index: " + name)
}
}
// newPgCatalogCache creates a new pgCatalogCache, with the query/process ID set to |pid|. The PID is important,
// since pgCatalogCache instances only cache data for the duration of a single query.
func newPgCatalogCache(pid uint64) *pgCatalogCache {
return &pgCatalogCache{
pid: pid,
}
}
// getPgCatalogCache returns the pgCatalogCache instance for the current query in this session. If no cache exists
// yet, then a new one is created and returned. Note that pgCatalogCache only caches catalog data for a single query,
// so if the PID of the current context does not match the PID of the context when the pgCatalogCache was created,
// then a new cache will be created.
func getPgCatalogCache(ctx *sql.Context) (*pgCatalogCache, error) {
untypedPgCatalogCache, err := core.GetPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if untypedPgCatalogCache == nil {
return initializeNewPgCatalogCache(ctx)
}
cache, ok := untypedPgCatalogCache.(*pgCatalogCache)
if !ok {
return nil, errors.Errorf("unexpected type %T for pg_catalog cache", untypedPgCatalogCache)
}
if cache.pid != ctx.Pid() {
return initializeNewPgCatalogCache(ctx)
}
return cache, nil
}
// initializeNewPgCatalogCache creates a new pgCatalogCache instance and sets it in the context. This function should
// not be used directly, and should only be used directly by getPgCatalogCache(*sql.Context).
func initializeNewPgCatalogCache(ctx *sql.Context) (*pgCatalogCache, error) {
cache := newPgCatalogCache(ctx.Pid())
if err := core.SetPgCatalogCache(ctx, cache); err != nil {
return nil, err
}
return cache, nil
}
+467
View File
@@ -0,0 +1,467 @@
// 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 pgcatalog
import (
"fmt"
"io"
"math"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/index"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgClassName is a constant to the pg_class name.
const PgClassName = "pg_class"
// InitPgClass handles registration of the pg_class handler.
func InitPgClass() {
tables.AddHandler(PgCatalogName, PgClassName, PgClassHandler{})
}
// PgClassHandler is the handler for the pg_class table.
type PgClassHandler struct{}
var _ tables.Handler = PgClassHandler{}
var _ tables.IndexedTableHandler = PgClassHandler{}
// Name implements the interface tables.Handler.
func (p PgClassHandler) Name() string {
return PgClassName
}
// RowIter implements the interface tables.Handler.
func (p PgClassHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// Use cached data from this session if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.pgClasses == nil {
err = cachePgClasses(ctx, pgCatalogCache)
if err != nil {
return nil, err
}
}
if classIdxPart, ok := partition.(inMemIndexPartition); ok {
return &inMemIndexScanIter[*pgClass]{
lookup: classIdxPart.lookup,
rangeConverter: p,
btreeAccess: pgCatalogCache.pgClasses,
rowConverter: pgClassToRow,
}, nil
}
return &pgClassTableScanIter{
classCache: pgCatalogCache.pgClasses,
idx: 0,
}, nil
}
// cachePgClasses caches the pg_class data for the current database in the session.
func cachePgClasses(ctx *sql.Context, pgCatalogCache *pgCatalogCache) error {
var classes []*pgClass
tableHasIndexes := make(map[uint32]struct{})
nameIdx := NewUniqueInMemIndexStorage[*pgClass](lessName)
oidIdx := NewUniqueInMemIndexStorage[*pgClass](lessOid)
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.AsId())] = struct{}{}
schemaOid := schema.OID
class := &pgClass{
oid: index.OID.AsId(),
oidNative: id.Cache().ToOID(index.OID.AsId()),
name: formatIndexName(index.Item),
hasIndexes: false,
kind: "i",
schemaOid: schemaOid.AsId(),
schemaOidNative: id.Cache().ToOID(schemaOid.AsId()),
relType: id.Null,
}
nameIdx.Add(class)
oidIdx.Add(class)
classes = append(classes, class)
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.AsId())]
class := &pgClass{
oid: table.OID.AsId(),
oidNative: id.Cache().ToOID(table.OID.AsId()),
name: table.Item.Name(),
hasIndexes: hasIndexes,
kind: "r",
schemaOid: schema.OID.AsId(),
schemaOidNative: id.Cache().ToOID(schema.OID.AsId()),
relType: id.NewType(table.OID.SchemaName(), table.OID.SchemaName()).AsId(),
}
nameIdx.Add(class)
oidIdx.Add(class)
classes = append(classes, class)
return true, nil
},
View: func(ctx *sql.Context, schema functions.ItemSchema, view functions.ItemView) (cont bool, err error) {
class := &pgClass{
oid: view.OID.AsId(),
oidNative: id.Cache().ToOID(view.OID.AsId()),
name: view.Item.Name,
hasIndexes: false,
kind: "v",
schemaOid: schema.OID.AsId(),
schemaOidNative: id.Cache().ToOID(schema.OID.AsId()),
relType: id.NewType(view.OID.SchemaName(), view.OID.SchemaName()).AsId(),
}
nameIdx.Add(class)
oidIdx.Add(class)
classes = append(classes, class)
return true, nil
},
Sequence: func(ctx *sql.Context, schema functions.ItemSchema, sequence functions.ItemSequence) (cont bool, err error) {
class := &pgClass{
oid: sequence.OID.AsId(),
oidNative: id.Cache().ToOID(sequence.OID.AsId()),
name: sequence.Item.Id.SequenceName(),
hasIndexes: false,
kind: "S",
schemaOid: schema.OID.AsId(),
schemaOidNative: id.Cache().ToOID(schema.OID.AsId()),
relType: id.Null,
}
nameIdx.Add(class)
oidIdx.Add(class)
classes = append(classes, class)
return true, nil
},
})
if err != nil {
return err
}
pgCatalogCache.pgClasses = &pgClassCache{
classes: classes,
nameIdx: nameIdx,
oidIdx: oidIdx,
}
return nil
}
// formatIndexName returns the name of an index for display
func formatIndexName(idx sql.Index) string {
if idx.ID() == "PRIMARY" {
return fmt.Sprintf("%s_pkey", idx.Table())
}
switch idx.(type) {
case *index.BranchNameIndex, *index.CommitIndex:
return fmt.Sprintf("%s_%s_key", idx.Table(), idx.ID())
}
return idx.ID()
// TODO: Unnamed indexes should have below format
// return fmt.Sprintf("%s_%s_key", idx.Table(), idx.ID())
}
// getIndexScanRange implements the interface RangeConverter.
func (p PgClassHandler) getIndexScanRange(rng sql.Range, index sql.Index) (*pgClass, bool, *pgClass, bool) {
var gte, lt *pgClass
var hasLowerBound, hasUpperBound bool
switch index.(pgCatalogInMemIndex).name {
case "pg_class_oid_index":
msrng := rng.(sql.MySQLRange)
oidRng := msrng[0]
if oidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(oidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
gte = &pgClass{
oidNative: idToOid(lowerRangeCutKey),
}
hasLowerBound = true
}
}
if oidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(oidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
lt = &pgClass{
oidNative: idToOid(upperRangeCutKey) + 1,
}
hasUpperBound = true
}
}
case "pg_class_relname_nsp_index":
msrng := rng.(sql.MySQLRange)
relNameRange := msrng[0]
schemaOidRange := msrng[1]
var relnameLower, relnameUpper string
schemaOidLower := uint32(0)
schemaOidUpper := uint32(math.MaxUint32)
schemaOidUpperSet := false
if relNameRange.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(relNameRange.LowerBound)
if lb != nil {
relnameLower = lb.(string)
hasLowerBound = true
}
}
if relNameRange.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(relNameRange.UpperBound)
if ub != nil {
relnameUpper = ub.(string)
hasUpperBound = true
}
}
if schemaOidRange.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(schemaOidRange.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
schemaOidLower = idToOid(lowerRangeCutKey)
}
}
if schemaOidRange.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(schemaOidRange.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
schemaOidUpper = idToOid(upperRangeCutKey)
schemaOidUpperSet = true
}
}
if relNameRange.HasLowerBound() || schemaOidRange.HasLowerBound() {
gte = &pgClass{
name: relnameLower,
schemaOidNative: schemaOidLower,
}
}
if relNameRange.HasUpperBound() || schemaOidRange.HasUpperBound() {
// our less-than upper bound depends on whether we have a prefix match or both fields were set
if !schemaOidUpperSet {
relnameUpper = fmt.Sprintf("%s%o", relnameUpper, rune(0))
} else {
schemaOidUpper = schemaOidUpper + 1
}
lt = &pgClass{
name: relnameUpper,
schemaOidNative: schemaOidUpper,
}
}
default:
panic("unknown index name: " + index.(pgCatalogInMemIndex).name)
}
return gte, hasLowerBound, lt, hasUpperBound
}
// idToOid converts an id.Id to its native uint32 OID representation. The type conversion process during index
// building will produce one of two values for comparison against an OID column: either a known OID value, which
// will be an Id of the appropriate type (Table, Namespace, etc), or an unknown value, which will be an oid.Oid.
func idToOid(i id.Id) uint32 {
switch i.Section() {
case id.Section_OID:
return id.Oid(i).OID()
default:
return id.Cache().ToOID(i)
}
}
// PkSchema implements the interface tables.Handler.
func (p PgClassHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgClassSchema,
PkOrdinals: nil,
}
}
// Indexes implements tables.IndexedTableHandler.
func (p PgClassHandler) Indexes() ([]sql.Index, error) {
return []sql.Index{
pgCatalogInMemIndex{
name: "pg_class_oid_index",
tblName: "pg_class",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{{Expression: "pg_class.oid", Type: pgtypes.Oid}},
},
pgCatalogInMemIndex{
name: "pg_class_relname_nsp_index",
tblName: "pg_class",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{
{Expression: "pg_class.relname", Type: pgtypes.Name},
{Expression: "pg_class.relnamespace", Type: pgtypes.Oid},
},
},
}, nil
}
// LookupPartitions implements tables.IndexedTableHandler.
func (p PgClassHandler) LookupPartitions(context *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error) {
return &inMemIndexPartIter{
part: inMemIndexPartition{
idxName: lookup.Index.(pgCatalogInMemIndex).name,
lookup: lookup,
},
}, nil
}
// pgClassSchema is the schema for pg_class.
var pgClassSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relnamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "reltype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "reloftype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relam", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relfilenode", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "reltablespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relpages", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgClassName},
{Name: "reltuples", Type: pgtypes.Float32, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relallvisible", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgClassName},
{Name: "reltoastrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relhasindex", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relisshared", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relpersistence", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relkind", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relnatts", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relchecks", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relhasrules", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relhastriggers", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relhassubclass", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relrowsecurity", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relforcerowsecurity", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relispopulated", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relreplident", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relispartition", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relrewrite", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relfrozenxid", Type: pgtypes.Xid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relminmxid", Type: pgtypes.Xid, Default: nil, Nullable: false, Source: PgClassName},
{Name: "relacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgClassName}, // TODO: type aclitem[]
{Name: "reloptions", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgClassName}, // TODO: collation C
{Name: "relpartbound", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgClassName}, // TODO: type pg_node_tree, collation C
}
// pgClass represents a row in the pg_class table.
// We store oids in their native format as well so that we can do range scans on them.
type pgClass struct {
oid id.Id
oidNative uint32
name string
schemaOid id.Id
schemaOidNative uint32
hasIndexes bool
kind string // r = ordinary table, i = index, S = sequence, t = TOAST table, v = view, m = materialized view, c = composite type, f = foreign table, p = partitioned table, I = partitioned index
relType id.Id
}
// lessOid is a sort function for pgClass based on oid.
func lessOid(a, b *pgClass) bool {
return a.oidNative < b.oidNative
}
// lessName is a sort function for pgClass based on name, then schemaOid.
func lessName(a, b *pgClass) bool {
if a.name == b.name {
return a.schemaOidNative < b.schemaOidNative
}
return a.name < b.name
}
// pgClassTableScanIter is the sql.RowIter for the pg_class table.
type pgClassTableScanIter struct {
classCache *pgClassCache
idx int
}
var _ sql.RowIter = (*pgClassTableScanIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgClassTableScanIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.classCache.classes) {
return nil, io.EOF
}
iter.idx++
class := iter.classCache.classes[iter.idx-1]
return pgClassToRow(class), nil
}
func pgClassToRow(class *pgClass) sql.Row {
// TODO: this is temporary definition of 'relam' field
var relam = id.Null
if class.kind == "i" {
relam = id.NewAccessMethod("btree").AsId()
} else if class.kind == "r" || class.kind == "t" {
relam = id.NewAccessMethod("heap").AsId()
}
// TODO: Fill in the rest of the pg_class columns
return sql.Row{
class.oid, // oid
class.name, // relname
class.schemaOid, // relnamespace
class.relType, // reltype
id.Null, // reloftype
id.Null, // relowner
relam, // relam
id.Null, // relfilenode
id.Null, // reltablespace
int32(0), // relpages
float32(0), // reltuples
int32(0), // relallvisible
id.Null, // reltoastrelid
class.hasIndexes, // relhasindex
false, // relisshared
"p", // relpersistence
class.kind, // relkind
int16(0), // relnatts
int16(0), // relchecks
false, // relhasrules
false, // relhastriggers
false, // relhassubclass
false, // relrowsecurity
false, // relforcerowsecurity
true, // relispopulated
"d", // relreplident
false, // relispartition
id.Null, // relrewrite
uint32(0), // relfrozenxid
uint32(0), // relminmxid
nil, // relacl
nil, // reloptions
nil, // relpartbound
}
}
// Close implements the interface sql.RowIter.
func (iter *pgClassTableScanIter) Close(ctx *sql.Context) error {
return nil
}
+87
View File
@@ -0,0 +1,87 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgCollationName is a constant to the pg_collation name.
const PgCollationName = "pg_collation"
// InitPgCollation handles registration of the pg_collation handler.
func InitPgCollation() {
tables.AddHandler(PgCatalogName, PgCollationName, PgCollationHandler{})
}
// PgCollationHandler is the handler for the pg_collation table.
type PgCollationHandler struct{}
var _ tables.Handler = PgCollationHandler{}
// Name implements the interface tables.Handler.
func (p PgCollationHandler) Name() string {
return PgCollationName
}
// RowIter implements the interface tables.Handler.
func (p PgCollationHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_collation row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgCollationHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: PgCollationSchema,
PkOrdinals: nil,
}
}
// PgCollationSchema is the schema for pg_collation.
var PgCollationSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgCollationName},
{Name: "collname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgCollationName},
{Name: "collnamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgCollationName},
{Name: "collowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgCollationName},
{Name: "collprovider", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgCollationName},
{Name: "collisdeterministic", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgCollationName},
{Name: "collencoding", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgCollationName},
{Name: "collcollate", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgCollationName}, // TODO: collation C
{Name: "collctype", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgCollationName}, // TODO: collation C
{Name: "colliculocale", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgCollationName}, // TODO: collation C
{Name: "collversion", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgCollationName}, // TODO: collation C
}
// pgCollationRowIter is the sql.RowIter for the pg_collation table.
type pgCollationRowIter struct {
}
var _ sql.RowIter = (*pgCollationRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgCollationRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgCollationRowIter) Close(ctx *sql.Context) error {
return nil
}
+78
View File
@@ -0,0 +1,78 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgConfigName is a constant to the pg_config name.
const PgConfigName = "pg_config"
// InitPgConfig handles registration of the pg_config handler.
func InitPgConfig() {
tables.AddHandler(PgCatalogName, PgConfigName, PgConfigHandler{})
}
// PgConfigHandler is the handler for the pg_config table.
type PgConfigHandler struct{}
var _ tables.Handler = PgConfigHandler{}
// Name implements the interface tables.Handler.
func (p PgConfigHandler) Name() string {
return PgConfigName
}
// RowIter implements the interface tables.Handler.
func (p PgConfigHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_config row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgConfigHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgConfigSchema,
PkOrdinals: nil,
}
}
// pgConfigSchema is the schema for pg_config.
var pgConfigSchema = sql.Schema{
{Name: "name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgConfigName},
{Name: "setting", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgConfigName},
}
// pgConfigRowIter is the sql.RowIter for the pg_config table.
type pgConfigRowIter struct {
}
var _ sql.RowIter = (*pgConfigRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgConfigRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgConfigRowIter) Close(ctx *sql.Context) error {
return nil
}
+711
View File
@@ -0,0 +1,711 @@
// 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 pgcatalog
import (
"fmt"
"io"
"math"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgConstraintName is a constant to the pg_constraint name.
const PgConstraintName = "pg_constraint"
// InitPgConstraint handles registration of the pg_constraint handler.
func InitPgConstraint() {
tables.AddHandler(PgCatalogName, PgConstraintName, PgConstraintHandler{})
}
// PgConstraintHandler is the handler for the pg_constraint table.
type PgConstraintHandler struct{}
var _ tables.Handler = PgConstraintHandler{}
var _ tables.IndexedTableHandler = PgConstraintHandler{}
// Name implements the interface tables.Handler.
func (p PgConstraintHandler) Name() string {
return PgConstraintName
}
// RowIter implements the interface tables.Handler.
func (p PgConstraintHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// Use cached data from this session if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.pgConstraints == nil {
err = cachePgConstraints(ctx, pgCatalogCache)
if err != nil {
return nil, err
}
}
if constraintIdxPart, ok := partition.(inMemIndexPartition); ok {
return &inMemIndexScanIter[*pgConstraint]{
lookup: constraintIdxPart.lookup,
rangeConverter: p,
btreeAccess: pgCatalogCache.pgConstraints,
rowConverter: pgConstraintToRow,
}, nil
}
return &pgConstraintTableScanIter{
constraintCache: pgCatalogCache.pgConstraints,
idx: 0,
}, nil
}
func getFKMatchType(matchType sql.ForeignKeyMatchType) string {
switch matchType {
case sql.ForeignKeyMatchType_Full:
return "f"
default:
return "s"
}
}
func getFKAction(action sql.ForeignKeyReferentialAction) string {
switch action {
case sql.ForeignKeyReferentialAction_NoAction:
return "a"
case sql.ForeignKeyReferentialAction_Restrict:
return "r"
case sql.ForeignKeyReferentialAction_Cascade:
return "c"
case sql.ForeignKeyReferentialAction_SetNull:
return "n"
case sql.ForeignKeyReferentialAction_SetDefault:
return "d"
default:
return ""
}
}
// PkSchema implements the interface tables.Handler.
func (p PgConstraintHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: PgConstraintSchema,
PkOrdinals: nil,
}
}
// Indexes implements tables.IndexedTableHandler.
func (p PgConstraintHandler) Indexes() ([]sql.Index, error) {
return []sql.Index{
pgCatalogInMemIndex{
name: "pg_constraint_oid_index",
tblName: "pg_constraint",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{{Expression: "pg_constraint.oid", Type: pgtypes.Oid}},
},
pgCatalogInMemIndex{
name: "pg_constraint_conrelid_contypid_conname_index",
tblName: "pg_constraint",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{
{Expression: "pg_constraint.conrelid", Type: pgtypes.Oid},
{Expression: "pg_constraint.contypid", Type: pgtypes.Oid},
{Expression: "pg_constraint.conname", Type: pgtypes.Name},
},
},
pgCatalogInMemIndex{
name: "pg_constraint_conname_nsp_index",
tblName: "pg_constraint",
dbName: "pg_catalog",
uniq: false,
columnExprs: []sql.ColumnExpressionType{
{Expression: "pg_constraint.conname", Type: pgtypes.Name},
{Expression: "pg_constraint.connamespace", Type: pgtypes.Oid},
},
},
// pg_constraint_conparentid_index is skipped because we don't support partitions, but might be worth
// implementing if it makes any tool faster
pgCatalogInMemIndex{
name: "pg_constraint_contypid_index",
tblName: "pg_constraint",
dbName: "pg_catalog",
uniq: false,
columnExprs: []sql.ColumnExpressionType{
{Expression: "pg_constraint.contypid", Type: pgtypes.Oid},
},
},
}, nil
}
// LookupPartitions implements tables.IndexedTableHandler.
func (p PgConstraintHandler) LookupPartitions(context *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error) {
return &inMemIndexPartIter{
part: inMemIndexPartition{
idxName: lookup.Index.(pgCatalogInMemIndex).name,
lookup: lookup,
},
}, nil
}
// getIndexScanRange implements the interface RangeConverter.
func (p PgConstraintHandler) getIndexScanRange(rng sql.Range, index sql.Index) (*pgConstraint, bool, *pgConstraint, bool) {
var gte, lt *pgConstraint
var hasLowerBound, hasUpperBound bool
switch index.(pgCatalogInMemIndex).name {
case "pg_constraint_oid_index":
msrng := rng.(sql.MySQLRange)
oidRng := msrng[0]
if oidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(oidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
gte = &pgConstraint{
oidNative: idToOid(lowerRangeCutKey),
}
hasLowerBound = true
}
}
if oidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(oidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
lt = &pgConstraint{
oidNative: idToOid(upperRangeCutKey) + 1,
}
hasUpperBound = true
}
}
case "pg_constraint_conrelid_contypid_conname_index":
msrng := rng.(sql.MySQLRange)
relOidRng := msrng[0]
typOidRng := msrng[1]
nameRng := msrng[2]
relOidLower := uint32(0)
relOidUpper := uint32(math.MaxUint32)
relOidUpperSet := false
typOidLower := uint32(0)
typOidUpper := uint32(math.MaxUint32)
typOidUpperSet := false
nameLower := ""
nameUpper := ""
nameUpperSet := false
if relOidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(relOidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
relOidLower = idToOid(lowerRangeCutKey)
hasLowerBound = true
}
}
if relOidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(relOidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
relOidUpper = idToOid(upperRangeCutKey)
relOidUpperSet = true
hasUpperBound = true
}
}
if typOidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(typOidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
typOidLower = idToOid(lowerRangeCutKey)
hasLowerBound = true
}
}
if typOidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(typOidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
typOidUpper = idToOid(upperRangeCutKey)
typOidUpperSet = true
hasUpperBound = true
}
}
if nameRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(nameRng.LowerBound)
if lb != nil {
nameLower = lb.(string)
hasLowerBound = true
}
}
if nameRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(nameRng.UpperBound)
if ub != nil {
nameUpper = ub.(string)
nameUpperSet = true
hasUpperBound = true
}
}
if hasLowerBound {
gte = &pgConstraint{
tableOidNative: relOidLower,
typeOidNative: typOidLower,
name: nameLower,
}
}
if hasUpperBound {
// our less-than upper bounds depend on how many fields were set
if typOidUpperSet {
if nameUpperSet {
nameUpper = fmt.Sprintf("%s%o", nameUpper, rune(0))
} else {
typOidUpper = typOidUpper + 1
}
} else {
if !relOidUpperSet {
relOidUpper = relOidUpper + 1
}
}
lt = &pgConstraint{
tableOidNative: relOidUpper,
typeOidNative: typOidUpper,
name: nameUpper,
}
}
case "pg_constraint_conname_nsp_index":
msrng := rng.(sql.MySQLRange)
conNameRange := msrng[0]
schemaOidRange := msrng[1]
var conNameLower, conNameUpper string
schemaOidLower := uint32(0)
schemaOidUpper := uint32(math.MaxUint32)
schemaOidUpperSet := false
if conNameRange.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(conNameRange.LowerBound)
if lb != nil {
conNameLower = lb.(string)
hasLowerBound = true
}
}
if conNameRange.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(conNameRange.UpperBound)
if ub != nil {
conNameUpper = ub.(string)
hasUpperBound = true
}
}
if schemaOidRange.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(schemaOidRange.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
schemaOidLower = idToOid(lowerRangeCutKey)
}
}
if schemaOidRange.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(schemaOidRange.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
schemaOidUpper = idToOid(upperRangeCutKey)
schemaOidUpperSet = true
}
}
if conNameRange.HasLowerBound() || schemaOidRange.HasLowerBound() {
gte = &pgConstraint{
name: conNameLower,
schemaOidNative: schemaOidLower,
}
}
if conNameRange.HasUpperBound() || schemaOidRange.HasUpperBound() {
// our less-than upper bound depends on whether we have a prefix match or both fields were set
if !schemaOidUpperSet {
conNameUpper = fmt.Sprintf("%s%o", conNameUpper, rune(0))
} else {
schemaOidUpper = schemaOidUpper + 1
}
lt = &pgConstraint{
name: conNameUpper,
schemaOidNative: schemaOidUpper,
}
}
case "pg_constraint_contypid_index":
msrng := rng.(sql.MySQLRange)
typOidRng := msrng[0]
if typOidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(typOidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
gte = &pgConstraint{
typeOidNative: idToOid(lowerRangeCutKey),
}
hasLowerBound = true
}
}
if typOidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(typOidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
lt = &pgConstraint{
typeOidNative: idToOid(upperRangeCutKey) + 1,
}
hasUpperBound = true
}
}
default:
panic("unknown index name: " + index.(pgCatalogInMemIndex).name)
}
return gte, hasLowerBound, lt, hasUpperBound
}
// cachePgConstraints caches the pg_constraint data for the current database in the session.
func cachePgConstraints(ctx *sql.Context, pgCatalogCache *pgCatalogCache) error {
var constraints []*pgConstraint
tableOIDs := make(map[id.Id]map[string]id.Id)
tableColToIdxMap := make(map[string]int16)
oidIdx := NewUniqueInMemIndexStorage[*pgConstraint](lessConstraintOid)
nameSchemaIdx := NewNonUniqueInMemIndexStorage[*pgConstraint](lessConstraintNameSchema)
relidTypNameIdx := NewUniqueInMemIndexStorage[*pgConstraint](lessConstraintRelidTypeName)
typIdx := NewNonUniqueInMemIndexStorage[*pgConstraint](lessConstraintType)
// 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.AsId()]
if !ok {
inner = make(map[string]id.Id)
tableOIDs[schema.OID.AsId()] = inner
}
inner[table.Item.Name()] = table.OID.AsId()
for i, col := range table.Item.Schema(ctx) {
tableColToIdxMap[fmt.Sprintf("%s.%s", table.Item.Name(), col.Name)] = int16(i + 1)
}
return true, nil
},
})
if err != nil {
return err
}
// Then we iterate over everything to fill our constraints
err = functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Check: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, check functions.ItemCheck) (cont bool, err error) {
constraint := &pgConstraint{
oid: check.OID.AsId(),
oidNative: id.Cache().ToOID(check.OID.AsId()),
name: check.Item.Name,
schemaOid: schema.OID.AsId(),
schemaOidNative: id.Cache().ToOID(schema.OID.AsId()),
conType: "c",
tableOid: table.OID.AsId(),
tableOidNative: id.Cache().ToOID(table.OID.AsId()),
typeOid: id.Id(id.NewOID(0)),
convalidated: !check.Item.IsNotValid,
}
oidIdx.Add(constraint)
relidTypNameIdx.Add(constraint)
nameSchemaIdx.Add(constraint)
typIdx.Add(constraint)
constraints = append(constraints, constraint)
return true, nil
},
ForeignKey: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, foreignKey functions.ItemForeignKey) (cont bool, err error) {
conKey := make([]any, len(foreignKey.Item.Columns))
for i, col := range foreignKey.Item.Columns {
keyExpr := fmt.Sprintf("%s.%s", foreignKey.Item.Table, col)
conKey[i] = tableColToIdxMap[keyExpr]
}
parentTableColToIdxMap := make(map[string]int16)
parentTable, ok, err := schema.Item.GetTableInsensitive(ctx, foreignKey.Item.ParentTable)
if err != nil {
return false, err
} else if ok {
for i, col := range parentTable.Schema(ctx) {
parentTableColToIdxMap[col.Name] = int16(i + 1)
}
}
conFkey := make([]any, len(foreignKey.Item.ParentColumns))
for i, expr := range foreignKey.Item.ParentColumns {
conFkey[i] = parentTableColToIdxMap[expr]
}
constraint := &pgConstraint{
oid: foreignKey.OID.AsId(),
oidNative: id.Cache().ToOID(foreignKey.OID.AsId()),
name: foreignKey.Item.Name,
schemaOid: schema.OID.AsId(),
schemaOidNative: id.Cache().ToOID(schema.OID.AsId()),
conType: "f",
tableOid: tableOIDs[schema.OID.AsId()][foreignKey.Item.Table],
tableOidNative: id.Cache().ToOID(tableOIDs[schema.OID.AsId()][foreignKey.Item.Table]),
idxOid: foreignKey.OID.AsId(),
tableRefOid: tableOIDs[schema.OID.AsId()][foreignKey.Item.ParentTable],
fkUpdateType: getFKAction(foreignKey.Item.OnUpdate),
fkDeleteType: getFKAction(foreignKey.Item.OnDelete),
fkMatchType: getFKMatchType(foreignKey.Item.MatchType),
conKey: conKey,
conFkey: conFkey,
typeOid: id.Id(id.NewOID(0)),
convalidated: !foreignKey.Item.IsNotValid,
}
oidIdx.Add(constraint)
relidTypNameIdx.Add(constraint)
nameSchemaIdx.Add(constraint)
typIdx.Add(constraint)
constraints = append(constraints, constraint)
return true, nil
},
Index: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, index functions.ItemIndex) (cont bool, err error) {
conType := "p"
if index.Item.ID() != "PRIMARY" {
if index.Item.IsUnique() {
conType = "u"
} else {
// If this isn't a primary key or a unique index, then it's a regular index, and not
// a constraint, so we don't need to report it in the pg_constraint table.
return true, nil
}
}
conKey := make([]any, len(index.Item.Expressions()))
for i, expr := range index.Item.Expressions() {
conKey[i] = tableColToIdxMap[expr]
}
constraint := &pgConstraint{
oid: index.OID.AsId(),
oidNative: id.Cache().ToOID(index.OID.AsId()),
name: formatIndexName(index.Item),
schemaOid: schema.OID.AsId(),
schemaOidNative: id.Cache().ToOID(schema.OID.AsId()),
conType: conType,
tableOid: table.OID.AsId(),
tableOidNative: id.Cache().ToOID(table.OID.AsId()),
idxOid: index.OID.AsId(),
conKey: conKey,
typeOid: id.Id(id.NewOID(0)),
convalidated: true,
}
oidIdx.Add(constraint)
relidTypNameIdx.Add(constraint)
nameSchemaIdx.Add(constraint)
typIdx.Add(constraint)
constraints = append(constraints, constraint)
return true, nil
},
Type: func(ctx *sql.Context, schema functions.ItemSchema, typ functions.ItemType) (cont bool, err error) {
for _, check := range typ.Item.Checks {
checkOid := id.NewCheck(schema.Item.SchemaName(), "", check.Name)
constraint := &pgConstraint{
oid: checkOid.AsId(),
oidNative: id.Cache().ToOID(checkOid.AsId()),
name: check.Name,
schemaOid: schema.OID.AsId(),
schemaOidNative: id.Cache().ToOID(schema.OID.AsId()),
conType: "c",
typeOid: typ.Oid.AsId(),
typeOidNative: id.Cache().ToOID(typ.Oid.AsId()),
}
oidIdx.Add(constraint)
relidTypNameIdx.Add(constraint)
nameSchemaIdx.Add(constraint)
typIdx.Add(constraint)
constraints = append(constraints, constraint)
}
return true, nil
},
})
if err != nil {
return err
}
pgCatalogCache.pgConstraints = &pgConstraintCache{
constraints: constraints,
oidIdx: oidIdx,
relidTypNameIdx: relidTypNameIdx,
nameSchemaIdx: nameSchemaIdx,
typIdx: typIdx,
}
return nil
}
// lessConstraintOid is a sort function for pgConstraint based on oid.
func lessConstraintOid(a, b *pgConstraint) bool {
return a.oidNative < b.oidNative
}
// lessConstraintRelidTypeName is a sort function for pgConstraint based on conrelid, contypid, then conname.
func lessConstraintRelidTypeName(a, b *pgConstraint) bool {
if a.tableOidNative == b.tableOidNative {
if a.typeOidNative == b.typeOidNative {
return a.name < b.name
}
return a.typeOidNative < b.typeOidNative
}
return a.tableOidNative < b.tableOidNative
}
// lessConstraintNameSchema is a sort function for pgConstraint based on conname, then schemaOid.
func lessConstraintNameSchema(a, b []*pgConstraint) bool {
if a[0].name == b[0].name {
return a[0].schemaOidNative < b[0].schemaOidNative
}
return a[0].name < b[0].name
}
// lessConstraintType is a sort function for pgConstraint based on type oid.
func lessConstraintType(a, b []*pgConstraint) bool {
return a[0].typeOidNative < b[0].typeOidNative
}
// PgConstraintSchema is the schema for pg_constraint.
var PgConstraintSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "conname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "connamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "contype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "condeferrable", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "condeferred", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "convalidated", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "conrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "contypid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "conindid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "conparentid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "confrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "confupdtype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "confdeltype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "confmatchtype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "conislocal", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "coninhcount", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "connoinherit", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgConstraintName},
{Name: "conkey", Type: pgtypes.Int16Array, Default: nil, Nullable: true, Source: PgConstraintName},
{Name: "confkey", Type: pgtypes.Int16Array, Default: nil, Nullable: true, Source: PgConstraintName},
{Name: "conpfeqop", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgConstraintName},
{Name: "conppeqop", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgConstraintName},
{Name: "conffeqop", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgConstraintName},
{Name: "confdelsetcols", Type: pgtypes.Int16Array, Default: nil, Nullable: true, Source: PgConstraintName},
{Name: "conexclop", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgConstraintName},
{Name: "conbin", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgConstraintName}, // TODO: type pg_node_tree, collation C
}
// pgConstraint is the struct for the pg_constraint table.
// We store oids in their native format as well so that we can do range scans on them.
type pgConstraint struct {
oid id.Id
oidNative uint32
name string
schemaOid id.Id
schemaOidNative uint32
conType string // c = check constraint, f = foreign key constraint, p = primary key constraint, u = unique constraint, t = constraint trigger, x = exclusion constraint
tableOid id.Id
tableOidNative uint32
typeOid id.Id
typeOidNative uint32
idxOid id.Id
tableRefOid id.Id
fkUpdateType string // a = no action, r = restrict, c = cascade, n = set null, d = set default
fkDeleteType string // a = no action, r = restrict, c = cascade, n = set null, d = set default
fkMatchType string // f = full, p = partial, s = simple
conKey []any
conFkey []any
convalidated bool
}
// pgConstraintTableScanIter is the sql.RowIter for the pg_constraint table.
type pgConstraintTableScanIter struct {
constraintCache *pgConstraintCache
idx int
}
var _ sql.RowIter = (*pgConstraintTableScanIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgConstraintTableScanIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.constraintCache.constraints) {
return nil, io.EOF
}
iter.idx++
constraint := iter.constraintCache.constraints[iter.idx-1]
return pgConstraintToRow(constraint), nil
}
// Close implements the interface sql.RowIter.
func (iter *pgConstraintTableScanIter) Close(ctx *sql.Context) error {
return nil
}
// pgConstraintToRow converts a pgConstraint to a sql.Row.
func pgConstraintToRow(constraint *pgConstraint) sql.Row {
var conKey interface{}
if len(constraint.conKey) == 0 {
conKey = nil
} else {
conKey = constraint.conKey
}
var conFkey interface{}
if len(constraint.conFkey) == 0 {
conFkey = nil
} else {
conFkey = constraint.conFkey
}
return sql.Row{
constraint.oid, // oid
constraint.name, // conname
constraint.schemaOid, // connamespace
constraint.conType, // contype
false, // condeferrable
false, // condeferred
constraint.convalidated, // convalidated
constraint.tableOid, // conrelid
constraint.typeOid, // contypid
constraint.idxOid, // conindid
id.Null, // conparentid
constraint.tableRefOid, // confrelid
constraint.fkUpdateType, // confupdtype
constraint.fkDeleteType, // confdeltype
constraint.fkMatchType, // confmatchtype
true, // conislocal
int16(0), // coninhcount
true, // connoinherit
conKey, // conkey
conFkey, // confkey
nil, // conpfeqop
nil, // conppeqop
nil, // conffeqop
nil, // confdelsetcols
nil, // conexclop
nil, // conbin
}
}
+47
View File
@@ -0,0 +1,47 @@
package pgcatalog
import (
"testing"
assert "github.com/stretchr/testify/require"
)
func TestIndexes(t *testing.T) {
// Only the fields that impact indexing are set here
con1 := &pgConstraint{
oidNative: 100,
name: "abc",
tableOidNative: 300,
typeOidNative: 0, // this means the constraint is on a table, not a type
schemaOidNative: 500,
}
relidTypNameIdx := NewUniqueInMemIndexStorage[*pgConstraint](lessConstraintRelidTypeName)
relidTypNameIdx.Add(con1)
var foundElements []*pgConstraint
cb := func(c *pgConstraint) bool {
foundElements = append(foundElements, c)
return true
}
// lookup by relid
relidTypNameIdx.uniqTree.AscendRange(
&pgConstraint{tableOidNative: 300},
&pgConstraint{tableOidNative: 301},
cb,
)
assert.Equal(t, []*pgConstraint{con1}, foundElements)
foundElements = nil
// lookup by relid, typeid
relidTypNameIdx.uniqTree.AscendRange(
&pgConstraint{tableOidNative: 300, typeOidNative: 0},
&pgConstraint{tableOidNative: 300, typeOidNative: 1},
cb,
)
assert.Equal(t, []*pgConstraint{con1}, foundElements)
}
+84
View File
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgConversionName is a constant to the pg_conversion name.
const PgConversionName = "pg_conversion"
// InitPgConversion handles registration of the pg_conversion handler.
func InitPgConversion() {
tables.AddHandler(PgCatalogName, PgConversionName, PgConversionHandler{})
}
// PgConversionHandler is the handler for the pg_conversion table.
type PgConversionHandler struct{}
var _ tables.Handler = PgConversionHandler{}
// Name implements the interface tables.Handler.
func (p PgConversionHandler) Name() string {
return PgConversionName
}
// RowIter implements the interface tables.Handler.
func (p PgConversionHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_conversion row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgConversionHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: PgConversionSchema,
PkOrdinals: nil,
}
}
// PgConversionSchema is the schema for pg_conversion.
var PgConversionSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConversionName},
{Name: "conname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgConversionName},
{Name: "connamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConversionName},
{Name: "conowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgConversionName},
{Name: "conforencoding", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgConversionName},
{Name: "contoencoding", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgConversionName},
{Name: "conproc", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgConversionName}, // TODO: regproc type
{Name: "condefault", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgConversionName},
}
// pgConversionRowIter is the sql.RowIter for the pg_conversion table.
type pgConversionRowIter struct {
}
var _ sql.RowIter = (*pgConversionRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgConversionRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgConversionRowIter) Close(ctx *sql.Context) error {
return nil
}
+82
View File
@@ -0,0 +1,82 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgCursorsName is a constant to the pg_cursors name.
const PgCursorsName = "pg_cursors"
// InitPgCursors handles registration of the pg_cursors handler.
func InitPgCursors() {
tables.AddHandler(PgCatalogName, PgCursorsName, PgCursorsHandler{})
}
// PgCursorsHandler is the handler for the pg_cursors table.
type PgCursorsHandler struct{}
var _ tables.Handler = PgCursorsHandler{}
// Name implements the interface tables.Handler.
func (p PgCursorsHandler) Name() string {
return PgCursorsName
}
// RowIter implements the interface tables.Handler.
func (p PgCursorsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_cursors row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgCursorsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgCursorsSchema,
PkOrdinals: nil,
}
}
// pgCursorsSchema is the schema for pg_cursors.
var pgCursorsSchema = sql.Schema{
{Name: "name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgCursorsName},
{Name: "statement", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgCursorsName},
{Name: "is_holdable", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgCursorsName},
{Name: "is_binary", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgCursorsName},
{Name: "is_scrollable", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgCursorsName},
{Name: "creation_time", Type: pgtypes.TimestampTZ, Default: nil, Nullable: true, Source: PgCursorsName},
}
// pgCursorsRowIter is the sql.RowIter for the pg_cursors table.
type pgCursorsRowIter struct {
}
var _ sql.RowIter = (*pgCursorsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgCursorsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgCursorsRowIter) Close(ctx *sql.Context) error {
return nil
}
+144
View File
@@ -0,0 +1,144 @@
// 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 pgcatalog
import (
"io"
"sort"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
sqle "github.com/dolthub/go-mysql-server"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgDatabaseName is a constant to the pg_database name.
const PgDatabaseName = "pg_database"
// InitPgDatabase handles registration of the pg_database handler.
func InitPgDatabase() {
tables.AddHandler(PgCatalogName, PgDatabaseName, PgDatabaseHandler{})
}
// PgDatabaseHandler is the handler for the pg_database table.
type PgDatabaseHandler struct{}
var _ tables.Handler = PgDatabaseHandler{}
// Name implements the interface tables.Handler.
func (p PgDatabaseHandler) Name() string {
return PgDatabaseName
}
// RowIter implements the interface tables.Handler.
func (p PgDatabaseHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Should the catalog be passed to RowIter like it is for the information_schema tables RowIter?
doltSession := dsess.DSessFromSess(ctx.Session)
c := sqle.NewDefault(doltSession.Provider()).Analyzer.Catalog
databases := c.AllDatabases(ctx)
dbs := make([]sql.Database, 0, len(databases))
for _, db := range databases {
name := db.Name()
if name == "information_schema" || name == "pg_catalog" || name == "performance_schema" {
continue
}
dbs = append(dbs, db)
}
sort.Slice(dbs, func(i, j int) bool {
return dbs[i].Name() < dbs[j].Name()
})
return &pgDatabaseRowIter{
dbs: dbs,
idx: 0,
}, nil
}
// PkSchema implements the interface tables.Handler.
func (p PgDatabaseHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgDatabaseSchema,
PkOrdinals: nil,
}
}
// pgDatabaseSchema is the schema for pg_database.
var pgDatabaseSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datdba", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "encoding", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datlocprovider", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datistemplate", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datallowconn", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datconnlimit", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datfrozenxid", Type: pgtypes.Xid, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datminmxid", Type: pgtypes.Xid, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "dattablespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datcollate", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgDatabaseName}, // TODO: collation C
{Name: "datctype", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgDatabaseName}, // TODO: collation C
{Name: "daticulocale", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgDatabaseName}, // TODO: collation C
{Name: "daticurules", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgDatabaseName},
{Name: "datcollversion", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgDatabaseName}, // TODO: collation C
{Name: "datacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgDatabaseName}, // TODO: type aclitem[]
}
// pgDatabaseRowIter is the sql.RowIter for the pg_database table.
type pgDatabaseRowIter struct {
dbs []sql.Database
idx int
}
var _ sql.RowIter = (*pgDatabaseRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgDatabaseRowIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.dbs) {
return nil, io.EOF
}
iter.idx++
db := iter.dbs[iter.idx-1]
dbOid := id.NewDatabase(db.Name()).AsId()
// TODO: Add the rest of the pg_database columns
return sql.Row{
dbOid, // oid
db.Name(), // datname
id.Null, // datdba
int32(6), // encoding
"i", // datlocprovider
false, // datistemplate
true, // datallowconn
int32(-1), // datconnlimit
uint32(0), // datfrozenxid
uint32(0), // datminmxid
id.Null, // dattablespace
"", // datcollate
"", // datctype
nil, // daticulocale
"", // daticurules
nil, // datcollversion
nil, // datacl
}, nil
}
// Close implements the interface sql.RowIter.
func (iter *pgDatabaseRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,79 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgDbRoleSettingName is a constant to the pg_db_role_setting name.
const PgDbRoleSettingName = "pg_db_role_setting"
// InitPgDbRoleSetting handles registration of the pg_db_role_setting handler.
func InitPgDbRoleSetting() {
tables.AddHandler(PgCatalogName, PgDbRoleSettingName, PgDbRoleSettingHandler{})
}
// PgDbRoleSettingHandler is the handler for the pg_db_role_setting table.
type PgDbRoleSettingHandler struct{}
var _ tables.Handler = PgDbRoleSettingHandler{}
// Name implements the interface tables.Handler.
func (p PgDbRoleSettingHandler) Name() string {
return PgDbRoleSettingName
}
// RowIter implements the interface tables.Handler.
func (p PgDbRoleSettingHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_db_role_setting row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgDbRoleSettingHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgDbRoleSettingSchema,
PkOrdinals: nil,
}
}
// pgDbRoleSettingSchema is the schema for pg_db_role_setting.
var pgDbRoleSettingSchema = sql.Schema{
{Name: "setdatabase", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDbRoleSettingName},
{Name: "setrole", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDbRoleSettingName},
{Name: "setconfig", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgDbRoleSettingName}, // TODO: collation C
}
// pgDbRoleSettingRowIter is the sql.RowIter for the pg_db_role_setting table.
type pgDbRoleSettingRowIter struct {
}
var _ sql.RowIter = (*pgDbRoleSettingRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgDbRoleSettingRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgDbRoleSettingRowIter) Close(ctx *sql.Context) error {
return nil
}
+81
View File
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgDefaultAclName is a constant to the pg_default_acl name.
const PgDefaultAclName = "pg_default_acl"
// InitPgDefaultAcl handles registration of the pg_default_acl handler.
func InitPgDefaultAcl() {
tables.AddHandler(PgCatalogName, PgDefaultAclName, PgDefaultAclHandler{})
}
// PgDefaultAclHandler is the handler for the pg_default_acl table.
type PgDefaultAclHandler struct{}
var _ tables.Handler = PgDefaultAclHandler{}
// Name implements the interface tables.Handler.
func (p PgDefaultAclHandler) Name() string {
return PgDefaultAclName
}
// RowIter implements the interface tables.Handler.
func (p PgDefaultAclHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_default_acl row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgDefaultAclHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgDefaultAclSchema,
PkOrdinals: nil,
}
}
// pgDefaultAclSchema is the schema for pg_default_acl.
var pgDefaultAclSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDefaultAclName},
{Name: "defaclrole", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDefaultAclName},
{Name: "defaclnamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDefaultAclName},
{Name: "defaclobjtype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgDefaultAclName},
{Name: "defaclacl", Type: pgtypes.TextArray, Default: nil, Nullable: false, Source: PgDefaultAclName}, // TODO: aclitem[] type
}
// pgDefaultAclRowIter is the sql.RowIter for the pg_default_acl table.
type pgDefaultAclRowIter struct {
}
var _ sql.RowIter = (*pgDefaultAclRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgDefaultAclRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgDefaultAclRowIter) Close(ctx *sql.Context) error {
return nil
}
+83
View File
@@ -0,0 +1,83 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgDependName is a constant to the pg_depend name.
const PgDependName = "pg_depend"
// InitPgDepend handles registration of the pg_depend handler.
func InitPgDepend() {
tables.AddHandler(PgCatalogName, PgDependName, PgDependHandler{})
}
// PgDependHandler is the handler for the pg_depend table.
type PgDependHandler struct{}
var _ tables.Handler = PgDependHandler{}
// Name implements the interface tables.Handler.
func (p PgDependHandler) Name() string {
return PgDependName
}
// RowIter implements the interface tables.Handler.
func (p PgDependHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_depend row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgDependHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgDependSchema,
PkOrdinals: nil,
}
}
// pgDependSchema is the schema for pg_depend.
var pgDependSchema = sql.Schema{
{Name: "classid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDependName},
{Name: "objid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDependName},
{Name: "objsubid", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgDependName},
{Name: "refclassid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDependName},
{Name: "refobjid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDependName},
{Name: "refobjsubid", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgDependName},
{Name: "deptype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgDependName},
}
// pgDependRowIter is the sql.RowIter for the pg_depend table.
type pgDependRowIter struct {
}
var _ sql.RowIter = (*pgDependRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgDependRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgDependRowIter) Close(ctx *sql.Context) error {
return nil
}
+80
View File
@@ -0,0 +1,80 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgDescriptionName is a constant to the pg_description name.
const PgDescriptionName = "pg_description"
// InitPgDescription handles registration of the pg_description handler.
func InitPgDescription() {
tables.AddHandler(PgCatalogName, PgDescriptionName, PgDescriptionHandler{})
}
// PgDescriptionHandler is the handler for the pg_description table.
type PgDescriptionHandler struct{}
var _ tables.Handler = PgDescriptionHandler{}
// Name implements the interface tables.Handler.
func (p PgDescriptionHandler) Name() string {
return PgDescriptionName
}
// RowIter implements the interface tables.Handler.
func (p PgDescriptionHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_description row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgDescriptionHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgDescriptionSchema,
PkOrdinals: nil,
}
}
// pgDescriptionSchema is the schema for pg_description.
var pgDescriptionSchema = sql.Schema{
{Name: "objoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDescriptionName},
{Name: "classoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgDescriptionName},
{Name: "objsubid", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgDescriptionName},
{Name: "description", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgDescriptionName}, // TODO: collation C
}
// pgDescriptionRowIter is the sql.RowIter for the pg_description table.
type pgDescriptionRowIter struct {
}
var _ sql.RowIter = (*pgDescriptionRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgDescriptionRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgDescriptionRowIter) Close(ctx *sql.Context) error {
return nil
}
+82
View File
@@ -0,0 +1,82 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgEnumName is a constant to the pg_enum name.
const PgEnumName = "pg_enum"
// InitPgEnum handles registration of the pg_enum handler.
func InitPgEnum() {
tables.AddHandler(PgCatalogName, PgEnumName, PgEnumHandler{})
}
// PgEnumHandler is the handler for the pg_enum table.
type PgEnumHandler struct{}
var _ tables.Handler = PgEnumHandler{}
// Name implements the interface tables.Handler.
func (p PgEnumHandler) Name() string {
return PgEnumName
}
// RowIter implements the interface tables.Handler.
func (p PgEnumHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_enum row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgEnumHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgEnumSchema,
PkOrdinals: nil,
}
}
// pgEnumSchema is the schema for pg_enum.
var pgEnumSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgEnumName},
{Name: "enumtypid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgEnumName},
{Name: "enumsortorder", Type: pgtypes.Float32, Default: nil, Nullable: false, Source: PgEnumName},
{Name: "enumlabel", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgEnumName},
}
// TODO: add unique constraint "pg_enum_typid_label_index"
// pgEnumRowIter is the sql.RowIter for the pg_enum table.
type pgEnumRowIter struct {
}
var _ sql.RowIter = (*pgEnumRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgEnumRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgEnumRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,83 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgEventTriggerName is a constant to the pg_event_trigger name.
const PgEventTriggerName = "pg_event_trigger"
// InitPgEventTrigger handles registration of the pg_event_trigger handler.
func InitPgEventTrigger() {
tables.AddHandler(PgCatalogName, PgEventTriggerName, PgEventTriggerHandler{})
}
// PgEventTriggerHandler is the handler for the pg_event_trigger table.
type PgEventTriggerHandler struct{}
var _ tables.Handler = PgEventTriggerHandler{}
// Name implements the interface tables.Handler.
func (p PgEventTriggerHandler) Name() string {
return PgEventTriggerName
}
// RowIter implements the interface tables.Handler.
func (p PgEventTriggerHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_event_trigger row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgEventTriggerHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: PgEventTriggerSchema,
PkOrdinals: nil,
}
}
// PgEventTriggerSchema is the schema for pg_event_trigger.
var PgEventTriggerSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgEventTriggerName},
{Name: "evtname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgEventTriggerName},
{Name: "evtevent", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgEventTriggerName},
{Name: "evtowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgEventTriggerName},
{Name: "evtfoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgEventTriggerName},
{Name: "evtenabled", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgEventTriggerName},
{Name: "evttags", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgEventTriggerName}, // TODO: collation C
}
// pgEventTriggerRowIter is the sql.RowIter for the pg_event_trigger table.
type pgEventTriggerRowIter struct {
}
var _ sql.RowIter = (*pgEventTriggerRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgEventTriggerRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgEventTriggerRowIter) Close(ctx *sql.Context) error {
return nil
}
+84
View File
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgExtensionName is a constant to the pg_extension name.
const PgExtensionName = "pg_extension"
// InitPgExtension handles registration of the pg_extension handler.
func InitPgExtension() {
tables.AddHandler(PgCatalogName, PgExtensionName, PgExtensionHandler{})
}
// PgExtensionHandler is the handler for the pg_extension table.
type PgExtensionHandler struct{}
var _ tables.Handler = PgExtensionHandler{}
// Name implements the interface tables.Handler.
func (p PgExtensionHandler) Name() string {
return PgExtensionName
}
// RowIter implements the interface tables.Handler.
func (p PgExtensionHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_extension row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgExtensionHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgExtensionSchema,
PkOrdinals: nil,
}
}
// pgExtensionSchema is the schema for pg_extension.
var pgExtensionSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgExtensionName},
{Name: "extname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgExtensionName},
{Name: "extowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgExtensionName},
{Name: "extnamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgExtensionName},
{Name: "extrelocatable", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgExtensionName},
{Name: "extversion", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgExtensionName}, // TODO: collation C
{Name: "extconfig", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgExtensionName},
{Name: "extcondition", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgExtensionName}, // TODO: collation C
}
// pgExtensionRowIter is the sql.RowIter for the pg_extension table.
type pgExtensionRowIter struct {
}
var _ sql.RowIter = (*pgExtensionRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgExtensionRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgExtensionRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,83 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgFileSettingsName is a constant to the pg_file_settings name.
const PgFileSettingsName = "pg_file_settings"
// InitPgFileSettings handles registration of the pg_file_settings handler.
func InitPgFileSettings() {
tables.AddHandler(PgCatalogName, PgFileSettingsName, PgFileSettingsHandler{})
}
// PgFileSettingsHandler is the handler for the pg_file_settings table.
type PgFileSettingsHandler struct{}
var _ tables.Handler = PgFileSettingsHandler{}
// Name implements the interface tables.Handler.
func (p PgFileSettingsHandler) Name() string {
return PgFileSettingsName
}
// RowIter implements the interface tables.Handler.
func (p PgFileSettingsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_file_settings row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgFileSettingsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgFileSettingsSchema,
PkOrdinals: nil,
}
}
// pgFileSettingsSchema is the schema for pg_file_settings.
var pgFileSettingsSchema = sql.Schema{
{Name: "sourcefile", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgFileSettingsName},
{Name: "sourceline", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgFileSettingsName},
{Name: "seqno", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgFileSettingsName},
{Name: "name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgFileSettingsName},
{Name: "setting", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgFileSettingsName},
{Name: "applied", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgFileSettingsName},
{Name: "error", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgFileSettingsName},
}
// pgFileSettingsRowIter is the sql.RowIter for the pg_file_settings table.
type pgFileSettingsRowIter struct {
}
var _ sql.RowIter = (*pgFileSettingsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgFileSettingsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgFileSettingsRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,83 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgForeignDataWrapperName is a constant to the pg_foreign_data_wrapper name.
const PgForeignDataWrapperName = "pg_foreign_data_wrapper"
// InitPgForeignDataWrapper handles registration of the pg_foreign_data_wrapper handler.
func InitPgForeignDataWrapper() {
tables.AddHandler(PgCatalogName, PgForeignDataWrapperName, PgForeignDataWrapperHandler{})
}
// PgForeignDataWrapperHandler is the handler for the pg_foreign_data_wrapper table.
type PgForeignDataWrapperHandler struct{}
var _ tables.Handler = PgForeignDataWrapperHandler{}
// Name implements the interface tables.Handler.
func (p PgForeignDataWrapperHandler) Name() string {
return PgForeignDataWrapperName
}
// RowIter implements the interface tables.Handler.
func (p PgForeignDataWrapperHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_foreign_data_wrapper row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgForeignDataWrapperHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgForeignDataWrapperSchema,
PkOrdinals: nil,
}
}
// pgForeignDataWrapperSchema is the schema for pg_foreign_data_wrapper.
var pgForeignDataWrapperSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignDataWrapperName},
{Name: "fdwname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgForeignDataWrapperName},
{Name: "fdwowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignDataWrapperName},
{Name: "fdwhandler", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignDataWrapperName},
{Name: "fdwvalidator", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignDataWrapperName},
{Name: "fdwacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgForeignDataWrapperName}, // TODO: aclitem[] type
{Name: "fdwoptions", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgForeignDataWrapperName}, // TODO: collation C
}
// pgForeignDataWrapperRowIter is the sql.RowIter for the pg_foreign_data_wrapper table.
type pgForeignDataWrapperRowIter struct {
}
var _ sql.RowIter = (*pgForeignDataWrapperRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgForeignDataWrapperRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgForeignDataWrapperRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgForeignServerName is a constant to the pg_foreign_server name.
const PgForeignServerName = "pg_foreign_server"
// InitPgForeignServer handles registration of the pg_foreign_server handler.
func InitPgForeignServer() {
tables.AddHandler(PgCatalogName, PgForeignServerName, PgForeignServerHandler{})
}
// PgForeignServerHandler is the handler for the pg_foreign_server table.
type PgForeignServerHandler struct{}
var _ tables.Handler = PgForeignServerHandler{}
// Name implements the interface tables.Handler.
func (p PgForeignServerHandler) Name() string {
return PgForeignServerName
}
// RowIter implements the interface tables.Handler.
func (p PgForeignServerHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_foreign_server row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgForeignServerHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgForeignServerSchema,
PkOrdinals: nil,
}
}
// pgForeignServerSchema is the schema for pg_foreign_server.
var pgForeignServerSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignServerName},
{Name: "srvname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgForeignServerName},
{Name: "srvowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignServerName},
{Name: "srvfdw", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignServerName},
{Name: "srvtype", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgForeignServerName}, // TODO: collation C
{Name: "srvversion", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgForeignServerName}, // TODO: collation C
{Name: "srvacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgForeignServerName}, // TODO: aclitem[] type
{Name: "srvoptions", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgForeignServerName}, // TODO: collation C
}
// pgForeignServerRowIter is the sql.RowIter for the pg_foreign_server table.
type pgForeignServerRowIter struct {
}
var _ sql.RowIter = (*pgForeignServerRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgForeignServerRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgForeignServerRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,79 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgForeignTableName is a constant to the pg_foreign_table name.
const PgForeignTableName = "pg_foreign_table"
// InitPgForeignTable handles registration of the pg_foreign_table handler.
func InitPgForeignTable() {
tables.AddHandler(PgCatalogName, PgForeignTableName, PgForeignTableHandler{})
}
// PgForeignTableHandler is the handler for the pg_foreign_table table.
type PgForeignTableHandler struct{}
var _ tables.Handler = PgForeignTableHandler{}
// Name implements the interface tables.Handler.
func (p PgForeignTableHandler) Name() string {
return PgForeignTableName
}
// RowIter implements the interface tables.Handler.
func (p PgForeignTableHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_foreign_table row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgForeignTableHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgForeignTableSchema,
PkOrdinals: nil,
}
}
// pgForeignTableSchema is the schema for pg_foreign_table.
var pgForeignTableSchema = sql.Schema{
{Name: "ftrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignTableName},
{Name: "ftserver", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgForeignTableName},
{Name: "ftoptions", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgForeignTableName}, // TODO: collation C
}
// pgForeignTableRowIter is the sql.RowIter for the pg_foreign_table table.
type pgForeignTableRowIter struct {
}
var _ sql.RowIter = (*pgForeignTableRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgForeignTableRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgForeignTableRowIter) Close(ctx *sql.Context) error {
return nil
}
+79
View File
@@ -0,0 +1,79 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgGroupName is a constant to the pg_group name.
const PgGroupName = "pg_group"
// InitPgGroup handles registration of the pg_group handler.
func InitPgGroup() {
tables.AddHandler(PgCatalogName, PgGroupName, PgGroupHandler{})
}
// PgGroupHandler is the handler for the pg_group table.
type PgGroupHandler struct{}
var _ tables.Handler = PgGroupHandler{}
// Name implements the interface tables.Handler.
func (p PgGroupHandler) Name() string {
return PgGroupName
}
// RowIter implements the interface tables.Handler.
func (p PgGroupHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_group row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgGroupHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgGroupSchema,
PkOrdinals: nil,
}
}
// pgGroupSchema is the schema for pg_group.
var pgGroupSchema = sql.Schema{
{Name: "groname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgGroupName},
{Name: "grosysid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgGroupName},
{Name: "grolist", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgGroupName},
}
// pgGroupRowIter is the sql.RowIter for the pg_group table.
type pgGroupRowIter struct {
}
var _ sql.RowIter = (*pgGroupRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgGroupRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgGroupRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgHbaFileRulesName is a constant to the pg_hba_file_rules name.
const PgHbaFileRulesName = "pg_hba_file_rules"
// InitPgHbaFileRules handles registration of the pg_hba_file_rules handler.
func InitPgHbaFileRules() {
tables.AddHandler(PgCatalogName, PgHbaFileRulesName, PgHbaFileRulesHandler{})
}
// PgHbaFileRulesHandler is the handler for the pg_hba_file_rules table.
type PgHbaFileRulesHandler struct{}
var _ tables.Handler = PgHbaFileRulesHandler{}
// Name implements the interface tables.Handler.
func (p PgHbaFileRulesHandler) Name() string {
return PgHbaFileRulesName
}
// RowIter implements the interface tables.Handler.
func (p PgHbaFileRulesHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_hba_file_rules row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgHbaFileRulesHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgHbaFileRulesSchema,
PkOrdinals: nil,
}
}
// pgHbaFileRulesSchema is the schema for pg_hba_file_rules.
var pgHbaFileRulesSchema = sql.Schema{
{Name: "line_number", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "type", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "database", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "user_name", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "address", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "netmask", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "auth_method", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "options", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
{Name: "error", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgHbaFileRulesName},
}
// pgHbaFileRulesRowIter is the sql.RowIter for the pg_hba_file_rules table.
type pgHbaFileRulesRowIter struct {
}
var _ sql.RowIter = (*pgHbaFileRulesRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgHbaFileRulesRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgHbaFileRulesRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgIdentFileMappingsName is a constant to the pg_ident_file_mappings name.
const PgIdentFileMappingsName = "pg_ident_file_mappings"
// InitPgIdentFileMappings handles registration of the pg_ident_file_mappings handler.
func InitPgIdentFileMappings() {
tables.AddHandler(PgCatalogName, PgIdentFileMappingsName, PgIdentFileMappingsHandler{})
}
// PgIdentFileMappingsHandler is the handler for the pg_ident_file_mappings table.
type PgIdentFileMappingsHandler struct{}
var _ tables.Handler = PgIdentFileMappingsHandler{}
// Name implements the interface tables.Handler.
func (p PgIdentFileMappingsHandler) Name() string {
return PgIdentFileMappingsName
}
// RowIter implements the interface tables.Handler.
func (p PgIdentFileMappingsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_ident_file_mappings row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgIdentFileMappingsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgIdentFileMappingsSchema,
PkOrdinals: nil,
}
}
// pgIdentFileMappingsSchema is the schema for pg_ident_file_mappings.
var pgIdentFileMappingsSchema = sql.Schema{
{Name: "line_number", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgIdentFileMappingsName},
{Name: "map_name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgIdentFileMappingsName},
{Name: "sys_name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgIdentFileMappingsName},
{Name: "pg_username", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgIdentFileMappingsName},
{Name: "error", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgIdentFileMappingsName},
}
// pgIdentFileMappingsRowIter is the sql.RowIter for the pg_ident_file_mappings table.
type pgIdentFileMappingsRowIter struct {
}
var _ sql.RowIter = (*pgIdentFileMappingsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgIdentFileMappingsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgIdentFileMappingsRowIter) Close(ctx *sql.Context) error {
return nil
}
+348
View File
@@ -0,0 +1,348 @@
// 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 pgcatalog
import (
"io"
"strings"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgIndexName is a constant to the pg_index name.
const PgIndexName = "pg_index"
// InitPgIndex handles registration of the pg_index handler.
func InitPgIndex() {
tables.AddHandler(PgCatalogName, PgIndexName, PgIndexHandler{})
}
// PgIndexHandler is the handler for the pg_index table.
type PgIndexHandler struct{}
var _ tables.Handler = PgIndexHandler{}
var _ tables.IndexedTableHandler = PgIndexHandler{}
// Name implements the interface tables.Handler.
func (p PgIndexHandler) Name() string {
return PgIndexName
}
// RowIter implements the interface tables.Handler.
func (p PgIndexHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// Use cached data from this session if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.pgIndexes == nil {
err = cachePgIndexes(ctx, pgCatalogCache)
if err != nil {
return nil, err
}
}
if indexIdxPart, ok := partition.(inMemIndexPartition); ok {
return &inMemIndexScanIter[*pgIndex]{
lookup: indexIdxPart.lookup,
rangeConverter: p,
btreeAccess: pgCatalogCache.pgIndexes,
rowConverter: pgIndexToRow,
}, nil
}
return &pgIndexTableScanIter{
indexCache: pgCatalogCache.pgIndexes,
idx: 0,
}, nil
}
// PkSchema implements the interface tables.Handler.
func (p PgIndexHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgIndexSchema,
PkOrdinals: nil,
}
}
// Indexes implements tables.IndexedTableHandler.
func (p PgIndexHandler) Indexes() ([]sql.Index, error) {
return []sql.Index{
pgCatalogInMemIndex{
name: "pg_index_indexrelid_index",
tblName: "pg_index",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{{Expression: "pg_index.indexrelid", Type: pgtypes.Oid}},
},
pgCatalogInMemIndex{
name: "pg_index_indrelid_index",
tblName: "pg_index",
dbName: "pg_catalog",
uniq: false,
columnExprs: []sql.ColumnExpressionType{{Expression: "pg_index.indrelid", Type: pgtypes.Oid}},
},
}, nil
}
// LookupPartitions implements tables.IndexedTableHandler.
func (p PgIndexHandler) LookupPartitions(context *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error) {
return &inMemIndexPartIter{
part: inMemIndexPartition{
idxName: lookup.Index.(pgCatalogInMemIndex).name,
lookup: lookup,
},
}, nil
}
// getIndexScanRange implements the interface RangeConverter.
func (p PgIndexHandler) getIndexScanRange(rng sql.Range, index sql.Index) (*pgIndex, bool, *pgIndex, bool) {
var gte, lt *pgIndex
var hasLowerBound, hasUpperBound bool
switch index.(pgCatalogInMemIndex).name {
case "pg_index_indexrelid_index":
msrng := rng.(sql.MySQLRange)
oidRng := msrng[0]
if oidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(oidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
gte = &pgIndex{
indexOidNative: idToOid(lowerRangeCutKey),
}
hasLowerBound = true
}
}
if oidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(oidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
lt = &pgIndex{
indexOidNative: idToOid(upperRangeCutKey) + 1,
}
hasUpperBound = true
}
}
case "pg_index_indrelid_index":
msrng := rng.(sql.MySQLRange)
oidRng := msrng[0]
if oidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(oidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
gte = &pgIndex{
tableOidNative: idToOid(lowerRangeCutKey),
}
hasLowerBound = true
}
}
if oidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(oidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
lt = &pgIndex{
tableOidNative: idToOid(upperRangeCutKey) + 1,
}
hasUpperBound = true
}
}
default:
panic("unknown index name: " + index.(pgCatalogInMemIndex).name)
}
return gte, hasLowerBound, lt, hasUpperBound
}
// pgIndexSchema is the schema for pg_index.
var pgIndexSchema = sql.Schema{
{Name: "indexrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indnatts", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indnkeyatts", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indisunique", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indnullsnotdistinct", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indisprimary", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indisexclusion", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indimmediate", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indisclustered", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indisvalid", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indcheckxmin", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indisready", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indislive", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indisreplident", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indkey", Type: pgtypes.Int16vector, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indcollation", Type: pgtypes.Oidvector, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indclass", Type: pgtypes.Oidvector, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indoption", Type: pgtypes.Int16vector, Default: nil, Nullable: false, Source: PgIndexName},
{Name: "indexprs", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgIndexName}, // TODO: type pg_node_tree, collation C
{Name: "indpred", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgIndexName}, // TODO: type pg_node_tree, collation C
}
func extractColName(expr string) string {
// TODO: this breaks for column names that contain a `.`, but this is a problem that happens
// throughout index analysis in the engine
lastDot := strings.LastIndex(expr, ".")
return expr[lastDot+1:]
}
// pgIndex represents a row in the pg_index table.
// We store oids in their native format as well so that we can do range scans on them.
type pgIndex struct {
index sql.Index
schemaName string
indexOid id.Id
indexOidNative uint32
tableOid id.Id
tableOidNative uint32
indnatts int16
indisunique bool
indisprimary bool
indkey []any
}
// lessIndexOid is a sort function for pgIndex based on indexrelid.
func lessIndexOid(a, b *pgIndex) bool {
return a.indexOidNative < b.indexOidNative
}
// lessIndrelid is a sort function for pgIndex based on indrelid.
func lessIndrelid(a, b []*pgIndex) bool {
return a[0].tableOidNative < b[0].tableOidNative
}
// pgIndexTableScanIter is the sql.RowIter for the pg_index table.
type pgIndexTableScanIter struct {
indexCache *pgIndexCache
idx int
}
var _ sql.RowIter = (*pgIndexTableScanIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgIndexTableScanIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.indexCache.indexes) {
return nil, io.EOF
}
iter.idx++
index := iter.indexCache.indexes[iter.idx-1]
return pgIndexToRow(index), nil
}
// Close implements the interface sql.RowIter.
func (iter *pgIndexTableScanIter) Close(ctx *sql.Context) error {
return nil
}
// pgIndexToRow converts a pgIndex to a sql.Row.
func pgIndexToRow(index *pgIndex) sql.Row {
return sql.Row{
index.indexOid, // indexrelid
index.tableOid, // indrelid
index.indnatts, // indnatts
int16(0), // indnkeyatts
index.index.IsUnique(), // indisunique
false, // indnullsnotdistinct
index.indisprimary, // indisprimary
false, // indisexclusion
false, // indimmediate
false, // indisclustered
true, // indisvalid
false, // indcheckxmin
true, // indisready
true, // indislive
false, // indisreplident
index.indkey, // indkey
[]any{}, // indcollation
[]any{}, // indclass
[]any{int16(0)}, // indoption
nil, // indexprs
indexPred(index.index), // indpred
}
}
// indexPred returns the predicate expression string for partial indexes, or nil for full indexes.
func indexPred(idx sql.Index) interface{} {
if pi, ok := idx.(sql.PartialIndex); ok && pi.Predicate() != "" {
return pi.Predicate()
}
return nil
}
// cachePgIndexes caches the pg_index data for the current database in the session.
func cachePgIndexes(ctx *sql.Context, pgCatalogCache *pgCatalogCache) error {
var indexes []*pgIndex
indexOidIdx := NewUniqueInMemIndexStorage[*pgIndex](lessIndexOid)
indrelidIdx := NewNonUniqueInMemIndexStorage[*pgIndex](lessIndrelid)
tableSchemas := make(map[id.Id]sql.Schema)
tableNames := make(map[id.Id]string)
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Index: func(ctx *sql.Context, schema functions.ItemSchema, table functions.ItemTable, index functions.ItemIndex) (cont bool, err error) {
if tableSchemas[table.OID.AsId()] == nil {
tableSchemas[table.OID.AsId()] = table.Item.Schema(ctx)
}
if tableNames[table.OID.AsId()] == "" {
tableNames[table.OID.AsId()] = table.Item.Name()
}
s := tableSchemas[table.OID.AsId()]
indKey := make([]any, len(index.Item.Expressions()))
for i, expr := range index.Item.Expressions() {
colName := extractColName(expr)
indKey[i] = int16(s.IndexOfColName(colName)) + 1
}
pgIdx := &pgIndex{
index: index.Item,
schemaName: schema.Item.SchemaName(),
indexOid: index.OID.AsId(),
indexOidNative: id.Cache().ToOID(index.OID.AsId()),
tableOid: table.OID.AsId(),
tableOidNative: id.Cache().ToOID(table.OID.AsId()),
indkey: indKey,
indnatts: int16(len(index.Item.Expressions())),
indisunique: index.Item.IsUnique(),
indisprimary: strings.ToLower(index.Item.ID()) == "primary",
}
indexOidIdx.Add(pgIdx)
indrelidIdx.Add(pgIdx)
indexes = append(indexes, pgIdx)
return true, nil
},
})
if err != nil {
return err
}
pgCatalogCache.pgIndexes = &pgIndexCache{
indexes: indexes,
tableNames: tableNames,
indexOidIdx: indexOidIdx,
indrelidIdx: indrelidIdx,
}
return nil
}
+140
View File
@@ -0,0 +1,140 @@
// 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 pgcatalog
import (
"fmt"
"io"
"strings"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgIndexesName is a constant to the pg_indexes name.
const PgIndexesName = "pg_indexes"
// InitPgIndexes handles registration of the pg_indexes handler.
func InitPgIndexes() {
tables.AddHandler(PgCatalogName, PgIndexesName, PgIndexesHandler{})
}
// PgIndexesHandler is the handler for the pg_indexes table.
type PgIndexesHandler struct{}
var _ tables.Handler = PgIndexesHandler{}
// Name implements the interface tables.Handler.
func (p PgIndexesHandler) Name() string {
return PgIndexesName
}
// RowIter implements the interface tables.Handler.
func (p PgIndexesHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// Use cached data from this process if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.pgIndexes == nil {
err = cachePgIndexes(ctx, pgCatalogCache)
if err != nil {
return nil, err
}
}
return &pgIndexesRowIter{
indexes: pgCatalogCache.pgIndexes,
idx: 0,
}, nil
}
// PkSchema implements the interface tables.Handler.
func (p PgIndexesHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgIndexesSchema,
PkOrdinals: nil,
}
}
// pgIndexesSchema is the schema for pg_indexes.
var pgIndexesSchema = sql.Schema{
{Name: "schemaname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgIndexesName},
{Name: "tablename", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgIndexesName},
{Name: "indexname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgIndexesName},
{Name: "tablespace", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgIndexesName},
{Name: "indexdef", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgIndexesName},
}
// pgIndexesRowIter is the sql.RowIter for the pg_indexes table.
type pgIndexesRowIter struct {
indexes *pgIndexCache
idx int
}
var _ sql.RowIter = (*pgIndexesRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgIndexesRowIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.indexes.indexes) {
return nil, io.EOF
}
iter.idx++
index := iter.indexes.indexes[iter.idx-1]
// TODO: Fill in the rest of the pg_indexes columns
return sql.Row{
index.schemaName, // schemaname
iter.indexes.tableNames[index.tableOid], // tablename
formatIndexName(index.index), // indexname
"", // tablespace
getIndexDef(index.index, index.schemaName), // indexdef
}, nil
}
// formatIndexName returns the definition of the index.
func getIndexDef(index sql.Index, schema string) string {
name := formatIndexName(index)
using := strings.ToLower(index.IndexType())
unique := ""
if index.IsUnique() {
unique = " UNIQUE"
}
cols := make([]string, len(index.Expressions()))
for i, expr := range index.Expressions() {
split := strings.Split(expr, ".")
if len(split) > 1 {
cols[i] = split[1]
} else {
cols[i] = expr
}
}
colsStr := strings.Join(cols, ", ")
def := fmt.Sprintf("CREATE%s INDEX %s ON %s.%s USING %s (%s)", unique, name, schema, index.Table(), using, colsStr)
if pi, ok := index.(sql.PartialIndex); ok && pi.Predicate() != "" {
def += " WHERE (" + pi.Predicate() + ")"
}
return def
}
// Close implements the interface sql.RowIter.
func (iter *pgIndexesRowIter) Close(ctx *sql.Context) error {
return nil
}
+80
View File
@@ -0,0 +1,80 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgInheritsName is a constant to the pg_inherits name.
const PgInheritsName = "pg_inherits"
// InitPgInherits handles registration of the pg_inherits handler.
func InitPgInherits() {
tables.AddHandler(PgCatalogName, PgInheritsName, PgInheritsHandler{})
}
// PgInheritsHandler is the handler for the pg_inherits table.
type PgInheritsHandler struct{}
var _ tables.Handler = PgInheritsHandler{}
// Name implements the interface tables.Handler.
func (p PgInheritsHandler) Name() string {
return PgInheritsName
}
// RowIter implements the interface tables.Handler.
func (p PgInheritsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_inherits row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgInheritsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgInheritsSchema,
PkOrdinals: nil,
}
}
// pgInheritsSchema is the schema for pg_inherits.
var pgInheritsSchema = sql.Schema{
{Name: "inhrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgInheritsName},
{Name: "inhparent", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgInheritsName},
{Name: "inhseqno", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgInheritsName},
{Name: "inhdetachpending", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgInheritsName},
}
// pgInheritsRowIter is the sql.RowIter for the pg_inherits table.
type pgInheritsRowIter struct {
}
var _ sql.RowIter = (*pgInheritsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgInheritsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgInheritsRowIter) Close(ctx *sql.Context) error {
return nil
}
+81
View File
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgInitPrivsName is a constant to the pg_init_privs name.
const PgInitPrivsName = "pg_init_privs"
// InitPgInitPrivs handles registration of the pg_init_privs handler.
func InitPgInitPrivs() {
tables.AddHandler(PgCatalogName, PgInitPrivsName, PgInitPrivsHandler{})
}
// PgInitPrivsHandler is the handler for the pg_init_privs table.
type PgInitPrivsHandler struct{}
var _ tables.Handler = PgInitPrivsHandler{}
// Name implements the interface tables.Handler.
func (p PgInitPrivsHandler) Name() string {
return PgInitPrivsName
}
// RowIter implements the interface tables.Handler.
func (p PgInitPrivsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_init_privs row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgInitPrivsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgInitPrivsSchema,
PkOrdinals: nil,
}
}
// pgInitPrivsSchema is the schema for pg_init_privs.
var pgInitPrivsSchema = sql.Schema{
{Name: "objoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgInitPrivsName},
{Name: "classoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgInitPrivsName},
{Name: "objsubid", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgInitPrivsName},
{Name: "privtype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgInitPrivsName},
{Name: "initprivs", Type: pgtypes.TextArray, Default: nil, Nullable: false, Source: PgInitPrivsName}, // TODO: aclitem[] type
}
// pgInitPrivsRowIter is the sql.RowIter for the pg_init_privs table.
type pgInitPrivsRowIter struct {
}
var _ sql.RowIter = (*pgInitPrivsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgInitPrivsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgInitPrivsRowIter) Close(ctx *sql.Context) error {
return nil
}
+85
View File
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgLanguageName is a constant to the pg_language name.
const PgLanguageName = "pg_language"
// InitPgLanguage handles registration of the pg_language handler.
func InitPgLanguage() {
tables.AddHandler(PgCatalogName, PgLanguageName, PgLanguageHandler{})
}
// PgLanguageHandler is the handler for the pg_language table.
type PgLanguageHandler struct{}
var _ tables.Handler = PgLanguageHandler{}
// Name implements the interface tables.Handler.
func (p PgLanguageHandler) Name() string {
return PgLanguageName
}
// RowIter implements the interface tables.Handler.
func (p PgLanguageHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_language row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgLanguageHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgLanguageSchema,
PkOrdinals: nil,
}
}
// pgLanguageSchema is the schema for pg_language.
var pgLanguageSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "lanname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "lanowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "lanispl", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "lanpltrusted", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "lanplcallfoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "laninline", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "lanvalidator", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLanguageName},
{Name: "lanacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgLanguageName}, // TODO: aclitem[] type
}
// pgLanguageRowIter is the sql.RowIter for the pg_language table.
type pgLanguageRowIter struct {
}
var _ sql.RowIter = (*pgLanguageRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgLanguageRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgLanguageRowIter) Close(ctx *sql.Context) error {
return nil
}
+79
View File
@@ -0,0 +1,79 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgLargeobjectName is a constant to the pg_largeobject name.
const PgLargeobjectName = "pg_largeobject"
// InitPgLargeobject handles registration of the pg_largeobject handler.
func InitPgLargeobject() {
tables.AddHandler(PgCatalogName, PgLargeobjectName, PgLargeobjectHandler{})
}
// PgLargeobjectHandler is the handler for the pg_largeobject table.
type PgLargeobjectHandler struct{}
var _ tables.Handler = PgLargeobjectHandler{}
// Name implements the interface tables.Handler.
func (p PgLargeobjectHandler) Name() string {
return PgLargeobjectName
}
// RowIter implements the interface tables.Handler.
func (p PgLargeobjectHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_largeobject row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgLargeobjectHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgLargeobjectSchema,
PkOrdinals: nil,
}
}
// pgLargeobjectSchema is the schema for pg_largeobject.
var pgLargeobjectSchema = sql.Schema{
{Name: "loid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLargeobjectName},
{Name: "pageno", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgLargeobjectName},
{Name: "data", Type: pgtypes.Bytea, Default: nil, Nullable: false, Source: PgLargeobjectName},
}
// pgLargeobjectRowIter is the sql.RowIter for the pg_largeobject table.
type pgLargeobjectRowIter struct {
}
var _ sql.RowIter = (*pgLargeobjectRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgLargeobjectRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgLargeobjectRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,79 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgLargeobjectMetadataName is a constant to the pg_largeobject_metadata name.
const PgLargeobjectMetadataName = "pg_largeobject_metadata"
// InitPgLargeobjectMetadata handles registration of the pg_largeobject_metadata handler.
func InitPgLargeobjectMetadata() {
tables.AddHandler(PgCatalogName, PgLargeobjectMetadataName, PgLargeobjectMetadataHandler{})
}
// PgLargeobjectMetadataHandler is the handler for the pg_largeobject_metadata table.
type PgLargeobjectMetadataHandler struct{}
var _ tables.Handler = PgLargeobjectMetadataHandler{}
// Name implements the interface tables.Handler.
func (p PgLargeobjectMetadataHandler) Name() string {
return PgLargeobjectMetadataName
}
// RowIter implements the interface tables.Handler.
func (p PgLargeobjectMetadataHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_largeobject_metadata row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgLargeobjectMetadataHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgLargeobjectMetadataSchema,
PkOrdinals: nil,
}
}
// pgLargeobjectMetadataSchema is the schema for pg_largeobject_metadata.
var pgLargeobjectMetadataSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLargeobjectMetadataName},
{Name: "lomowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgLargeobjectMetadataName},
{Name: "lomacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgLargeobjectMetadataName}, // TODO: aclitem[] type
}
// pgLargeobjectMetadataRowIter is the sql.RowIter for the pg_largeobject_metadata table.
type pgLargeobjectMetadataRowIter struct {
}
var _ sql.RowIter = (*pgLargeobjectMetadataRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgLargeobjectMetadataRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgLargeobjectMetadataRowIter) Close(ctx *sql.Context) error {
return nil
}
+92
View File
@@ -0,0 +1,92 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgLocksName is a constant to the pg_locks name.
const PgLocksName = "pg_locks"
// InitPgLocks handles registration of the pg_locks handler.
func InitPgLocks() {
tables.AddHandler(PgCatalogName, PgLocksName, PgLocksHandler{})
}
// PgLocksHandler is the handler for the pg_locks table.
type PgLocksHandler struct{}
var _ tables.Handler = PgLocksHandler{}
// Name implements the interface tables.Handler.
func (p PgLocksHandler) Name() string {
return PgLocksName
}
// RowIter implements the interface tables.Handler.
func (p PgLocksHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_locks row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgLocksHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgLocksSchema,
PkOrdinals: nil,
}
}
// pgLocksSchema is the schema for pg_locks.
var pgLocksSchema = sql.Schema{
{Name: "locktype", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "database", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "relation", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "page", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "tuple", Type: pgtypes.Int16, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "virtualxid", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "transactionid", Type: pgtypes.Xid, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "classid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "objid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "objsubid", Type: pgtypes.Int16, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "virtualtransaction", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "pid", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "mode", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "granted", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "fastpath", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgLocksName},
{Name: "waitstart", Type: pgtypes.TimestampTZ, Default: nil, Nullable: true, Source: PgLocksName},
}
// pgLocksRowIter is the sql.RowIter for the pg_locks table.
type pgLocksRowIter struct {
}
var _ sql.RowIter = (*pgLocksRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgLocksRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgLocksRowIter) Close(ctx *sql.Context) error {
return nil
}
+83
View File
@@ -0,0 +1,83 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgMatviewsName is a constant to the pg_matviews name.
const PgMatviewsName = "pg_matviews"
// InitPgMatviews handles registration of the pg_matviews handler.
func InitPgMatviews() {
tables.AddHandler(PgCatalogName, PgMatviewsName, PgMatviewsHandler{})
}
// PgMatviewsHandler is the handler for the pg_matviews table.
type PgMatviewsHandler struct{}
var _ tables.Handler = PgMatviewsHandler{}
// Name implements the interface tables.Handler.
func (p PgMatviewsHandler) Name() string {
return PgMatviewsName
}
// RowIter implements the interface tables.Handler.
func (p PgMatviewsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_matviews row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgMatviewsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgMatviewsSchema,
PkOrdinals: nil,
}
}
// pgMatviewsSchema is the schema for pg_matviews.
var pgMatviewsSchema = sql.Schema{
{Name: "schemaname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgMatviewsName},
{Name: "matviewname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgMatviewsName},
{Name: "matviewowner", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgMatviewsName},
{Name: "tablespace", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgMatviewsName},
{Name: "hasindexes", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgMatviewsName},
{Name: "ispopulated", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgMatviewsName},
{Name: "definition", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgMatviewsName},
}
// pgMatviewsRowIter is the sql.RowIter for the pg_matviews table.
type pgMatviewsRowIter struct {
}
var _ sql.RowIter = (*pgMatviewsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgMatviewsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgMatviewsRowIter) Close(ctx *sql.Context) error {
return nil
}
+266
View File
@@ -0,0 +1,266 @@
// 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 pgcatalog
import (
"fmt"
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgNamespaceName is a constant to the pg_namespace name.
const PgNamespaceName = "pg_namespace"
// InitPgNamespace handles registration of the pg_namespace handler.
func InitPgNamespace() {
tables.AddHandler(PgCatalogName, PgNamespaceName, PgNamespaceHandler{})
}
// PgNamespaceHandler is the handler for the pg_namespace table.
type PgNamespaceHandler struct{}
var _ tables.Handler = PgNamespaceHandler{}
var _ tables.IndexedTableHandler = PgNamespaceHandler{}
// Name implements the interface tables.Handler.
func (p PgNamespaceHandler) Name() string {
return PgNamespaceName
}
// RowIter implements the interface tables.Handler.
func (p PgNamespaceHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// Use cached data from this session if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.pgNamespaces == nil {
err = cachePgNamespaces(ctx, pgCatalogCache)
if err != nil {
return nil, err
}
}
if namespaceIdxPart, ok := partition.(inMemIndexPartition); ok {
return &inMemIndexScanIter[*pgNamespace]{
lookup: namespaceIdxPart.lookup,
rangeConverter: p,
btreeAccess: pgCatalogCache.pgNamespaces,
rowConverter: pgNamespaceToRow,
}, nil
}
return &pgNamespaceTableScanIter{
namespaceCache: pgCatalogCache.pgNamespaces,
idx: 0,
}, nil
}
// cachePgNamespaces caches the pg_namespace data for the current database in the session.
func cachePgNamespaces(ctx *sql.Context, pgCatalogCache *pgCatalogCache) error {
var namespaces []*pgNamespace
oidIdx := NewUniqueInMemIndexStorage[*pgNamespace](lessNamespaceOid)
nameIdx := NewUniqueInMemIndexStorage[*pgNamespace](lessNamespaceName)
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Schema: func(ctx *sql.Context, schema functions.ItemSchema) (cont bool, err error) {
namespace := &pgNamespace{
oid: schema.OID.AsId(),
oidNative: id.Cache().ToOID(schema.OID.AsId()),
name: schema.Item.SchemaName(),
}
oidIdx.Add(namespace)
nameIdx.Add(namespace)
namespaces = append(namespaces, namespace)
return true, nil
},
})
if err != nil {
return err
}
pgCatalogCache.pgNamespaces = &pgNamespaceCache{
namespaces: namespaces,
oidIdx: oidIdx,
nameIdx: nameIdx,
}
return nil
}
// getIndexScanRange implements the interface RangeConverter.
func (p PgNamespaceHandler) getIndexScanRange(rng sql.Range, index sql.Index) (*pgNamespace, bool, *pgNamespace, bool) {
var gte, lt *pgNamespace
var hasLowerBound, hasUpperBound bool
switch index.(pgCatalogInMemIndex).name {
case "pg_namespace_oid_index":
msrng := rng.(sql.MySQLRange)
oidRng := msrng[0]
if oidRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(oidRng.LowerBound)
if lb != nil {
lowerRangeCutKey := lb.(id.Id)
gte = &pgNamespace{
oidNative: idToOid(lowerRangeCutKey),
}
hasLowerBound = true
}
}
if oidRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(oidRng.UpperBound)
if ub != nil {
upperRangeCutKey := ub.(id.Id)
lt = &pgNamespace{
oidNative: idToOid(upperRangeCutKey) + 1,
}
hasUpperBound = true
}
}
case "pg_namespace_nspname_index":
msrng := rng.(sql.MySQLRange)
nameRng := msrng[0]
var nameLower, nameUpper string
if nameRng.HasLowerBound() {
lb := sql.GetMySQLRangeCutKey(nameRng.LowerBound)
if lb != nil {
nameLower = lb.(string)
hasLowerBound = true
}
}
if nameRng.HasUpperBound() {
ub := sql.GetMySQLRangeCutKey(nameRng.UpperBound)
if ub != nil {
nameUpper = ub.(string)
nameUpper = fmt.Sprintf("%s%o", nameUpper, rune(0))
hasUpperBound = true
}
}
if hasLowerBound {
gte = &pgNamespace{
name: nameLower,
}
}
if hasUpperBound {
lt = &pgNamespace{
name: nameUpper,
}
}
default:
panic("unknown index name: " + index.(pgCatalogInMemIndex).name)
}
return gte, hasLowerBound, lt, hasUpperBound
}
// PkSchema implements the interface tables.Handler.
func (p PgNamespaceHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgNamespaceSchema,
PkOrdinals: nil,
}
}
// Indexes implements tables.IndexedTableHandler.
func (p PgNamespaceHandler) Indexes() ([]sql.Index, error) {
return []sql.Index{
pgCatalogInMemIndex{
name: "pg_namespace_oid_index",
tblName: "pg_namespace",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{{Expression: "pg_namespace.oid", Type: pgtypes.Oid}},
},
pgCatalogInMemIndex{
name: "pg_namespace_nspname_index",
tblName: "pg_namespace",
dbName: "pg_catalog",
uniq: true,
columnExprs: []sql.ColumnExpressionType{{Expression: "pg_namespace.nspname", Type: pgtypes.Name}},
},
}, nil
}
// LookupPartitions implements tables.IndexedTableHandler.
func (p PgNamespaceHandler) LookupPartitions(context *sql.Context, lookup sql.IndexLookup) (sql.PartitionIter, error) {
return &inMemIndexPartIter{
part: inMemIndexPartition{
idxName: lookup.Index.(pgCatalogInMemIndex).name,
lookup: lookup,
},
}, nil
}
// pgNamespaceSchema is the schema for pg_namespace.
var pgNamespaceSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgNamespaceName},
{Name: "nspname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgNamespaceName},
{Name: "nspowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgNamespaceName},
{Name: "nspacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgNamespaceName}, // TODO: type aclitem[]
}
// lessNamespaceOid is a sort function for pgNamespace based on oid.
func lessNamespaceOid(a, b *pgNamespace) bool {
return a.oidNative < b.oidNative
}
// lessNamespaceName is a sort function for pgNamespace based on name.
func lessNamespaceName(a, b *pgNamespace) bool {
return a.name < b.name
}
// pgNamespaceTableScanIter is the sql.RowIter for the pg_namespace table.
type pgNamespaceTableScanIter struct {
namespaceCache *pgNamespaceCache
idx int
}
var _ sql.RowIter = (*pgNamespaceTableScanIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgNamespaceTableScanIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.namespaceCache.namespaces) {
return nil, io.EOF
}
iter.idx++
namespace := iter.namespaceCache.namespaces[iter.idx-1]
return pgNamespaceToRow(namespace), nil
}
// Close implements the interface sql.RowIter.
func (iter *pgNamespaceTableScanIter) Close(ctx *sql.Context) error {
return nil
}
func pgNamespaceToRow(namespace *pgNamespace) sql.Row {
// TODO: columns are incomplete
return sql.Row{
namespace.oid, // oid
namespace.name, // nspname
id.Null, // nspowner
nil, // nspacl
}
}
+85
View File
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgOpclassName is a constant to the pg_opclass name.
const PgOpclassName = "pg_opclass"
// InitPgOpclass handles registration of the pg_opclass handler.
func InitPgOpclass() {
tables.AddHandler(PgCatalogName, PgOpclassName, PgOpclassHandler{})
}
// PgOpclassHandler is the handler for the pg_opclass table.
type PgOpclassHandler struct{}
var _ tables.Handler = PgOpclassHandler{}
// Name implements the interface tables.Handler.
func (p PgOpclassHandler) Name() string {
return PgOpclassName
}
// RowIter implements the interface tables.Handler.
func (p PgOpclassHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_opclass row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgOpclassHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgOpclassSchema,
PkOrdinals: nil,
}
}
// pgOpclassSchema is the schema for pg_opclass.
var pgOpclassSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opcmethod", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opcname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opcnamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opcowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opcfamily", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opcintype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opcdefault", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgOpclassName},
{Name: "opckeytype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpclassName},
}
// pgOpclassRowIter is the sql.RowIter for the pg_opclass table.
type pgOpclassRowIter struct {
}
var _ sql.RowIter = (*pgOpclassRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgOpclassRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgOpclassRowIter) Close(ctx *sql.Context) error {
return nil
}
+91
View File
@@ -0,0 +1,91 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgOperatorName is a constant to the pg_operator name.
const PgOperatorName = "pg_operator"
// InitPgOperator handles registration of the pg_operator handler.
func InitPgOperator() {
tables.AddHandler(PgCatalogName, PgOperatorName, PgOperatorHandler{})
}
// PgOperatorHandler is the handler for the pg_operator table.
type PgOperatorHandler struct{}
var _ tables.Handler = PgOperatorHandler{}
// Name implements the interface tables.Handler.
func (p PgOperatorHandler) Name() string {
return PgOperatorName
}
// RowIter implements the interface tables.Handler.
func (p PgOperatorHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_operator row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgOperatorHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgOperatorSchema,
PkOrdinals: nil,
}
}
// pgOperatorSchema is the schema for pg_operator.
var pgOperatorSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprnamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprkind", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprcanmerge", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprcanhash", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprleft", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprright", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprresult", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprcom", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprnegate", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprcode", Type: pgtypes.Regproc, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprrest", Type: pgtypes.Regproc, Default: nil, Nullable: false, Source: PgOperatorName},
{Name: "oprjoin", Type: pgtypes.Regproc, Default: nil, Nullable: false, Source: PgOperatorName},
}
// pgOperatorRowIter is the sql.RowIter for the pg_operator table.
type pgOperatorRowIter struct {
}
var _ sql.RowIter = (*pgOperatorRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgOperatorRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgOperatorRowIter) Close(ctx *sql.Context) error {
return nil
}
+81
View File
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgOpfamilyName is a constant to the pg_opfamily name.
const PgOpfamilyName = "pg_opfamily"
// InitPgOpfamily handles registration of the pg_opfamily handler.
func InitPgOpfamily() {
tables.AddHandler(PgCatalogName, PgOpfamilyName, PgOpfamilyHandler{})
}
// PgOpfamilyHandler is the handler for the pg_opfamily table.
type PgOpfamilyHandler struct{}
var _ tables.Handler = PgOpfamilyHandler{}
// Name implements the interface tables.Handler.
func (p PgOpfamilyHandler) Name() string {
return PgOpfamilyName
}
// RowIter implements the interface tables.Handler.
func (p PgOpfamilyHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_opfamily row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgOpfamilyHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgOpfamilySchema,
PkOrdinals: nil,
}
}
// pgOpfamilySchema is the schema for pg_opfamily.
var pgOpfamilySchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpfamilyName},
{Name: "opfmethod", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpfamilyName},
{Name: "opfname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgOpfamilyName},
{Name: "opfnamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpfamilyName},
{Name: "opfowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgOpfamilyName},
}
// pgOpfamilyRowIter is the sql.RowIter for the pg_opfamily table.
type pgOpfamilyRowIter struct {
}
var _ sql.RowIter = (*pgOpfamilyRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgOpfamilyRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgOpfamilyRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,79 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgParameterAclName is a constant to the pg_parameter_acl name.
const PgParameterAclName = "pg_parameter_acl"
// InitPgParameterAcl handles registration of the pg_parameter_acl handler.
func InitPgParameterAcl() {
tables.AddHandler(PgCatalogName, PgParameterAclName, PgParameterAclHandler{})
}
// PgParameterAclHandler is the handler for the pg_parameter_acl table.
type PgParameterAclHandler struct{}
var _ tables.Handler = PgParameterAclHandler{}
// Name implements the interface tables.Handler.
func (p PgParameterAclHandler) Name() string {
return PgParameterAclName
}
// RowIter implements the interface tables.Handler.
func (p PgParameterAclHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_parameter_acl row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgParameterAclHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgParameterAclSchema,
PkOrdinals: nil,
}
}
// pgParameterAclSchema is the schema for pg_parameter_acl.
var pgParameterAclSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgParameterAclName},
{Name: "parname", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgParameterAclName}, // TODO: collation C
{Name: "paracl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgParameterAclName}, // TODO: aclitem[] type
}
// pgParameterAclRowIter is the sql.RowIter for the pg_parameter_acl table.
type pgParameterAclRowIter struct {
}
var _ sql.RowIter = (*pgParameterAclRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgParameterAclRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgParameterAclRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPartitionedTableName is a constant to the pg_partitioned_table name.
const PgPartitionedTableName = "pg_partitioned_table"
// InitPgPartitionedTable handles registration of the pg_partitioned_table handler.
func InitPgPartitionedTable() {
tables.AddHandler(PgCatalogName, PgPartitionedTableName, PgPartitionedTableHandler{})
}
// PgPartitionedTableHandler is the handler for the pg_partitioned_table table.
type PgPartitionedTableHandler struct{}
var _ tables.Handler = PgPartitionedTableHandler{}
// Name implements the interface tables.Handler.
func (p PgPartitionedTableHandler) Name() string {
return PgPartitionedTableName
}
// RowIter implements the interface tables.Handler.
func (p PgPartitionedTableHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_partitioned_table row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPartitionedTableHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPartitionedTableSchema,
PkOrdinals: nil,
}
}
// pgPartitionedTableSchema is the schema for pg_partitioned_table.
var pgPartitionedTableSchema = sql.Schema{
{Name: "partrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPartitionedTableName},
{Name: "partstrat", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgPartitionedTableName},
{Name: "partnatts", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgPartitionedTableName},
{Name: "partdefid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPartitionedTableName},
{Name: "partattrs", Type: pgtypes.Int16Array, Default: nil, Nullable: false, Source: PgPartitionedTableName}, // TODO: int2vector type
{Name: "partclass", Type: pgtypes.OidArray, Default: nil, Nullable: false, Source: PgPartitionedTableName}, // TODO: oidvector type
{Name: "partcollation", Type: pgtypes.OidArray, Default: nil, Nullable: false, Source: PgPartitionedTableName}, // TODO: oidvector type
{Name: "partexprs", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPartitionedTableName}, // TODO: pg_node_tree type, collation C
}
// pgPartitionedTableRowIter is the sql.RowIter for the pg_partitioned_table table.
type pgPartitionedTableRowIter struct {
}
var _ sql.RowIter = (*pgPartitionedTableRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPartitionedTableRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPartitionedTableRowIter) Close(ctx *sql.Context) error {
return nil
}
+84
View File
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPoliciesName is a constant to the pg_policies name.
const PgPoliciesName = "pg_policies"
// InitPgPolicies handles registration of the pg_policies handler.
func InitPgPolicies() {
tables.AddHandler(PgCatalogName, PgPoliciesName, PgPoliciesHandler{})
}
// PgPoliciesHandler is the handler for the pg_policies table.
type PgPoliciesHandler struct{}
var _ tables.Handler = PgPoliciesHandler{}
// Name implements the interface tables.Handler.
func (p PgPoliciesHandler) Name() string {
return PgPoliciesName
}
// RowIter implements the interface tables.Handler.
func (p PgPoliciesHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_policies row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPoliciesHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPoliciesSchema,
PkOrdinals: nil,
}
}
// pgPoliciesSchema is the schema for pg_policies.
var pgPoliciesSchema = sql.Schema{
{Name: "schemaname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPoliciesName},
{Name: "tablename", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPoliciesName},
{Name: "policyname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPoliciesName},
{Name: "permissive", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPoliciesName},
{Name: "roles", Type: pgtypes.NameArray, Default: nil, Nullable: true, Source: PgPoliciesName},
{Name: "cmd", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPoliciesName},
{Name: "qual", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPoliciesName}, // TODO: collation C
{Name: "with_check", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPoliciesName}, // TODO: collation C
}
// pgPoliciesRowIter is the sql.RowIter for the pg_policies table.
type pgPoliciesRowIter struct {
}
var _ sql.RowIter = (*pgPoliciesRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPoliciesRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPoliciesRowIter) Close(ctx *sql.Context) error {
return nil
}
+84
View File
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPolicyName is a constant to the pg_policy name.
const PgPolicyName = "pg_policy"
// InitPgPolicy handles registration of the pg_policy handler.
func InitPgPolicy() {
tables.AddHandler(PgCatalogName, PgPolicyName, PgPolicyHandler{})
}
// PgPolicyHandler is the handler for the pg_policy table.
type PgPolicyHandler struct{}
var _ tables.Handler = PgPolicyHandler{}
// Name implements the interface tables.Handler.
func (p PgPolicyHandler) Name() string {
return PgPolicyName
}
// RowIter implements the interface tables.Handler.
func (p PgPolicyHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_policy row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPolicyHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPolicySchema,
PkOrdinals: nil,
}
}
// pgPolicySchema is the schema for pg_policy.
var pgPolicySchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPolicyName},
{Name: "polname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgPolicyName},
{Name: "polrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPolicyName},
{Name: "polcmd", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgPolicyName},
{Name: "polpermissive", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgPolicyName},
{Name: "polroles", Type: pgtypes.OidArray, Default: nil, Nullable: false, Source: PgPolicyName},
{Name: "polqual", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPolicyName}, // TODO: pg_node_tree type, collation C
{Name: "polwithcheck", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPolicyName}, // TODO: pg_node_tree type, collation C
}
// pgPolicyRowIter is the sql.RowIter for the pg_policy table.
type pgPolicyRowIter struct {
}
var _ sql.RowIter = (*pgPolicyRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPolicyRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPolicyRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPreparedStatementsName is a constant to the pg_prepared_statements name.
const PgPreparedStatementsName = "pg_prepared_statements"
// InitPgPreparedStatements handles registration of the pg_prepared_statements handler.
func InitPgPreparedStatements() {
tables.AddHandler(PgCatalogName, PgPreparedStatementsName, PgPreparedStatementsHandler{})
}
// PgPreparedStatementsHandler is the handler for the pg_prepared_statements table.
type PgPreparedStatementsHandler struct{}
var _ tables.Handler = PgPreparedStatementsHandler{}
// Name implements the interface tables.Handler.
func (p PgPreparedStatementsHandler) Name() string {
return PgPreparedStatementsName
}
// RowIter implements the interface tables.Handler.
func (p PgPreparedStatementsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_prepared_statements row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPreparedStatementsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPreparedStatementsSchema,
PkOrdinals: nil,
}
}
// pgPreparedStatementsSchema is the schema for pg_prepared_statements.
var pgPreparedStatementsSchema = sql.Schema{
{Name: "name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPreparedStatementsName},
{Name: "statement", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPreparedStatementsName},
{Name: "prepare_time", Type: pgtypes.TimestampTZ, Default: nil, Nullable: true, Source: PgPreparedStatementsName},
{Name: "parameter_types", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPreparedStatementsName}, // TODO: regtype[] type
{Name: "result_types", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPreparedStatementsName}, // TODO: regtype[] type
{Name: "from_sql", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgPreparedStatementsName},
{Name: "generic_plans", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgPreparedStatementsName},
{Name: "custom_plans", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgPreparedStatementsName},
}
// pgPreparedStatementsRowIter is the sql.RowIter for the pg_prepared_statements table.
type pgPreparedStatementsRowIter struct {
}
var _ sql.RowIter = (*pgPreparedStatementsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPreparedStatementsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPreparedStatementsRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPreparedXactsName is a constant to the pg_prepared_xacts name.
const PgPreparedXactsName = "pg_prepared_xacts"
// InitPgPreparedXacts handles registration of the pg_prepared_xacts handler.
func InitPgPreparedXacts() {
tables.AddHandler(PgCatalogName, PgPreparedXactsName, PgPreparedXactsHandler{})
}
// PgPreparedXactsHandler is the handler for the pg_prepared_xacts table.
type PgPreparedXactsHandler struct{}
var _ tables.Handler = PgPreparedXactsHandler{}
// Name implements the interface tables.Handler.
func (p PgPreparedXactsHandler) Name() string {
return PgPreparedXactsName
}
// RowIter implements the interface tables.Handler.
func (p PgPreparedXactsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_prepared_xacts row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPreparedXactsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPreparedXactsSchema,
PkOrdinals: nil,
}
}
// pgPreparedXactsSchema is the schema for pg_prepared_xacts.
var pgPreparedXactsSchema = sql.Schema{
{Name: "transaction", Type: pgtypes.Xid, Default: nil, Nullable: true, Source: PgPreparedXactsName},
{Name: "gid", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPreparedXactsName},
{Name: "prepared", Type: pgtypes.TimestampTZ, Default: nil, Nullable: true, Source: PgPreparedXactsName},
{Name: "owner", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPreparedXactsName},
{Name: "database", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPreparedXactsName},
}
// pgPreparedXactsRowIter is the sql.RowIter for the pg_prepared_xacts table.
type pgPreparedXactsRowIter struct {
}
var _ sql.RowIter = (*pgPreparedXactsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPreparedXactsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPreparedXactsRowIter) Close(ctx *sql.Context) error {
return nil
}
+106
View File
@@ -0,0 +1,106 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgProcName is a constant to the pg_proc name.
const PgProcName = "pg_proc"
// InitPgProc handles registration of the pg_proc handler.
func InitPgProc() {
tables.AddHandler(PgCatalogName, PgProcName, PgProcHandler{})
}
// PgProcHandler is the handler for the pg_proc table.
type PgProcHandler struct{}
var _ tables.Handler = PgProcHandler{}
// Name implements the interface tables.Handler.
func (p PgProcHandler) Name() string {
return PgProcName
}
// RowIter implements the interface tables.Handler.
func (p PgProcHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_proc row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgProcHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgProcSchema,
PkOrdinals: nil,
}
}
// pgProcSchema is the schema for pg_proc.
var pgProcSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgProcName},
{Name: "pronamespace", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgProcName},
{Name: "prolang", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgProcName},
{Name: "procost", Type: pgtypes.Float32, Default: nil, Nullable: false, Source: PgProcName},
{Name: "prorows", Type: pgtypes.Float32, Default: nil, Nullable: false, Source: PgProcName},
{Name: "provariadic", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgProcName},
{Name: "prosupport", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgProcName}, // TODO: type regproc
{Name: "prokind", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgProcName},
{Name: "prosecdef", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proleakproof", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proisstrict", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proretset", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgProcName},
{Name: "provolatile", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proparallel", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgProcName},
{Name: "pronargs", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgProcName},
{Name: "pronargdefaults", Type: pgtypes.Int16, Default: nil, Nullable: false, Source: PgProcName},
{Name: "prorettype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proargtypes", Type: pgtypes.Oidvector, Default: nil, Nullable: false, Source: PgProcName},
{Name: "proallargtypes", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgProcName},
{Name: "proargmodes", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgProcName}, // TODO: type char[]
{Name: "proargnames", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgProcName}, // TODO: collation C
{Name: "proargdefaults", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgProcName}, // TODO: type pg_node_tree, collation C
{Name: "protrftypes", Type: pgtypes.OidArray, Default: nil, Nullable: true, Source: PgProcName},
{Name: "prosrc", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgProcName}, // TODO: collation C
{Name: "probin", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgProcName},
{Name: "prosqlbody", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgProcName}, // TODO: type pg_node_tree, collation C
{Name: "proconfig", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgProcName}, // TODO: collation C
{Name: "proacl", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgProcName}, // TODO: type aclitem[]
}
// pgProcRowIter is the sql.RowIter for the pg_proc table.
type pgProcRowIter struct {
}
var _ sql.RowIter = (*pgProcRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgProcRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgProcRowIter) Close(ctx *sql.Context) error {
return nil
}
+85
View File
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPublicationName is a constant to the pg_publication name.
const PgPublicationName = "pg_publication"
// InitPgPublication handles registration of the pg_publication handler.
func InitPgPublication() {
tables.AddHandler(PgCatalogName, PgPublicationName, PgPublicationHandler{})
}
// PgPublicationHandler is the handler for the pg_publication table.
type PgPublicationHandler struct{}
var _ tables.Handler = PgPublicationHandler{}
// Name implements the interface tables.Handler.
func (p PgPublicationHandler) Name() string {
return PgPublicationName
}
// RowIter implements the interface tables.Handler.
func (p PgPublicationHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_publication row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPublicationHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPublicationSchema,
PkOrdinals: nil,
}
}
// pgPublicationSchema is the schema for pg_publication.
var pgPublicationSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "pubname", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "pubowner", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "puballtables", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "pubinsert", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "pubupdate", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "pubdelete", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "pubtruncate", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgPublicationName},
{Name: "pubviaroot", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgPublicationName},
}
// pgPublicationRowIter is the sql.RowIter for the pg_publication table.
type pgPublicationRowIter struct {
}
var _ sql.RowIter = (*pgPublicationRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPublicationRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPublicationRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,79 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPublicationNamespaceName is a constant to the pg_publication_namespace name.
const PgPublicationNamespaceName = "pg_publication_namespace"
// InitPgPublicationNamespace handles registration of the pg_publication_namespace handler.
func InitPgPublicationNamespace() {
tables.AddHandler(PgCatalogName, PgPublicationNamespaceName, PgPublicationNamespaceHandler{})
}
// PgPublicationNamespaceHandler is the handler for the pg_publication_namespace table.
type PgPublicationNamespaceHandler struct{}
var _ tables.Handler = PgPublicationNamespaceHandler{}
// Name implements the interface tables.Handler.
func (p PgPublicationNamespaceHandler) Name() string {
return PgPublicationNamespaceName
}
// RowIter implements the interface tables.Handler.
func (p PgPublicationNamespaceHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_publication_namespace row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPublicationNamespaceHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPublicationNamespaceSchema,
PkOrdinals: nil,
}
}
// pgPublicationNamespaceSchema is the schema for pg_publication_namespace.
var pgPublicationNamespaceSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationNamespaceName},
{Name: "pnpubid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationNamespaceName},
{Name: "pnnspid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationNamespaceName},
}
// pgPublicationNamespaceRowIter is the sql.RowIter for the pg_publication_namespace table.
type pgPublicationNamespaceRowIter struct {
}
var _ sql.RowIter = (*pgPublicationNamespaceRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPublicationNamespaceRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPublicationNamespaceRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPublicationRelName is a constant to the pg_publication_rel name.
const PgPublicationRelName = "pg_publication_rel"
// InitPgPublicationRel handles registration of the pg_publication_rel handler.
func InitPgPublicationRel() {
tables.AddHandler(PgCatalogName, PgPublicationRelName, PgPublicationRelHandler{})
}
// PgPublicationRelHandler is the handler for the pg_publication_rel table.
type PgPublicationRelHandler struct{}
var _ tables.Handler = PgPublicationRelHandler{}
// Name implements the interface tables.Handler.
func (p PgPublicationRelHandler) Name() string {
return PgPublicationRelName
}
// RowIter implements the interface tables.Handler.
func (p PgPublicationRelHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_publication_rel row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPublicationRelHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPublicationRelSchema,
PkOrdinals: nil,
}
}
// pgPublicationRelSchema is the schema for pg_publication_rel.
var pgPublicationRelSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationRelName},
{Name: "prpubid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationRelName},
{Name: "prrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgPublicationRelName},
{Name: "prqual", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPublicationRelName}, // TODO: pg_node_tree type, collation C
{Name: "prattrs", Type: pgtypes.Int16Array, Default: nil, Nullable: true, Source: PgPublicationRelName}, // TODO: int2vector type
}
// pgPublicationRelRowIter is the sql.RowIter for the pg_publication_rel table.
type pgPublicationRelRowIter struct {
}
var _ sql.RowIter = (*pgPublicationRelRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPublicationRelRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPublicationRelRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgPublicationTablesName is a constant to the pg_publication_tables name.
const PgPublicationTablesName = "pg_publication_tables"
// InitPgPublicationTables handles registration of the pg_publication_tables handler.
func InitPgPublicationTables() {
tables.AddHandler(PgCatalogName, PgPublicationTablesName, PgPublicationTablesHandler{})
}
// PgPublicationTablesHandler is the handler for the pg_publication_tables table.
type PgPublicationTablesHandler struct{}
var _ tables.Handler = PgPublicationTablesHandler{}
// Name implements the interface tables.Handler.
func (p PgPublicationTablesHandler) Name() string {
return PgPublicationTablesName
}
// RowIter implements the interface tables.Handler.
func (p PgPublicationTablesHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_publication_tables row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgPublicationTablesHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgPublicationTablesSchema,
PkOrdinals: nil,
}
}
// pgPublicationTablesSchema is the schema for pg_publication_tables.
var pgPublicationTablesSchema = sql.Schema{
{Name: "pubname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPublicationTablesName},
{Name: "schemaname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPublicationTablesName},
{Name: "tablename", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgPublicationTablesName},
{Name: "attnames", Type: pgtypes.NameArray, Default: nil, Nullable: true, Source: PgPublicationTablesName},
{Name: "rowfilter", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgPublicationTablesName},
}
// pgPublicationTablesRowIter is the sql.RowIter for the pg_publication_tables table.
type pgPublicationTablesRowIter struct {
}
var _ sql.RowIter = (*pgPublicationTablesRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgPublicationTablesRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgPublicationTablesRowIter) Close(ctx *sql.Context) error {
return nil
}
+83
View File
@@ -0,0 +1,83 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgRangeName is a constant to the pg_range name.
const PgRangeName = "pg_range"
// InitPgRange handles registration of the pg_range handler.
func InitPgRange() {
tables.AddHandler(PgCatalogName, PgRangeName, PgRangeHandler{})
}
// PgRangeHandler is the handler for the pg_range table.
type PgRangeHandler struct{}
var _ tables.Handler = PgRangeHandler{}
// Name implements the interface tables.Handler.
func (p PgRangeHandler) Name() string {
return PgRangeName
}
// RowIter implements the interface tables.Handler.
func (p PgRangeHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_range row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgRangeHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgRangeSchema,
PkOrdinals: nil,
}
}
// pgRangeSchema is the schema for pg_range.
var pgRangeSchema = sql.Schema{
{Name: "rngtypid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgRangeName},
{Name: "rngsubtype", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgRangeName},
{Name: "rngmultitypid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgRangeName},
{Name: "rngcollation", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgRangeName},
{Name: "rngsubopc", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgRangeName},
{Name: "rngcanonical", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgRangeName}, // TODO: regproc type
{Name: "rngsubdiff", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgRangeName}, // TODO: regproc type
}
// pgRangeRowIter is the sql.RowIter for the pg_range table.
type pgRangeRowIter struct {
}
var _ sql.RowIter = (*pgRangeRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgRangeRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgRangeRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,78 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgReplicationOriginName is a constant to the pg_replication_origin name.
const PgReplicationOriginName = "pg_replication_origin"
// InitPgReplicationOrigin handles registration of the pg_replication_origin handler.
func InitPgReplicationOrigin() {
tables.AddHandler(PgCatalogName, PgReplicationOriginName, PgReplicationOriginHandler{})
}
// PgReplicationOriginHandler is the handler for the pg_replication_origin table.
type PgReplicationOriginHandler struct{}
var _ tables.Handler = PgReplicationOriginHandler{}
// Name implements the interface tables.Handler.
func (p PgReplicationOriginHandler) Name() string {
return PgReplicationOriginName
}
// RowIter implements the interface tables.Handler.
func (p PgReplicationOriginHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_replication_origin row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgReplicationOriginHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgReplicationOriginSchema,
PkOrdinals: nil,
}
}
// pgReplicationOriginSchema is the schema for pg_replication_origin.
var pgReplicationOriginSchema = sql.Schema{
{Name: "roident", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgReplicationOriginName},
{Name: "roname", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgReplicationOriginName}, // TODO: collation C
}
// pgReplicationOriginRowIter is the sql.RowIter for the pg_replication_origin table.
type pgReplicationOriginRowIter struct {
}
var _ sql.RowIter = (*pgReplicationOriginRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgReplicationOriginRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgReplicationOriginRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,80 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgReplicationOriginStatusName is a constant to the pg_replication_origin_status name.
const PgReplicationOriginStatusName = "pg_replication_origin_status"
// InitPgReplicationOriginStatus handles registration of the pg_replication_origin_status handler.
func InitPgReplicationOriginStatus() {
tables.AddHandler(PgCatalogName, PgReplicationOriginStatusName, PgReplicationOriginStatusHandler{})
}
// PgReplicationOriginStatusHandler is the handler for the pg_replication_origin_status table.
type PgReplicationOriginStatusHandler struct{}
var _ tables.Handler = PgReplicationOriginStatusHandler{}
// Name implements the interface tables.Handler.
func (p PgReplicationOriginStatusHandler) Name() string {
return PgReplicationOriginStatusName
}
// RowIter implements the interface tables.Handler.
func (p PgReplicationOriginStatusHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_replication_origin_status row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgReplicationOriginStatusHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgReplicationOriginStatusSchema,
PkOrdinals: nil,
}
}
// pgReplicationOriginStatusSchema is the schema for pg_replication_origin_status.
var pgReplicationOriginStatusSchema = sql.Schema{
{Name: "local_id", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgReplicationOriginStatusName},
{Name: "external_id", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgReplicationOriginStatusName},
{Name: "remote_lsn", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgReplicationOriginStatusName}, // TODO: pg_lsn type
{Name: "local_lsn", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgReplicationOriginStatusName}, // TODO: pg_lsn type
}
// pgReplicationOriginStatusRowIter is the sql.RowIter for the pg_replication_origin_status table.
type pgReplicationOriginStatusRowIter struct {
}
var _ sql.RowIter = (*pgReplicationOriginStatusRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgReplicationOriginStatusRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgReplicationOriginStatusRowIter) Close(ctx *sql.Context) error {
return nil
}
@@ -0,0 +1,91 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgReplicationSlotsName is a constant to the pg_replication_slots name.
const PgReplicationSlotsName = "pg_replication_slots"
// InitPgReplicationSlots handles registration of the pg_replication_slots handler.
func InitPgReplicationSlots() {
tables.AddHandler(PgCatalogName, PgReplicationSlotsName, PgReplicationSlotsHandler{})
}
// PgReplicationSlotsHandler is the handler for the pg_replication_slots table.
type PgReplicationSlotsHandler struct{}
var _ tables.Handler = PgReplicationSlotsHandler{}
// Name implements the interface tables.Handler.
func (p PgReplicationSlotsHandler) Name() string {
return PgReplicationSlotsName
}
// RowIter implements the interface tables.Handler.
func (p PgReplicationSlotsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_replication_slots row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgReplicationSlotsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgReplicationSlotsSchema,
PkOrdinals: nil,
}
}
// pgReplicationSlotsSchema is the schema for pg_replication_slots.
var pgReplicationSlotsSchema = sql.Schema{
{Name: "slot_name", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "plugin", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "slot_type", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "datoid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "database", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "temporary", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "active", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "active_pid", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "xmin", Type: pgtypes.Xid, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "catalog_xmin", Type: pgtypes.Xid, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "restart_lsn", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgReplicationSlotsName}, // TODO: pg_lsn type
{Name: "confirmed_flush_lsn", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgReplicationSlotsName}, // TODO: pg_lsn type
{Name: "wal_status", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "safe_wal_size", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
{Name: "two_phase", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgReplicationSlotsName},
}
// pgReplicationSlotsRowIter is the sql.RowIter for the pg_replication_slots table.
type pgReplicationSlotsRowIter struct {
}
var _ sql.RowIter = (*pgReplicationSlotsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgReplicationSlotsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgReplicationSlotsRowIter) Close(ctx *sql.Context) error {
return nil
}
+84
View File
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgRewriteName is a constant to the pg_rewrite name.
const PgRewriteName = "pg_rewrite"
// InitPgRewrite handles registration of the pg_rewrite handler.
func InitPgRewrite() {
tables.AddHandler(PgCatalogName, PgRewriteName, PgRewriteHandler{})
}
// PgRewriteHandler is the handler for the pg_rewrite table.
type PgRewriteHandler struct{}
var _ tables.Handler = PgRewriteHandler{}
// Name implements the interface tables.Handler.
func (p PgRewriteHandler) Name() string {
return PgRewriteName
}
// RowIter implements the interface tables.Handler.
func (p PgRewriteHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_rewrite row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgRewriteHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgRewriteSchema,
PkOrdinals: nil,
}
}
// pgRewriteSchema is the schema for pg_rewrite.
var pgRewriteSchema = sql.Schema{
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgRewriteName},
{Name: "rulename", Type: pgtypes.Name, Default: nil, Nullable: false, Source: PgRewriteName},
{Name: "ev_class", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgRewriteName},
{Name: "ev_type", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgRewriteName},
{Name: "ev_enabled", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgRewriteName},
{Name: "is_instead", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgRewriteName},
{Name: "ev_qual", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgRewriteName}, // TODO: pg_node_tree type, collation C
{Name: "ev_action", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgRewriteName}, // TODO: pg_node_tree type, collation C
}
// pgRewriteRowIter is the sql.RowIter for the pg_rewrite table.
type pgRewriteRowIter struct {
}
var _ sql.RowIter = (*pgRewriteRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgRewriteRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgRewriteRowIter) Close(ctx *sql.Context) error {
return nil
}
+89
View File
@@ -0,0 +1,89 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgRolesName is a constant to the pg_roles name.
const PgRolesName = "pg_roles"
// InitPgRoles handles registration of the pg_roles handler.
func InitPgRoles() {
tables.AddHandler(PgCatalogName, PgRolesName, PgRolesHandler{})
}
// PgRolesHandler is the handler for the pg_roles table.
type PgRolesHandler struct{}
var _ tables.Handler = PgRolesHandler{}
// Name implements the interface tables.Handler.
func (p PgRolesHandler) Name() string {
return PgRolesName
}
// RowIter implements the interface tables.Handler.
func (p PgRolesHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_roles row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgRolesHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgRolesSchema,
PkOrdinals: nil,
}
}
// pgRolesSchema is the schema for pg_roles.
var pgRolesSchema = sql.Schema{
{Name: "rolname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolsuper", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolinherit", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolcreaterole", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolcreatedb", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolcanlogin", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolreplication", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolconnlimit", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolpassword", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolvaliduntil", Type: pgtypes.TimestampTZ, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolbypassrls", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgRolesName},
{Name: "rolconfig", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgRolesName}, // TODO: collation C
{Name: "oid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgRolesName},
}
// pgRolesRowIter is the sql.RowIter for the pg_roles table.
type pgRolesRowIter struct {
}
var _ sql.RowIter = (*pgRolesRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgRolesRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgRolesRowIter) Close(ctx *sql.Context) error {
return nil
}
+80
View File
@@ -0,0 +1,80 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgRulesName is a constant to the pg_rules name.
const PgRulesName = "pg_rules"
// InitPgRules handles registration of the pg_rules handler.
func InitPgRules() {
tables.AddHandler(PgCatalogName, PgRulesName, PgRulesHandler{})
}
// PgRulesHandler is the handler for the pg_rules table.
type PgRulesHandler struct{}
var _ tables.Handler = PgRulesHandler{}
// Name implements the interface tables.Handler.
func (p PgRulesHandler) Name() string {
return PgRulesName
}
// RowIter implements the interface tables.Handler.
func (p PgRulesHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_rules row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgRulesHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgRulesSchema,
PkOrdinals: nil,
}
}
// pgRulesSchema is the schema for pg_rules.
var pgRulesSchema = sql.Schema{
{Name: "schemaname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgRulesName},
{Name: "tablename", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgRulesName},
{Name: "rulename", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgRulesName},
{Name: "definition", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgRulesName},
}
// pgRulesRowIter is the sql.RowIter for the pg_rules table.
type pgRulesRowIter struct {
}
var _ sql.RowIter = (*pgRulesRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgRulesRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgRulesRowIter) Close(ctx *sql.Context) error {
return nil
}
+81
View File
@@ -0,0 +1,81 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgSeclabelName is a constant to the pg_seclabel name.
const PgSeclabelName = "pg_seclabel"
// InitPgSeclabel handles registration of the pg_seclabel handler.
func InitPgSeclabel() {
tables.AddHandler(PgCatalogName, PgSeclabelName, PgSeclabelHandler{})
}
// PgSeclabelHandler is the handler for the pg_seclabel table.
type PgSeclabelHandler struct{}
var _ tables.Handler = PgSeclabelHandler{}
// Name implements the interface tables.Handler.
func (p PgSeclabelHandler) Name() string {
return PgSeclabelName
}
// RowIter implements the interface tables.Handler.
func (p PgSeclabelHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_seclabel row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgSeclabelHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgSeclabelSchema,
PkOrdinals: nil,
}
}
// pgSeclabelSchema is the schema for pg_seclabel.
var pgSeclabelSchema = sql.Schema{
{Name: "objoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgSeclabelName},
{Name: "classoid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgSeclabelName},
{Name: "objsubid", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgSeclabelName},
{Name: "provider", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgSeclabelName}, // TODO: collation C
{Name: "label", Type: pgtypes.Text, Default: nil, Nullable: false, Source: PgSeclabelName}, // TODO: collation C
}
// pgSeclabelRowIter is the sql.RowIter for the pg_seclabel table.
type pgSeclabelRowIter struct {
}
var _ sql.RowIter = (*pgSeclabelRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgSeclabelRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgSeclabelRowIter) Close(ctx *sql.Context) error {
return nil
}
+84
View File
@@ -0,0 +1,84 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgSeclabelsName is a constant to the pg_seclabels name.
const PgSeclabelsName = "pg_seclabels"
// InitPgSeclabels handles registration of the pg_seclabels handler.
func InitPgSeclabels() {
tables.AddHandler(PgCatalogName, PgSeclabelsName, PgSeclabelsHandler{})
}
// PgSeclabelsHandler is the handler for the pg_seclabels table.
type PgSeclabelsHandler struct{}
var _ tables.Handler = PgSeclabelsHandler{}
// Name implements the interface tables.Handler.
func (p PgSeclabelsHandler) Name() string {
return PgSeclabelsName
}
// RowIter implements the interface tables.Handler.
func (p PgSeclabelsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_seclabels row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgSeclabelsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgSeclabelsSchema,
PkOrdinals: nil,
}
}
// pgSeclabelsSchema is the schema for pg_seclabels.
var pgSeclabelsSchema = sql.Schema{
{Name: "objoid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgSeclabelsName},
{Name: "classoid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgSeclabelsName},
{Name: "objsubid", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgSeclabelsName},
{Name: "objtype", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSeclabelsName},
{Name: "objnamespace", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgSeclabelsName},
{Name: "objname", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSeclabelsName}, // TODO: collation C
{Name: "provider", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSeclabelsName}, // TODO: collation C
{Name: "label", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSeclabelsName}, // TODO: collation C
}
// pgSeclabelsRowIter is the sql.RowIter for the pg_seclabels table.
type pgSeclabelsRowIter struct {
}
var _ sql.RowIter = (*pgSeclabelsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgSeclabelsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgSeclabelsRowIter) Close(ctx *sql.Context) error {
return nil
}
+150
View File
@@ -0,0 +1,150 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/core/id"
"github.com/dolthub/doltgresql/core/sequences"
"github.com/dolthub/doltgresql/server/functions"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgSequenceName is a constant to the pg_sequence name.
const PgSequenceName = "pg_sequence"
// InitPgSequence handles registration of the pg_sequence handler.
func InitPgSequence() {
tables.AddHandler(PgCatalogName, PgSequenceName, PgSequenceHandler{})
}
// PgSequenceHandler is the handler for the pg_sequence table.
type PgSequenceHandler struct{}
// pgSequence represents a row in the pg_sequence table and pg_sequences view
type pgSequence struct {
sequence *sequences.Sequence
schema string
oid id.Id
}
var _ tables.Handler = PgSequenceHandler{}
// Name implements the interface tables.Handler.
func (p PgSequenceHandler) Name() string {
return PgSequenceName
}
// RowIter implements the interface tables.Handler.
func (p PgSequenceHandler) RowIter(ctx *sql.Context, _ sql.Partition) (sql.RowIter, error) {
// Use cached data from this process if it exists
pgCatalogCache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if pgCatalogCache.sequences == nil {
err = cachePgSequences(ctx, pgCatalogCache)
if err != nil {
return nil, err
}
}
return &pgSequenceRowIter{
sequences: pgCatalogCache.sequences,
idx: 0,
}, nil
}
func cachePgSequences(ctx *sql.Context, pgCatalogCache *pgCatalogCache) error {
var sequences []*pgSequence
err := functions.IterateCurrentDatabase(ctx, functions.Callbacks{
Sequence: func(ctx *sql.Context, schema functions.ItemSchema, sequence functions.ItemSequence) (cont bool, err error) {
pgSeq := &pgSequence{
sequence: sequence.Item,
schema: schema.Item.SchemaName(),
oid: sequence.OID.AsId(),
}
sequences = append(sequences, pgSeq)
return true, nil
},
})
if err != nil {
return err
}
pgCatalogCache.sequences = sequences
return nil
}
// PkSchema implements the interface tables.Handler.
func (p PgSequenceHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgSequenceSchema,
PkOrdinals: nil,
}
}
// pgSequenceSchema is the schema for pg_sequence.
var pgSequenceSchema = sql.Schema{
{Name: "seqrelid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgSequenceName},
{Name: "seqtypid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgSequenceName},
{Name: "seqstart", Type: pgtypes.Int64, Default: nil, Nullable: false, Source: PgSequenceName},
{Name: "seqincrement", Type: pgtypes.Int64, Default: nil, Nullable: false, Source: PgSequenceName},
{Name: "seqmax", Type: pgtypes.Int64, Default: nil, Nullable: false, Source: PgSequenceName},
{Name: "seqmin", Type: pgtypes.Int64, Default: nil, Nullable: false, Source: PgSequenceName},
{Name: "seqcache", Type: pgtypes.Int64, Default: nil, Nullable: false, Source: PgSequenceName},
{Name: "seqcycle", Type: pgtypes.Bool, Default: nil, Nullable: false, Source: PgSequenceName},
}
// pgSequenceRowIter is the sql.RowIter for the pg_sequence table.
type pgSequenceRowIter struct {
sequences []*pgSequence
idx int
}
var _ sql.RowIter = (*pgSequenceRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgSequenceRowIter) Next(ctx *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.sequences) {
return nil, io.EOF
}
iter.idx++
sequence := iter.sequences[iter.idx-1].sequence
oid := iter.sequences[iter.idx-1].oid
return sql.Row{
oid, // seqrelid
sequence.DataTypeID.AsId(), // 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
}
// Close implements the interface sql.RowIter.
func (iter *pgSequenceRowIter) Close(ctx *sql.Context) error {
return nil
}
+131
View File
@@ -0,0 +1,131 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgSequencesName is a constant to the pg_sequences name.
const PgSequencesName = "pg_sequences"
// InitPgSequences handles registration of the pg_sequences handler.
func InitPgSequences() {
tables.AddHandler(PgCatalogName, PgSequencesName, PgSequencesHandler{})
}
// PgSequencesHandler is the handler for the pg_sequences table.
type PgSequencesHandler struct{}
var _ tables.Handler = PgSequencesHandler{}
// Name implements the interface tables.Handler.
func (p PgSequencesHandler) Name() string {
return PgSequencesName
}
// RowIter implements the interface tables.Handler.
func (p PgSequencesHandler) RowIter(ctx *sql.Context, _ sql.Partition) (sql.RowIter, error) {
cache, err := getPgCatalogCache(ctx)
if err != nil {
return nil, err
}
if cache.sequences == nil {
err = cachePgSequences(ctx, cache)
if err != nil {
return nil, err
}
}
return &pgSequencesRowIter{
sequences: cache.sequences,
idx: 0,
}, nil
}
// PkSchema implements the interface tables.Handler.
func (p PgSequencesHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgSequencesSchema,
PkOrdinals: nil,
}
}
// pgSequencesSchema is the schema for pg_sequences.
var pgSequencesSchema = sql.Schema{
{Name: "schemaname", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "sequencename", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "sequenceowner", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "data_type", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSequencesName}, // TODO: regtype type
{Name: "start_value", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "min_value", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "max_value", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "increment_by", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "cycle", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "cache_size", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgSequencesName},
{Name: "last_value", Type: pgtypes.Int64, Default: nil, Nullable: true, Source: PgSequencesName},
}
// pgSequencesRowIter is the sql.RowIter for the pg_sequences table.
type pgSequencesRowIter struct {
sequences []*pgSequence
idx int
}
var _ sql.RowIter = (*pgSequencesRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgSequencesRowIter) Next(_ *sql.Context) (sql.Row, error) {
if iter.idx >= len(iter.sequences) {
return nil, io.EOF
}
sequence := iter.sequences[iter.idx].sequence
schemaName := iter.sequences[iter.idx].schema
iter.idx++
var lastValue interface{}
if sequence.HasBeenCalled {
if sequence.IsAtEnd {
lastValue = sequence.Current
} else {
lastValue = sequence.Current - sequence.Increment
}
}
return sql.Row{
schemaName, // schemaname
sequence.Id.SequenceName(), // sequencename
nil, // sequenceowner
sequence.DataTypeID.TypeName(), // data_type
sequence.Start, // start_value
sequence.Minimum, // min_value
sequence.Maximum, // max_value
sequence.Increment, // increment_by
sequence.Cycle, // cycle
sequence.Cache, // cache_size
lastValue, // last_value
}, nil
}
// Close implements the interface sql.RowIter.
func (iter *pgSequencesRowIter) Close(_ *sql.Context) error {
return nil
}
+93
View File
@@ -0,0 +1,93 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgSettingsName is a constant to the pg_settings name.
const PgSettingsName = "pg_settings"
// InitPgSettings handles registration of the pg_settings handler.
func InitPgSettings() {
tables.AddHandler(PgCatalogName, PgSettingsName, PgSettingsHandler{})
}
// PgSettingsHandler is the handler for the pg_settings table.
type PgSettingsHandler struct{}
var _ tables.Handler = PgSettingsHandler{}
// Name implements the interface tables.Handler.
func (p PgSettingsHandler) Name() string {
return PgSettingsName
}
// RowIter implements the interface tables.Handler.
func (p PgSettingsHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_settings row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgSettingsHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgSettingsSchema,
PkOrdinals: nil,
}
}
// pgSettingsSchema is the schema for pg_settings.
var pgSettingsSchema = sql.Schema{
{Name: "name", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "setting", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "unit", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "category", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "short_desc", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "extra_desc", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "context", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "vartype", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "source", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "min_val", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "max_val", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "enumvals", Type: pgtypes.TextArray, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "boot_val", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "reset_val", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "sourcefile", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "sourceline", Type: pgtypes.Int32, Default: nil, Nullable: true, Source: PgSettingsName},
{Name: "pending_restart", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgSettingsName},
}
// pgSettingsRowIter is the sql.RowIter for the pg_settings table.
type pgSettingsRowIter struct {
}
var _ sql.RowIter = (*pgSettingsRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgSettingsRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgSettingsRowIter) Close(ctx *sql.Context) error {
return nil
}
+85
View File
@@ -0,0 +1,85 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgShadowName is a constant to the pg_shadow name.
const PgShadowName = "pg_shadow"
// InitPgShadow handles registration of the pg_shadow handler.
func InitPgShadow() {
tables.AddHandler(PgCatalogName, PgShadowName, PgShadowHandler{})
}
// PgShadowHandler is the handler for the pg_shadow table.
type PgShadowHandler struct{}
var _ tables.Handler = PgShadowHandler{}
// Name implements the interface tables.Handler.
func (p PgShadowHandler) Name() string {
return PgShadowName
}
// RowIter implements the interface tables.Handler.
func (p PgShadowHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_shadow row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgShadowHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgShadowSchema,
PkOrdinals: nil,
}
}
// pgShadowSchema is the schema for pg_shadow.
var pgShadowSchema = sql.Schema{
{Name: "usename", Type: pgtypes.Name, Default: nil, Nullable: true, Source: PgShadowName},
{Name: "usesysid", Type: pgtypes.Oid, Default: nil, Nullable: true, Source: PgShadowName},
{Name: "usecreatedb", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgShadowName},
{Name: "usesuper", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgShadowName},
{Name: "userepl", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgShadowName},
{Name: "usebypassrls", Type: pgtypes.Bool, Default: nil, Nullable: true, Source: PgShadowName},
{Name: "passwd", Type: pgtypes.Text, Default: nil, Nullable: true, Source: PgShadowName}, // TODO: collation C
{Name: "valuntil", Type: pgtypes.TimestampTZ, Default: nil, Nullable: true, Source: PgShadowName},
{Name: "useconfig", Type: pgtypes.TimeArray, Default: nil, Nullable: true, Source: PgShadowName}, // TODO: collation C
}
// pgShadowRowIter is the sql.RowIter for the pg_shadow table.
type pgShadowRowIter struct {
}
var _ sql.RowIter = (*pgShadowRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgShadowRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgShadowRowIter) Close(ctx *sql.Context) error {
return nil
}
+83
View File
@@ -0,0 +1,83 @@
// 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 pgcatalog
import (
"io"
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/doltgresql/server/tables"
pgtypes "github.com/dolthub/doltgresql/server/types"
)
// PgShdependName is a constant to the pg_shdepend name.
const PgShdependName = "pg_shdepend"
// InitPgShdepend handles registration of the pg_shdepend handler.
func InitPgShdepend() {
tables.AddHandler(PgCatalogName, PgShdependName, PgShdependHandler{})
}
// PgShdependHandler is the handler for the pg_shdepend table.
type PgShdependHandler struct{}
var _ tables.Handler = PgShdependHandler{}
// Name implements the interface tables.Handler.
func (p PgShdependHandler) Name() string {
return PgShdependName
}
// RowIter implements the interface tables.Handler.
func (p PgShdependHandler) RowIter(ctx *sql.Context, partition sql.Partition) (sql.RowIter, error) {
// TODO: Implement pg_shdepend row iter
return emptyRowIter()
}
// PkSchema implements the interface tables.Handler.
func (p PgShdependHandler) PkSchema() sql.PrimaryKeySchema {
return sql.PrimaryKeySchema{
Schema: pgShdependSchema,
PkOrdinals: nil,
}
}
// pgShdependSchema is the schema for pg_shdepend.
var pgShdependSchema = sql.Schema{
{Name: "dbid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgShdependName},
{Name: "classid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgShdependName},
{Name: "objid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgShdependName},
{Name: "objsubid", Type: pgtypes.Int32, Default: nil, Nullable: false, Source: PgShdependName},
{Name: "refclassid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgShdependName},
{Name: "refobjid", Type: pgtypes.Oid, Default: nil, Nullable: false, Source: PgShdependName},
{Name: "deptype", Type: pgtypes.InternalChar, Default: nil, Nullable: false, Source: PgShdependName},
}
// pgShdependRowIter is the sql.RowIter for the pg_shdepend table.
type pgShdependRowIter struct {
}
var _ sql.RowIter = (*pgShdependRowIter)(nil)
// Next implements the interface sql.RowIter.
func (iter *pgShdependRowIter) Next(ctx *sql.Context) (sql.Row, error) {
return nil, io.EOF
}
// Close implements the interface sql.RowIter.
func (iter *pgShdependRowIter) Close(ctx *sql.Context) error {
return nil
}

Some files were not shown because too many files have changed in this diff Show More