diff --git a/go/libraries/doltcore/sqle/database.go b/go/libraries/doltcore/sqle/database.go index 7c2b745feb..47348eeb6c 100644 --- a/go/libraries/doltcore/sqle/database.go +++ b/go/libraries/doltcore/sqle/database.go @@ -275,28 +275,18 @@ func (db Database) GetTableInsensitiveAsOf(ctx *sql.Context, tableName string, a return table, ok, nil } - switch table := table.(type) { - case *DoltTable: - tbl, err := table.LockedToRoot(ctx, root) - if err != nil { - return nil, false, err - } - return tbl, true, nil - case *AlterableDoltTable: - tbl, err := table.LockedToRoot(ctx, root) - if err != nil { - return nil, false, err - } - return tbl, true, nil - case *WritableDoltTable: - tbl, err := table.LockedToRoot(ctx, root) - if err != nil { - return nil, false, err - } - return tbl, true, nil - default: + versionableTable, ok := table.(dtables.VersionableTable) + if !ok { panic(fmt.Sprintf("unexpected table type %T", table)) } + + versionedTable, err := versionableTable.LockedToRoot(ctx, root) + + if err != nil { + return nil, false, err + } + return versionedTable, true, nil + } func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds *dsess.DoltSession, root *doltdb.RootValue, tblName string) (sql.Table, bool, error) { @@ -457,7 +447,12 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds if err != nil { return nil, false, err } - dt, found = dtables.NewIgnoreTable(ctx, db.ddb, backingTable), true + if backingTable == nil { + dt, found = dtables.NewEmptyIgnoreTable(ctx), true + } else { + versionableTable := backingTable.(dtables.VersionableTable) + dt, found = dtables.NewIgnoreTable(ctx, versionableTable), true + } } if found { diff --git a/go/libraries/doltcore/sqle/dtables/ignore_table.go b/go/libraries/doltcore/sqle/dtables/ignore_table.go index 79202e6919..6c75339ab0 100644 --- a/go/libraries/doltcore/sqle/dtables/ignore_table.go +++ b/go/libraries/doltcore/sqle/dtables/ignore_table.go @@ -38,8 +38,7 @@ var _ sql.ReplaceableTable = (*IgnoreTable)(nil) // IgnoreTable is the system table that stores patterns for table names that should not be committed. type IgnoreTable struct { - ddb *doltdb.DoltDB - backingTable sql.Table + backingTable VersionableTable } func (i *IgnoreTable) Name() string { @@ -81,8 +80,13 @@ func (i *IgnoreTable) PartitionRows(context *sql.Context, partition sql.Partitio } // NewIgnoreTable creates an IgnoreTable -func NewIgnoreTable(_ *sql.Context, ddb *doltdb.DoltDB, backingTable sql.Table) sql.Table { - return &IgnoreTable{ddb: ddb, backingTable: backingTable} +func NewIgnoreTable(_ *sql.Context, backingTable VersionableTable) sql.Table { + return &IgnoreTable{backingTable: backingTable} +} + +// NewEmptyIgnoreTable creates an IgnoreTable +func NewEmptyIgnoreTable(_ *sql.Context) sql.Table { + return &IgnoreTable{} } // Replacer returns a RowReplacer for this table. The RowReplacer will have Insert and optionally Delete called once @@ -109,6 +113,24 @@ func (it *IgnoreTable) Deleter(*sql.Context) sql.RowDeleter { return newIgnoreWriter(it) } +func (it *IgnoreTable) LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (sql.IndexAddressableTable, error) { + if it.backingTable == nil { + return it, nil + } + return it.backingTable.LockedToRoot(ctx, root) +} + +// IndexedAccess implements IndexAddressableTable, but IgnoreTables has no indexes. +// Thus, this should never be called. +func (it *IgnoreTable) IndexedAccess(lookup sql.IndexLookup) sql.IndexedTable { + panic("Unreachable") +} + +// GetIndexes implements IndexAddressableTable, but IgnoreTables has no indexes. +func (it *IgnoreTable) GetIndexes(ctx *sql.Context) ([]sql.Index, error) { + return nil, nil +} + var _ sql.RowReplacer = (*ignoreWriter)(nil) var _ sql.RowUpdater = (*ignoreWriter)(nil) var _ sql.RowInserter = (*ignoreWriter)(nil) diff --git a/go/libraries/doltcore/sqle/dtables/versioned_table.go b/go/libraries/doltcore/sqle/dtables/versioned_table.go new file mode 100644 index 0000000000..44d4aab140 --- /dev/null +++ b/go/libraries/doltcore/sqle/dtables/versioned_table.go @@ -0,0 +1,27 @@ +// Copyright 2023 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" + + "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" +) + +// VersionableTable is a sql.Table that has a history. The history can be queried by setting a specific doltdb.RootValue. +type VersionableTable interface { + sql.Table + LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (sql.IndexAddressableTable, error) +} diff --git a/go/libraries/doltcore/sqle/history_table.go b/go/libraries/doltcore/sqle/history_table.go index bec320ea16..afb2aae45d 100644 --- a/go/libraries/doltcore/sqle/history_table.go +++ b/go/libraries/doltcore/sqle/history_table.go @@ -489,7 +489,7 @@ func newRowItrForTableAtCommit(ctx *sql.Context, table *DoltTable, h hash.Hash, return &historyIter{nonExistentTable: true}, nil } - table, err = table.LockedToRoot(ctx, root) + lockedTable, err := table.LockedToRoot(ctx, root) if err != nil { return nil, err } @@ -497,13 +497,13 @@ func newRowItrForTableAtCommit(ctx *sql.Context, table *DoltTable, h hash.Hash, var partIter sql.PartitionIter var histTable sql.Table if !lookup.IsEmpty() { - indexes, err := table.GetIndexes(ctx) + indexes, err := lockedTable.GetIndexes(ctx) if err != nil { return nil, err } for _, idx := range indexes { if idx.ID() == lookup.Index.ID() { - histTable = table.IndexedAccess(lookup) + histTable = lockedTable.IndexedAccess(lookup) if err != nil { return nil, err } @@ -520,14 +520,14 @@ func newRowItrForTableAtCommit(ctx *sql.Context, table *DoltTable, h hash.Hash, } } if histTable == nil { - histTable = table - partIter, err = table.Partitions(ctx) + histTable = lockedTable + partIter, err = lockedTable.Partitions(ctx) if err != nil { return nil, err } } - converter := rowConverter(table.Schema(), targetSchema, h, meta, projections) + converter := rowConverter(lockedTable.Schema(), targetSchema, h, meta, projections) return &historyIter{ table: histTable, tablePartitions: partIter, diff --git a/go/libraries/doltcore/sqle/tables.go b/go/libraries/doltcore/sqle/tables.go index 545aa4b78b..45b002f94f 100644 --- a/go/libraries/doltcore/sqle/tables.go +++ b/go/libraries/doltcore/sqle/tables.go @@ -39,6 +39,7 @@ import ( "github.com/dolthub/dolt/go/libraries/doltcore/schema" "github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo" "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess" + "github.com/dolthub/dolt/go/libraries/doltcore/sqle/dtables" "github.com/dolthub/dolt/go/libraries/doltcore/sqle/index" "github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil" "github.com/dolthub/dolt/go/libraries/doltcore/sqle/writer" @@ -74,6 +75,8 @@ func init() { } } +var _ dtables.VersionableTable = (*DoltTable)(nil) + // DoltTable implements the sql.Table interface and gives access to dolt table rows and schema. type DoltTable struct { tableName string @@ -120,7 +123,7 @@ func NewDoltTable(name string, sch schema.Schema, tbl *doltdb.Table, db dsess.Sq // LockedToRoot returns a version of this table with its root value locked to the given value. The table's values will // not change as the session's root value changes. Appropriate for AS OF queries, or other use cases where the table's // values should not change throughout execution of a session. -func (t *DoltTable) LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (*DoltTable, error) { +func (t *DoltTable) LockedToRoot(ctx *sql.Context, root *doltdb.RootValue) (sql.IndexAddressableTable, error) { tbl, ok, err := root.GetTable(ctx, t.tableName) if err != nil { return nil, err diff --git a/integration-tests/bats/ignore.bats b/integration-tests/bats/ignore.bats index ca68840580..267a57893e 100644 --- a/integration-tests/bats/ignore.bats +++ b/integration-tests/bats/ignore.bats @@ -63,325 +63,64 @@ get_conflict_tables() { ' } -@test "ignore: simple matches" { - dolt sql <