chore: import upstream snapshot with attribution
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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},
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
Executable
+331
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"},
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user