mirror of
https://github.com/dolthub/dolt.git
synced 2026-03-14 19:20:44 -05:00
Merge pull request #2938 from dolthub/andy/generalize-dolt-indexes
go/libraries/doltcore/sqle: Remove some dependencies on pkg `types`
This commit is contained in:
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/env"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/env/actions/commitwalk"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/row"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema/alterschema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
|
||||
@@ -38,7 +37,6 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/writer"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/table/editor"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
var ErrInvalidTableName = errors.NewKind("Invalid table name %s. Table names must match the regular expression " + doltdb.TableNameRegexStr)
|
||||
@@ -925,7 +923,7 @@ func (db Database) GetView(ctx *sql.Context, viewName string) (string, bool, err
|
||||
return view, true, nil
|
||||
}
|
||||
|
||||
tbl, ok, err := root.GetTable(ctx, doltdb.SchemasTableName)
|
||||
tbl, ok, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
@@ -933,7 +931,7 @@ func (db Database) GetView(ctx *sql.Context, viewName string) (string, bool, err
|
||||
return "", false, nil
|
||||
}
|
||||
|
||||
fragments, err := getSchemaFragmentsOfType(ctx, tbl, "view")
|
||||
fragments, err := getSchemaFragmentsOfType(ctx, tbl.(*WritableDoltTable), viewFragment)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
@@ -949,12 +947,7 @@ func (db Database) GetView(ctx *sql.Context, viewName string) (string, bool, err
|
||||
|
||||
// GetView implements sql.ViewDatabase
|
||||
func (db Database) AllViews(ctx *sql.Context) ([]sql.ViewDefinition, error) {
|
||||
root, err := db.GetRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tbl, ok, err := root.GetTable(ctx, doltdb.SchemasTableName)
|
||||
tbl, ok, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -962,7 +955,7 @@ func (db Database) AllViews(ctx *sql.Context) ([]sql.ViewDefinition, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
frags, err := getSchemaFragmentsOfType(ctx, tbl, "view")
|
||||
frags, err := getSchemaFragmentsOfType(ctx, tbl.(*WritableDoltTable), viewFragment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -997,12 +990,7 @@ func (db Database) DropView(ctx *sql.Context, name string) error {
|
||||
|
||||
// GetTriggers implements sql.TriggerDatabase.
|
||||
func (db Database) GetTriggers(ctx *sql.Context) ([]sql.TriggerDefinition, error) {
|
||||
root, err := db.GetRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tbl, ok, err := root.GetTable(ctx, doltdb.SchemasTableName)
|
||||
tbl, ok, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1010,7 +998,7 @@ func (db Database) GetTriggers(ctx *sql.Context) ([]sql.TriggerDefinition, error
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
frags, err := getSchemaFragmentsOfType(ctx, tbl, "trigger")
|
||||
frags, err := getSchemaFragmentsOfType(ctx, tbl.(*WritableDoltTable), triggerFragment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1047,70 +1035,7 @@ func (db Database) DropTrigger(ctx *sql.Context, name string) error {
|
||||
|
||||
// GetStoredProcedures implements sql.StoredProcedureDatabase.
|
||||
func (db Database) GetStoredProcedures(ctx *sql.Context) ([]sql.StoredProcedureDetails, error) {
|
||||
missingValue := errors.NewKind("missing `%s` value for procedure row: (%s)")
|
||||
|
||||
root, err := db.GetRoot(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
table, ok, err := root.GetTable(ctx, doltdb.ProceduresTableName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
rowData, err := table.GetNomsRowData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sch, err := table.GetSchema(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var spds []sql.StoredProcedureDetails
|
||||
err = rowData.Iter(ctx, func(key, val types.Value) (stop bool, err error) {
|
||||
dRow, err := row.FromNoms(sch, key.(types.Tuple), val.(types.Tuple))
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
taggedVals, err := dRow.TaggedValues()
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
name, ok := dRow.GetColVal(schema.DoltProceduresNameTag)
|
||||
if !ok {
|
||||
return true, missingValue.New(doltdb.ProceduresTableNameCol, taggedVals)
|
||||
}
|
||||
createStmt, ok := dRow.GetColVal(schema.DoltProceduresCreateStmtTag)
|
||||
if !ok {
|
||||
return true, missingValue.New(doltdb.ProceduresTableCreateStmtCol, taggedVals)
|
||||
}
|
||||
createdAt, ok := dRow.GetColVal(schema.DoltProceduresCreatedAtTag)
|
||||
if !ok {
|
||||
return true, missingValue.New(doltdb.ProceduresTableCreatedAtCol, taggedVals)
|
||||
}
|
||||
modifiedAt, ok := dRow.GetColVal(schema.DoltProceduresModifiedAtTag)
|
||||
if !ok {
|
||||
return true, missingValue.New(doltdb.ProceduresTableModifiedAtCol, taggedVals)
|
||||
}
|
||||
spds = append(spds, sql.StoredProcedureDetails{
|
||||
Name: string(name.(types.String)),
|
||||
CreateStatement: string(createStmt.(types.String)),
|
||||
CreatedAt: time.Time(createdAt.(types.Timestamp)),
|
||||
ModifiedAt: time.Time(modifiedAt.(types.Timestamp)),
|
||||
})
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return spds, nil
|
||||
return DoltProceduresGetAll(ctx, db)
|
||||
}
|
||||
|
||||
// SaveStoredProcedure implements sql.StoredProcedureDatabase.
|
||||
|
||||
@@ -376,6 +376,9 @@ func TestStoredProcedures(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestTransactions(t *testing.T) {
|
||||
if types.IsFormat_DOLT_1(types.Format_Default) {
|
||||
t.Skip()
|
||||
}
|
||||
enginetest.TestTransactionScripts(t, newDoltHarness(t))
|
||||
for _, script := range DoltTransactionTests {
|
||||
enginetest.TestTransactionScript(t, newDoltHarness(t), script)
|
||||
|
||||
@@ -23,11 +23,16 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
// TODO: we need tests for manual DOLT_COMMIT as well, but that's difficult with the way that functions are resolved
|
||||
// in the engine.
|
||||
func TestDoltTransactionCommitOneClient(t *testing.T) {
|
||||
if types.IsFormat_DOLT_1(types.Format_Default) {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
// In this test, we're setting only one client to match transaction commits to dolt commits.
|
||||
// Autocommit is disabled for the enabled client, as it's the recommended way to use this feature.
|
||||
harness := newDoltHarness(t)
|
||||
@@ -163,6 +168,10 @@ func TestDoltTransactionCommitOneClient(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoltTransactionCommitTwoClients(t *testing.T) {
|
||||
if types.IsFormat_DOLT_1(types.Format_Default) {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
// In this test, we're setting both clients to match transaction commits to dolt commits.
|
||||
// Autocommit is disabled, as it's the recommended way to use this feature.
|
||||
harness := newDoltHarness(t)
|
||||
@@ -291,6 +300,10 @@ func TestDoltTransactionCommitTwoClients(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoltTransactionCommitAutocommit(t *testing.T) {
|
||||
if types.IsFormat_DOLT_1(types.Format_Default) {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
// In this test, each insertion from both clients cause a commit as autocommit is enabled.
|
||||
// Not the recommended way to use the feature, but it's permitted.
|
||||
harness := newDoltHarness(t)
|
||||
@@ -365,6 +378,10 @@ func TestDoltTransactionCommitAutocommit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDoltTransactionCommitLateFkResolution(t *testing.T) {
|
||||
if types.IsFormat_DOLT_1(types.Format_Default) {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
harness := newDoltHarness(t)
|
||||
enginetest.TestTransactionScript(t, harness, enginetest.TransactionTest{
|
||||
Name: "delayed foreign key resolution with transaction commits",
|
||||
|
||||
@@ -290,7 +290,12 @@ RangeLoop:
|
||||
}
|
||||
|
||||
func (di doltIndex) HandledFilters(filters []sql.Expression) []sql.Expression {
|
||||
return filters
|
||||
if types.IsFormat_DOLT_1(di.vrw.Format()) {
|
||||
// todo(andy): handle first column filters
|
||||
return nil
|
||||
} else {
|
||||
return filters
|
||||
}
|
||||
}
|
||||
|
||||
// Database implement sql.Index
|
||||
@@ -425,14 +430,13 @@ func prollyRangeFromSqlRange(sqlRange sql.Range, tb *val.TupleBuilder) (rng prol
|
||||
start := prolly.RangeCut{Inclusive: true}
|
||||
startRow := sql.Row{}
|
||||
for _, sc := range lower {
|
||||
if !isBindingCut(sc) {
|
||||
if !sql.RangeCutIsBinding(sc) {
|
||||
start = prolly.RangeCut{Unbound: true, Inclusive: false}
|
||||
break
|
||||
}
|
||||
start.Inclusive = start.Inclusive && sc.TypeAsLowerBound() == sql.Closed
|
||||
startRow = append(startRow, sql.GetRangeCutKey(sc))
|
||||
}
|
||||
|
||||
if !start.Unbound {
|
||||
startRow, err = normalizeRangeKey(sqlRange, startRow)
|
||||
if err != nil {
|
||||
@@ -448,7 +452,7 @@ func prollyRangeFromSqlRange(sqlRange sql.Range, tb *val.TupleBuilder) (rng prol
|
||||
stop := prolly.RangeCut{Inclusive: true}
|
||||
stopRow := sql.Row{}
|
||||
for _, sc := range upper {
|
||||
if !isBindingCut(sc) {
|
||||
if !sql.RangeCutIsBinding(sc) {
|
||||
stop = prolly.RangeCut{Unbound: true, Inclusive: false}
|
||||
break
|
||||
}
|
||||
@@ -476,10 +480,6 @@ func prollyRangeFromSqlRange(sqlRange sql.Range, tb *val.TupleBuilder) (rng prol
|
||||
}, nil
|
||||
}
|
||||
|
||||
func isBindingCut(cut sql.RangeCut) bool {
|
||||
return cut != sql.BelowAll{} && cut != sql.AboveAll{}
|
||||
}
|
||||
|
||||
func tupleFromKeys(keys sql.Row, tb *val.TupleBuilder) (val.Tuple, error) {
|
||||
var err error
|
||||
for i, v := range keys {
|
||||
|
||||
@@ -31,6 +31,7 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/index"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/config"
|
||||
)
|
||||
|
||||
@@ -1056,7 +1057,10 @@ func TestDoltIndexBetween(t *testing.T) {
|
||||
indexLookup, err := sqlIndex.Build(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
indexIter, err := index.RowIterForIndexLookup(ctx, indexLookup, nil)
|
||||
pkSch, err := sqlutil.FromDoltSchema("fake_table", idx.Schema())
|
||||
require.NoError(t, err)
|
||||
|
||||
indexIter, err := index.RowIterForIndexLookup(ctx, indexLookup, pkSch, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
var readRows []sql.Row
|
||||
@@ -1250,7 +1254,7 @@ func requireUnorderedRowsEqual(t *testing.T, rows1, rows2 []sql.Row) {
|
||||
require.Equal(t, rows1, rows2)
|
||||
}
|
||||
|
||||
func testDoltIndex(t *testing.T, keys []interface{}, expectedRows []sql.Row, idx sql.Index, cmp indexComp) {
|
||||
func testDoltIndex(t *testing.T, keys []interface{}, expectedRows []sql.Row, idx index.DoltIndex, cmp indexComp) {
|
||||
ctx := NewTestSQLCtx(context.Background())
|
||||
exprs := idx.Expressions()
|
||||
builder := sql.NewIndexBuilder(sql.NewEmptyContext(), idx)
|
||||
@@ -1275,7 +1279,10 @@ func testDoltIndex(t *testing.T, keys []interface{}, expectedRows []sql.Row, idx
|
||||
indexLookup, err := builder.Build(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
indexIter, err := index.RowIterForIndexLookup(ctx, indexLookup, nil)
|
||||
pkSch, err := sqlutil.FromDoltSchema("fake_table", idx.Schema())
|
||||
require.NoError(t, err)
|
||||
|
||||
indexIter, err := index.RowIterForIndexLookup(ctx, indexLookup, pkSch, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
var readRows []sql.Row
|
||||
|
||||
@@ -36,26 +36,35 @@ func PartitionIndexedTableRows(ctx *sql.Context, idx sql.Index, part sql.Partiti
|
||||
doltIdx := idx.(DoltIndex)
|
||||
|
||||
if types.IsFormat_DOLT_1(rp.rows.Format()) {
|
||||
covers := indexCoversCols(doltIdx, columns)
|
||||
if covers {
|
||||
return newProllyCoveringIndexIter(ctx, doltIdx, rp.prollyRange, pkSch)
|
||||
} else {
|
||||
return newProllyIndexIter(ctx, doltIdx, rp.prollyRange, columns)
|
||||
}
|
||||
return RowIterForProllyRange(ctx, doltIdx, rp.prollyRange, pkSch, columns)
|
||||
}
|
||||
|
||||
ranges := []*noms.ReadRange{rp.nomsRange}
|
||||
return RowIterForRanges(ctx, doltIdx, ranges, rp.rows, columns)
|
||||
return RowIterForNomsRanges(ctx, doltIdx, ranges, rp.rows, columns)
|
||||
}
|
||||
|
||||
func RowIterForIndexLookup(ctx *sql.Context, ilu sql.IndexLookup, columns []string) (sql.RowIter, error) {
|
||||
func RowIterForIndexLookup(ctx *sql.Context, ilu sql.IndexLookup, pkSch sql.PrimaryKeySchema, columns []string) (sql.RowIter, error) {
|
||||
lookup := ilu.(*doltIndexLookup)
|
||||
idx := lookup.idx
|
||||
|
||||
return RowIterForRanges(ctx, idx, lookup.nomsRanges, lookup.IndexRowData(), columns)
|
||||
if types.IsFormat_DOLT_1(idx.Format()) {
|
||||
// todo(andy)
|
||||
return RowIterForProllyRange(ctx, idx, lookup.prollyRanges[0], pkSch, columns)
|
||||
} else {
|
||||
return RowIterForNomsRanges(ctx, idx, lookup.nomsRanges, lookup.IndexRowData(), columns)
|
||||
}
|
||||
}
|
||||
|
||||
func RowIterForRanges(ctx *sql.Context, idx DoltIndex, ranges []*noms.ReadRange, rowData durable.Index, columns []string) (sql.RowIter, error) {
|
||||
func RowIterForProllyRange(ctx *sql.Context, idx DoltIndex, ranges prolly.Range, pkSch sql.PrimaryKeySchema, columns []string) (sql.RowIter, error) {
|
||||
covers := indexCoversCols(idx, columns)
|
||||
if covers {
|
||||
return newProllyCoveringIndexIter(ctx, idx, ranges, pkSch)
|
||||
} else {
|
||||
return newProllyIndexIter(ctx, idx, ranges)
|
||||
}
|
||||
}
|
||||
|
||||
func RowIterForNomsRanges(ctx *sql.Context, idx DoltIndex, ranges []*noms.ReadRange, rowData durable.Index, columns []string) (sql.RowIter, error) {
|
||||
m := durable.NomsMapFromIndex(rowData)
|
||||
nrr := noms.NewNomsRangeReader(idx.IndexSchema(), m, ranges)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ type prollyIndexIter struct {
|
||||
var _ sql.RowIter = prollyIndexIter{}
|
||||
|
||||
// NewProllyIndexIter returns a new prollyIndexIter.
|
||||
func newProllyIndexIter(ctx *sql.Context, idx DoltIndex, rng prolly.Range, projection []string) (prollyIndexIter, error) {
|
||||
func newProllyIndexIter(ctx *sql.Context, idx DoltIndex, rng prolly.Range) (prollyIndexIter, error) {
|
||||
secondary := durable.ProllyMapFromIndex(idx.IndexRowData())
|
||||
indexIter, err := secondary.IterRange(ctx, rng)
|
||||
if err != nil {
|
||||
|
||||
@@ -58,7 +58,7 @@ func (idt *IndexedDoltTable) Partitions(ctx *sql.Context) (sql.PartitionIter, er
|
||||
|
||||
func (idt *IndexedDoltTable) PartitionRows(ctx *sql.Context, part sql.Partition) (sql.RowIter, error) {
|
||||
// todo(andy): only used by 'AS OF` queries
|
||||
return index.RowIterForIndexLookup(ctx, idt.indexLookup, nil)
|
||||
return index.RowIterForIndexLookup(ctx, idt.indexLookup, idt.table.sqlSch, nil)
|
||||
}
|
||||
|
||||
func (idt *IndexedDoltTable) IsTemporary() bool {
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
"gopkg.in/src-d/go-errors.v1"
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
@@ -95,6 +96,74 @@ func DoltProceduresGetTable(ctx *sql.Context, db Database) (*WritableDoltTable,
|
||||
return tbl.(*WritableDoltTable), nil
|
||||
}
|
||||
|
||||
func DoltProceduresGetAll(ctx *sql.Context, db Database) ([]sql.StoredProcedureDetails, error) {
|
||||
tbl, err := DoltProceduresGetTable(ctx, db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
indexes, err := tbl.GetIndexes(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(indexes) == 0 {
|
||||
return nil, fmt.Errorf("missing index for stored procedures")
|
||||
}
|
||||
idx := indexes[0]
|
||||
|
||||
if len(idx.Expressions()) == 0 {
|
||||
return nil, fmt.Errorf("missing index expression for stored procedures")
|
||||
}
|
||||
nameExpr := idx.Expressions()[0]
|
||||
|
||||
lookup, err := sql.NewIndexBuilder(ctx, idx).IsNotNull(ctx, nameExpr).Build(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iter, err := index.RowIterForIndexLookup(ctx, lookup, tbl.sqlSch, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if cerr := iter.Close(ctx); cerr != nil {
|
||||
err = cerr
|
||||
}
|
||||
}()
|
||||
|
||||
var sqlRow sql.Row
|
||||
var details []sql.StoredProcedureDetails
|
||||
missingValue := errors.NewKind("missing `%s` value for procedure row: (%s)")
|
||||
|
||||
for {
|
||||
sqlRow, err = iter.Next(ctx)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var d sql.StoredProcedureDetails
|
||||
var ok bool
|
||||
|
||||
if d.Name, ok = sqlRow[0].(string); !ok {
|
||||
return nil, missingValue.New(doltdb.ProceduresTableNameCol, sqlRow)
|
||||
}
|
||||
if d.CreateStatement, ok = sqlRow[1].(string); !ok {
|
||||
return nil, missingValue.New(doltdb.ProceduresTableCreateStmtCol, sqlRow)
|
||||
}
|
||||
if d.CreatedAt, ok = sqlRow[2].(time.Time); !ok {
|
||||
return nil, missingValue.New(doltdb.ProceduresTableCreatedAtCol, sqlRow)
|
||||
}
|
||||
if d.ModifiedAt, ok = sqlRow[3].(time.Time); !ok {
|
||||
return nil, missingValue.New(doltdb.ProceduresTableModifiedAtCol, sqlRow)
|
||||
}
|
||||
details = append(details, d)
|
||||
}
|
||||
return details, nil
|
||||
}
|
||||
|
||||
// DoltProceduresAddProcedure adds the stored procedure to the `dolt_procedures` table in the given db, creating it if
|
||||
// it does not exist.
|
||||
func DoltProceduresAddProcedure(ctx *sql.Context, db Database, spd sql.StoredProcedureDetails) (retErr error) {
|
||||
@@ -172,7 +241,7 @@ func DoltProceduresGetDetails(ctx *sql.Context, tbl *WritableDoltTable, name str
|
||||
return sql.StoredProcedureDetails{}, false, err
|
||||
}
|
||||
|
||||
rowIter, err := index.RowIterForIndexLookup(ctx, indexLookup, nil)
|
||||
rowIter, err := index.RowIterForIndexLookup(ctx, indexLookup, tbl.sqlSch, nil)
|
||||
if err != nil {
|
||||
return sql.StoredProcedureDetails{}, false, err
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/index"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/table"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/set"
|
||||
"github.com/dolthub/dolt/go/store/prolly"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
@@ -184,10 +185,30 @@ func ProllyRowIterFromPartition(ctx context.Context, tbl *doltdb.Table, projecti
|
||||
// returned rows always have the schema of the table, regardless of the value
|
||||
// of |columns|. Providing a column name which does not appear in the schema
|
||||
// is not an error, but no corresponding column will appear in the results.
|
||||
func TableToRowIter(ctx context.Context, table *doltdb.Table, columns []string) (sql.RowIter, error) {
|
||||
data, err := table.GetRowData(ctx)
|
||||
func TableToRowIter(ctx *sql.Context, table *WritableDoltTable, columns []string) (sql.RowIter, error) {
|
||||
t, err := table.doltTable(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newRowIterator(ctx, table, columns, doltTablePartition{rowData: data, end: NoUpperBound})
|
||||
data, err := t.GetRowData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := doltTablePartition{
|
||||
end: NoUpperBound,
|
||||
rowData: data,
|
||||
}
|
||||
|
||||
if types.IsFormat_DOLT_1(data.Format()) {
|
||||
m := durable.ProllyMapFromIndex(data)
|
||||
kd, _ := m.Descriptors()
|
||||
p.rowRange = prolly.Range{
|
||||
Start: prolly.RangeCut{Unbound: true},
|
||||
Stop: prolly.RangeCut{Unbound: true},
|
||||
KeyDesc: kd,
|
||||
}
|
||||
}
|
||||
|
||||
return newRowIterator(ctx, t, columns, p)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb/durable"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/row"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo"
|
||||
@@ -32,6 +33,11 @@ import (
|
||||
var errDoltSchemasTableFormat = fmt.Errorf("`%s` schema in unexpected format", doltdb.SchemasTableName)
|
||||
var noSchemaIndexDefined = fmt.Errorf("could not find index `%s` on system table `%s`", doltdb.SchemasTablesIndexName, doltdb.SchemasTableName)
|
||||
|
||||
const (
|
||||
viewFragment = "view"
|
||||
triggerFragment = "trigger"
|
||||
)
|
||||
|
||||
// The fixed dolt schema for the `dolt_schemas` table.
|
||||
func SchemasTableSchema() schema.Schema {
|
||||
typeCol, err := schema.NewColumnWithTypeInfo(doltdb.SchemasTablesTypeCol, schema.DoltSchemasTypeTag, typeinfo.LegacyStringDefaultType, false, "", false, "")
|
||||
@@ -200,26 +206,41 @@ func nextSchemasTableIndex(ctx *sql.Context, root *doltdb.RootValue) (int64, err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
rows, err := tbl.GetNomsRowData(ctx)
|
||||
rows, err := tbl.GetRowData(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
idx := int64(1)
|
||||
if rows.Len() > 0 {
|
||||
keyTpl, _, err := rows.Last(ctx)
|
||||
if rows.Empty() {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
if types.IsFormat_DOLT_1(tbl.Format()) {
|
||||
p := durable.ProllyMapFromIndex(rows)
|
||||
key, _, err := p.Last(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if keyTpl != nil {
|
||||
key, err := keyTpl.(types.Tuple).Get(1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
idx = int64(key.(types.Int)) + 1
|
||||
kd, _ := p.Descriptors()
|
||||
|
||||
i, _ := kd.GetInt64(0, key)
|
||||
return i + 1, nil
|
||||
} else {
|
||||
m := durable.NomsMapFromIndex(rows)
|
||||
keyTpl, _, err := m.Last(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if keyTpl == nil {
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
key, err := keyTpl.(types.Tuple).Get(1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int64(key.(types.Int)) + 1, nil
|
||||
}
|
||||
return idx, nil
|
||||
}
|
||||
|
||||
// fragFromSchemasTable returns the row with the given schema fragment if it exists.
|
||||
@@ -245,7 +266,7 @@ func fragFromSchemasTable(ctx *sql.Context, tbl *WritableDoltTable, fragType str
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
iter, err := index.RowIterForIndexLookup(ctx, lookup, nil)
|
||||
iter, err := index.RowIterForIndexLookup(ctx, lookup, tbl.sqlSch, nil)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
@@ -271,57 +292,29 @@ type schemaFragment struct {
|
||||
fragment string
|
||||
}
|
||||
|
||||
func getSchemaFragmentsOfType(ctx *sql.Context, tbl *doltdb.Table, fragmentType string) ([]schemaFragment, error) {
|
||||
sch, err := tbl.GetSchema(ctx)
|
||||
func getSchemaFragmentsOfType(ctx *sql.Context, tbl *WritableDoltTable, fragType string) ([]schemaFragment, error) {
|
||||
iter, err := TableToRowIter(ctx, tbl, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
typeCol, ok := sch.GetAllCols().GetByName(doltdb.SchemasTablesTypeCol)
|
||||
if !ok {
|
||||
return nil, errDoltSchemasTableFormat
|
||||
}
|
||||
nameCol, ok := sch.GetAllCols().GetByName(doltdb.SchemasTablesNameCol)
|
||||
if !ok {
|
||||
return nil, errDoltSchemasTableFormat
|
||||
}
|
||||
fragCol, ok := sch.GetAllCols().GetByName(doltdb.SchemasTablesFragmentCol)
|
||||
if !ok {
|
||||
return nil, errDoltSchemasTableFormat
|
||||
}
|
||||
|
||||
rowData, err := tbl.GetNomsRowData(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var fragments []schemaFragment
|
||||
err = rowData.Iter(ctx, func(key, val types.Value) (stop bool, err error) {
|
||||
dRow, err := row.FromNoms(sch, key.(types.Tuple), val.(types.Tuple))
|
||||
var frags []schemaFragment
|
||||
for {
|
||||
sqlRow, err := iter.Next(ctx)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return true, err
|
||||
return nil, err
|
||||
}
|
||||
if typeColVal, ok := dRow.GetColVal(typeCol.Tag); ok && typeColVal.Equals(types.String(fragmentType)) {
|
||||
name, ok := dRow.GetColVal(nameCol.Tag)
|
||||
if !ok {
|
||||
taggedVals, _ := dRow.TaggedValues()
|
||||
return true, fmt.Errorf("missing `%s` value for view row: (%s)", doltdb.SchemasTablesNameCol, taggedVals)
|
||||
}
|
||||
def, ok := dRow.GetColVal(fragCol.Tag)
|
||||
if !ok {
|
||||
taggedVals, _ := dRow.TaggedValues()
|
||||
return true, fmt.Errorf("missing `%s` value for view row: (%s)", doltdb.SchemasTablesFragmentCol, taggedVals)
|
||||
}
|
||||
fragments = append(fragments, schemaFragment{
|
||||
name: string(name.(types.String)),
|
||||
fragment: string(def.(types.String)),
|
||||
})
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fragments, nil
|
||||
if sqlRow[0] != fragType {
|
||||
continue
|
||||
}
|
||||
frags = append(frags, schemaFragment{
|
||||
name: sqlRow[1].(string),
|
||||
fragment: sqlRow[2].(string),
|
||||
})
|
||||
}
|
||||
return frags, nil
|
||||
}
|
||||
|
||||
@@ -484,6 +484,11 @@ func (t *WritableDoltTable) Truncate(ctx *sql.Context) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
sch, err := table.GetSchema(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
rowData, err := table.GetRowData(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -495,13 +500,20 @@ func (t *WritableDoltTable) Truncate(ctx *sql.Context) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// truncate table resets auto-increment value
|
||||
newTable, err := doltdb.NewTable(ctx, table.ValueReadWriter(), t.sch, empty, nil, nil)
|
||||
idxSet, err := table.GetIndexSet(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
newTable, err = editor.RebuildAllIndexes(ctx, newTable, t.opts)
|
||||
for _, idx := range sch.Indexes().AllIndexes() {
|
||||
idxSet, err = idxSet.PutIndex(ctx, idx.Name(), empty)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
// truncate table resets auto-increment value
|
||||
newTable, err := doltdb.NewTable(ctx, table.ValueReadWriter(), t.sch, empty, idxSet, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -852,6 +864,10 @@ var _ doltAlterableTableInterface = (*AlterableDoltTable)(nil)
|
||||
|
||||
// AddColumn implements sql.AlterableTable
|
||||
func (t *AlterableDoltTable) AddColumn(ctx *sql.Context, column *sql.Column, order *sql.ColumnOrder) error {
|
||||
if types.IsFormat_DOLT_1(t.nbf) {
|
||||
return nil
|
||||
}
|
||||
|
||||
root, err := t.getRoot(ctx)
|
||||
|
||||
if err != nil {
|
||||
@@ -916,6 +932,10 @@ func orderToOrder(order *sql.ColumnOrder) *alterschema.ColumnOrder {
|
||||
|
||||
// DropColumn implements sql.AlterableTable
|
||||
func (t *AlterableDoltTable) DropColumn(ctx *sql.Context, columnName string) error {
|
||||
if types.IsFormat_DOLT_1(t.nbf) {
|
||||
return nil
|
||||
}
|
||||
|
||||
root, err := t.getRoot(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1038,6 +1058,10 @@ func (t *AlterableDoltTable) dropColumnData(ctx *sql.Context, updatedTable *dolt
|
||||
|
||||
// ModifyColumn implements sql.AlterableTable
|
||||
func (t *AlterableDoltTable) ModifyColumn(ctx *sql.Context, columnName string, column *sql.Column, order *sql.ColumnOrder) error {
|
||||
if types.IsFormat_DOLT_1(t.nbf) {
|
||||
return nil
|
||||
}
|
||||
|
||||
root, err := t.getRoot(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1847,6 +1871,10 @@ func (t *AlterableDoltTable) constraintNameExists(ctx *sql.Context, name string)
|
||||
}
|
||||
|
||||
func (t *AlterableDoltTable) CreatePrimaryKey(ctx *sql.Context, columns []sql.IndexColumn) error {
|
||||
if types.IsFormat_DOLT_1(t.nbf) {
|
||||
return nil
|
||||
}
|
||||
|
||||
table, err := t.doltTable(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -1877,6 +1905,10 @@ func (t *AlterableDoltTable) CreatePrimaryKey(ctx *sql.Context, columns []sql.In
|
||||
}
|
||||
|
||||
func (t *AlterableDoltTable) DropPrimaryKey(ctx *sql.Context) error {
|
||||
if types.IsFormat_DOLT_1(t.nbf) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ensure that no auto increment requirements exist on this table
|
||||
if t.autoIncCol.AutoIncrement {
|
||||
return sql.ErrWrongAutoKey.New()
|
||||
|
||||
@@ -151,6 +151,19 @@ func (m Map) Has(ctx context.Context, key val.Tuple) (ok bool, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (m Map) Last(ctx context.Context) (key, value val.Tuple, err error) {
|
||||
cur, err := newCursorAtEnd(ctx, m.ns, m.root)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if cur.valid() {
|
||||
key = val.Tuple(cur.currentKey())
|
||||
value = val.Tuple(cur.currentValue())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// IterAll returns a MutableMapRangeIter that iterates over the entire Map.
|
||||
func (m Map) IterAll(ctx context.Context) (MapRangeIter, error) {
|
||||
rng := Range{
|
||||
|
||||
@@ -62,7 +62,7 @@ func newCursorAtStart(ctx context.Context, nrw NodeStore, nd Node) (cur *nodeCur
|
||||
return
|
||||
}
|
||||
|
||||
func newCursorPastEnd(ctx context.Context, nrw NodeStore, nd Node) (cur *nodeCursor, err error) {
|
||||
func newCursorAtEnd(ctx context.Context, nrw NodeStore, nd Node) (cur *nodeCursor, err error) {
|
||||
cur = &nodeCursor{nd: nd, nrw: nrw}
|
||||
cur.skipToNodeEnd()
|
||||
|
||||
@@ -76,6 +76,14 @@ func newCursorPastEnd(ctx context.Context, nrw NodeStore, nd Node) (cur *nodeCur
|
||||
cur = &nodeCursor{nd: nd, parent: parent, nrw: nrw}
|
||||
cur.skipToNodeEnd()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func newCursorPastEnd(ctx context.Context, nrw NodeStore, nd Node) (cur *nodeCursor, err error) {
|
||||
cur, err = newCursorAtEnd(ctx, nrw, nd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// advance |cur| past the end
|
||||
ok, err := cur.advance(ctx)
|
||||
|
||||
Reference in New Issue
Block a user