mirror of
https://github.com/dolthub/dolt.git
synced 2025-12-30 08:50:01 -06:00
Moved everything over to SHOW CREATE TABLE and fixed diff panic
This commit is contained in:
committed by
Daylon Wilkins
parent
2a09f9161e
commit
892de5ed98
@@ -430,3 +430,28 @@ SQL
|
||||
[ $status -eq 1 ]
|
||||
[[ ! $output =~ "panic" ]]
|
||||
}
|
||||
|
||||
@test "diff with foreign key and sql output" {
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE parent (
|
||||
id int PRIMARY KEY,
|
||||
pv1 int,
|
||||
pv2 int,
|
||||
INDEX v1 (pv1),
|
||||
INDEX v2 (pv2)
|
||||
);
|
||||
SQL
|
||||
dolt add -A
|
||||
dolt commit -m "hi"
|
||||
dolt sql <<SQL
|
||||
CREATE TABLE child (
|
||||
id int primary key,
|
||||
cv1 int,
|
||||
cv2 int,
|
||||
CONSTRAINT fk_named FOREIGN KEY (cv1) REFERENCES parent(pv1)
|
||||
);
|
||||
SQL
|
||||
run dolt diff -s -r=sql master
|
||||
[ $status -eq 0 ]
|
||||
[[ $output =~ "CONSTRAINT \`fk_named\` FOREIGN KEY (\`cv1\`) REFERENCES \`parent\` (\`pv1\`)" ]] || false
|
||||
}
|
||||
|
||||
@@ -59,12 +59,12 @@ teardown() {
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 9 ]
|
||||
[[ "${lines[0]}" =~ "test" ]] || false
|
||||
[[ "$output" =~ "\`pk\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c1\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c2\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c3\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c4\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c5\` INT" ]] || false
|
||||
[[ "$output" =~ "\`pk\` int" ]] || false
|
||||
[[ "$output" =~ "\`c1\` int" ]] || false
|
||||
[[ "$output" =~ "\`c2\` int" ]] || false
|
||||
[[ "$output" =~ "\`c3\` int" ]] || false
|
||||
[[ "$output" =~ "\`c4\` int" ]] || false
|
||||
[[ "$output" =~ "\`c5\` int" ]] || false
|
||||
|
||||
run dolt ls
|
||||
[ "$status" -eq 0 ]
|
||||
@@ -76,13 +76,13 @@ teardown() {
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 10 ]
|
||||
[[ "${lines[0]}" =~ "test" ]] || false
|
||||
[[ "$output" =~ "\`pk\` INT" ]] || false
|
||||
[[ "$output" =~ "\`int\` INT" ]] || false
|
||||
[[ "$output" =~ "\`string\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`boolean\` BIT(1)" ]] || false
|
||||
[[ "$output" =~ "\`float\` FLOAT" ]] || false
|
||||
[[ "$output" =~ "\`uint\` INT UNSIGNED" ]] || false
|
||||
[[ "$output" =~ "\`uuid\` CHAR(36) CHARACTER SET ascii COLLATE ascii_bin" ]] || false
|
||||
[[ "$output" =~ "\`pk\` int" ]] || false
|
||||
[[ "$output" =~ "\`int\` int" ]] || false
|
||||
[[ "$output" =~ "\`string\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`boolean\` bit(1)" ]] || false
|
||||
[[ "$output" =~ "\`float\` float" ]] || false
|
||||
[[ "$output" =~ "\`uint\` int unsigned" ]] || false
|
||||
[[ "$output" =~ "\`uuid\` char(36) character set ascii collate ascii_bin" ]] || false
|
||||
}
|
||||
|
||||
@test "schema import with an empty csv" {
|
||||
@@ -166,9 +166,9 @@ DELIM
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 7 ]
|
||||
[[ "${lines[0]}" =~ "test" ]] || false
|
||||
[[ "$output" =~ "\`pk\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`headerOne\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`headerTwo\` INT" ]] || false
|
||||
[[ "$output" =~ "\`pk\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`headerOne\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`headerTwo\` int" ]] || false
|
||||
}
|
||||
|
||||
@test "schema import --keep-types" {
|
||||
@@ -186,13 +186,13 @@ DELIM
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 11 ]
|
||||
[[ "${lines[0]}" =~ "test" ]] || false
|
||||
[[ "$output" =~ "\`pk\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c1\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c2\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c3\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c4\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c5\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c6\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`pk\` int" ]] || false
|
||||
[[ "$output" =~ "\`c1\` int" ]] || false
|
||||
[[ "$output" =~ "\`c2\` int" ]] || false
|
||||
[[ "$output" =~ "\`c3\` int" ]] || false
|
||||
[[ "$output" =~ "\`c4\` int" ]] || false
|
||||
[[ "$output" =~ "\`c5\` int" ]] || false
|
||||
[[ "$output" =~ "\`c6\` longtext" ]] || false
|
||||
[[ "$output" =~ "PRIMARY KEY (\`pk\`)" ]] || false
|
||||
}
|
||||
|
||||
@@ -207,13 +207,13 @@ DELIM
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 11 ]
|
||||
[[ "${lines[0]}" =~ "test" ]] || false
|
||||
[[ "$output" =~ "\`pk\` INT" ]] || false
|
||||
[[ "$output" =~ "\`c1\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`c2\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`c3\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`c4\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`c5\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`c6\` LONGTEXT" ]] || false
|
||||
[[ "$output" =~ "\`pk\` int" ]] || false
|
||||
[[ "$output" =~ "\`c1\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`c2\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`c3\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`c4\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`c5\` longtext" ]] || false
|
||||
[[ "$output" =~ "\`c6\` longtext" ]] || false
|
||||
[[ "$output" =~ "PRIMARY KEY (\`pk\`)" ]] || false
|
||||
}
|
||||
|
||||
@@ -227,7 +227,7 @@ DELIM
|
||||
run dolt schema import -c --pks=pk test 1pk-datetime.csv
|
||||
[ "$status" -eq 0 ]
|
||||
[ "${#lines[@]}" -eq 6 ]
|
||||
[[ "$output" =~ "DATETIME" ]] || false;
|
||||
[[ "$output" =~ "datetime" ]] || false;
|
||||
}
|
||||
|
||||
@test "schema import uses specific date/time types" {
|
||||
@@ -238,10 +238,10 @@ pk, c_date, c_time, c_datetime, c_date+time
|
||||
DELIM
|
||||
run dolt schema import -c --pks=pk test chrono.csv
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "\`c_date\` DATE" ]] || false
|
||||
[[ "$output" =~ "\`c_time\` TIME" ]] || false
|
||||
[[ "$output" =~ "\`c_datetime\` DATETIME" ]] || false
|
||||
[[ "$output" =~ "\`c_date+time\` DATETIME" ]] || false
|
||||
[[ "$output" =~ "\`c_date\` date" ]] || false
|
||||
[[ "$output" =~ "\`c_time\` time" ]] || false
|
||||
[[ "$output" =~ "\`c_datetime\` datetime" ]] || false
|
||||
[[ "$output" =~ "\`c_date+time\` datetime" ]] || false
|
||||
}
|
||||
|
||||
@test "schema import of two tables" {
|
||||
@@ -319,7 +319,7 @@ DELIM
|
||||
JSON
|
||||
run dolt schema import -c -pks=pk -m=name-map.json test abc.csv
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "\`pk\` INT" ]] || false
|
||||
[[ "$output" =~ "\`pk\` int" ]] || false
|
||||
[[ "$output" =~ "\`aa\`" ]] || false
|
||||
[[ "$output" =~ "\`bb\`" ]] || false
|
||||
[[ "$output" =~ "\`cc\`" ]] || false
|
||||
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/row"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/rowconv"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/sqlfmt"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table/pipeline"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table/untyped"
|
||||
@@ -538,7 +539,13 @@ func sqlSchemaDiff(ctx context.Context, td diff.TableDelta, toSchemas map[string
|
||||
if td.IsDrop() {
|
||||
cli.Println(sqlfmt.DropTableStmt(td.FromName))
|
||||
} else if td.IsAdd() {
|
||||
cli.Println(sqlfmt.CreateTableStmt(td.ToName, toSch, td.ToFks, nil))
|
||||
sqlDb := sqle.NewSingleTableDatabase(td.ToName, toSch, td.ToFks, td.ToFksParentSch)
|
||||
sqlCtx, engine, _ := sqle.PrepareCreateTableStmt(ctx, sqlDb)
|
||||
stmt, err := sqle.GetCreateTableStmt(sqlCtx, engine, td.ToName)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
cli.Println(stmt)
|
||||
} else {
|
||||
if td.FromName != td.ToName {
|
||||
cli.Println(sqlfmt.RenameTableStmt(td.FromName, td.ToName))
|
||||
|
||||
@@ -140,7 +140,7 @@ func exportSchemas(ctx context.Context, apr *argparser.ArgParseResults, root *do
|
||||
}
|
||||
|
||||
func exportTblSchema(ctx context.Context, tblName string, root *doltdb.RootValue, wr io.Writer) errhand.VerboseError {
|
||||
sqlCtx, engine, _ := dsqle.PrepareCreateTableStmt(ctx, root)
|
||||
sqlCtx, engine, _ := dsqle.PrepareCreateTableStmt(ctx, dsqle.NewUserSpaceDatabase(root))
|
||||
stmt, err := dsqle.GetCreateTableStmt(sqlCtx, engine, tblName)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/rowconv"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/encoding"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/sqlfmt"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/table/untyped/csv"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/utils/argparser"
|
||||
@@ -286,7 +286,13 @@ func importSchema(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPars
|
||||
|
||||
tblName := impArgs.tableName
|
||||
// inferred schemas have no foreign keys
|
||||
cli.Println(sqlfmt.CreateTableStmt(tblName, sch, nil, nil))
|
||||
sqlDb := sqle.NewSingleTableDatabase(tblName, sch, nil, nil)
|
||||
sqlCtx, engine, _ := sqle.PrepareCreateTableStmt(ctx, sqlDb)
|
||||
stmt, err := sqle.GetCreateTableStmt(sqlCtx, engine, tblName)
|
||||
if err != nil {
|
||||
return errhand.VerboseErrorFromError(err)
|
||||
}
|
||||
cli.Println(stmt)
|
||||
|
||||
if !apr.Contains(dryRunFlag) {
|
||||
tbl, tblExists, err := root.GetTable(ctx, tblName)
|
||||
|
||||
@@ -133,7 +133,7 @@ func printSchemas(ctx context.Context, apr *argparser.ArgParseResults, dEnv *env
|
||||
}
|
||||
}
|
||||
|
||||
sqlCtx, engine, _ := dsqle.PrepareCreateTableStmt(ctx, root)
|
||||
sqlCtx, engine, _ := dsqle.PrepareCreateTableStmt(ctx, dsqle.NewUserSpaceDatabase(root))
|
||||
|
||||
var notFound []string
|
||||
for _, tblName := range tables {
|
||||
|
||||
@@ -174,12 +174,13 @@ func GetDocDiffs(ctx context.Context, dEnv *env.DoltEnv) (*DocDiffs, *DocDiffs,
|
||||
// FromFKs and ToFKs contain Foreign Keys that constrain columns in this table,
|
||||
// they do not contain Foreign Keys that reference this table.
|
||||
type TableDelta struct {
|
||||
FromName string
|
||||
ToName string
|
||||
FromTable *doltdb.Table
|
||||
ToTable *doltdb.Table
|
||||
FromFks []doltdb.ForeignKey
|
||||
ToFks []doltdb.ForeignKey
|
||||
FromName string
|
||||
ToName string
|
||||
FromTable *doltdb.Table
|
||||
ToTable *doltdb.Table
|
||||
FromFks []doltdb.ForeignKey
|
||||
ToFks []doltdb.ForeignKey
|
||||
ToFksParentSch map[string]schema.Schema
|
||||
}
|
||||
|
||||
// GetTableDeltas returns a slice of TableDelta objects for each table that changed between fromRoot and toRoot.
|
||||
@@ -224,27 +225,44 @@ func GetTableDeltas(ctx context.Context, fromRoot, toRoot *doltdb.RootValue) (de
|
||||
}
|
||||
|
||||
toFKs, _ := toFKC.KeysForTable(name)
|
||||
toFksParentSch := make(map[string]schema.Schema)
|
||||
for _, toFk := range toFKs {
|
||||
toRefTable, _, ok, err := toRoot.GetTableInsensitive(ctx, toFk.ReferencedTableName)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if !ok {
|
||||
continue // as the schemas are for display-only, we can skip on any missing parents (they were deleted, etc.)
|
||||
}
|
||||
toRefSch, err := toRefTable.GetSchema(ctx)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
toFksParentSch[toFk.ReferencedTableName] = toRefSch
|
||||
}
|
||||
|
||||
pkTag := sch.GetPKCols().GetColumns()[0].Tag
|
||||
oldName, ok := fromTableNames[pkTag]
|
||||
|
||||
if !ok {
|
||||
deltas = append(deltas, TableDelta{
|
||||
ToName: name,
|
||||
ToTable: table,
|
||||
ToFks: toFKs,
|
||||
ToName: name,
|
||||
ToTable: table,
|
||||
ToFks: toFKs,
|
||||
ToFksParentSch: toFksParentSch,
|
||||
})
|
||||
} else if oldName != name ||
|
||||
fromTableHashes[pkTag] != th ||
|
||||
!fkSlicesAreEqual(fromTableFKs[pkTag], toFKs) {
|
||||
|
||||
deltas = append(deltas, TableDelta{
|
||||
FromName: fromTableNames[pkTag],
|
||||
ToName: name,
|
||||
FromTable: fromTables[pkTag],
|
||||
ToTable: table,
|
||||
FromFks: fromTableFKs[pkTag],
|
||||
ToFks: toFKs,
|
||||
FromName: fromTableNames[pkTag],
|
||||
ToName: name,
|
||||
FromTable: fromTables[pkTag],
|
||||
ToTable: table,
|
||||
FromFks: fromTableFKs[pkTag],
|
||||
ToFks: toFKs,
|
||||
ToFksParentSch: toFksParentSch,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -20,20 +20,17 @@ import (
|
||||
|
||||
sqle "github.com/liquidata-inc/go-mysql-server"
|
||||
"github.com/liquidata-inc/go-mysql-server/sql"
|
||||
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/doltdb"
|
||||
)
|
||||
|
||||
// These functions cannot be in the sqlfmt package as the reliance on the sqle package creates a circular reference.
|
||||
|
||||
func PrepareCreateTableStmt(ctx context.Context, root *doltdb.RootValue) (*sql.Context, *sqle.Engine, *DoltSession) {
|
||||
func PrepareCreateTableStmt(ctx context.Context, sqlDb sql.Database) (*sql.Context, *sqle.Engine, *DoltSession) {
|
||||
dsess := DefaultDoltSession()
|
||||
sqlCtx := sql.NewContext(ctx,
|
||||
sql.WithSession(dsess),
|
||||
sql.WithIndexRegistry(sql.NewIndexRegistry()),
|
||||
sql.WithViewRegistry(sql.NewViewRegistry()))
|
||||
engine := sqle.NewDefault()
|
||||
sqlDb := &UserSpaceDatabase{RootValue: root}
|
||||
engine.AddDatabase(sqlDb)
|
||||
dsess.SetCurrentDatabase(sqlDb.Name())
|
||||
return sqlCtx, engine, dsess
|
||||
|
||||
142
go/libraries/doltcore/sqle/single_table_info_db.go
Normal file
142
go/libraries/doltcore/sqle/single_table_info_db.go
Normal file
@@ -0,0 +1,142 @@
|
||||
// Copyright 2020 Liquidata, 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 sqle
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/liquidata-inc/go-mysql-server/sql"
|
||||
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema"
|
||||
sqleSchema "github.com/liquidata-inc/dolt/go/libraries/doltcore/sqle/schema"
|
||||
"github.com/liquidata-inc/dolt/go/store/types"
|
||||
)
|
||||
|
||||
// SingleTableInfoDatabase is intended to allow a sole schema to make use of any display functionality in `go-mysql-server`.
|
||||
// For example, you may have constructed a schema that you want a CREATE TABLE statement for, but the schema is not
|
||||
// persisted or is temporary. This allows `go-mysql-server` to interact with that sole schema as though it were a database.
|
||||
// No write operations will work with this database.
|
||||
type SingleTableInfoDatabase struct {
|
||||
tableName string
|
||||
sch schema.Schema
|
||||
foreignKeys []doltdb.ForeignKey
|
||||
parentSchs map[string]schema.Schema
|
||||
}
|
||||
|
||||
var _ sql.Database = (*SingleTableInfoDatabase)(nil)
|
||||
var _ sql.Table = (*SingleTableInfoDatabase)(nil)
|
||||
var _ sql.IndexedTable = (*SingleTableInfoDatabase)(nil)
|
||||
var _ sql.ForeignKeyTable = (*SingleTableInfoDatabase)(nil)
|
||||
|
||||
func NewSingleTableDatabase(tableName string, sch schema.Schema, foreignKeys []doltdb.ForeignKey, parentSchs map[string]schema.Schema) *SingleTableInfoDatabase {
|
||||
return &SingleTableInfoDatabase{
|
||||
tableName: tableName,
|
||||
sch: sch,
|
||||
foreignKeys: foreignKeys,
|
||||
parentSchs: parentSchs,
|
||||
}
|
||||
}
|
||||
|
||||
// Name implements sql.Table and sql.Database.
|
||||
func (db *SingleTableInfoDatabase) Name() string {
|
||||
return db.tableName
|
||||
}
|
||||
|
||||
// GetTableInsensitive implements sql.Database.
|
||||
func (db *SingleTableInfoDatabase) GetTableInsensitive(ctx *sql.Context, tableName string) (sql.Table, bool, error) {
|
||||
if strings.ToLower(tableName) == strings.ToLower(db.tableName) {
|
||||
return db, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// GetTableNames implements sql.Database.
|
||||
func (db *SingleTableInfoDatabase) GetTableNames(ctx *sql.Context) ([]string, error) {
|
||||
return []string{db.tableName}, nil
|
||||
}
|
||||
|
||||
// String implements sql.Table.
|
||||
func (db *SingleTableInfoDatabase) String() string {
|
||||
return db.tableName
|
||||
}
|
||||
|
||||
// Schema implements sql.Table.
|
||||
func (db *SingleTableInfoDatabase) Schema() sql.Schema {
|
||||
sqlSch, err := sqleSchema.FromDoltSchema(db.tableName, db.sch)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return sqlSch
|
||||
}
|
||||
|
||||
// Partitions implements sql.Table.
|
||||
func (db *SingleTableInfoDatabase) Partitions(*sql.Context) (sql.PartitionIter, error) {
|
||||
return nil, fmt.Errorf("cannot get paritions of a single table information database")
|
||||
}
|
||||
|
||||
// PartitionRows implements sql.Table.
|
||||
func (db *SingleTableInfoDatabase) PartitionRows(*sql.Context, sql.Partition) (sql.RowIter, error) {
|
||||
return nil, fmt.Errorf("cannot get parition rows of a single table information database")
|
||||
}
|
||||
|
||||
// GetForeignKeys implements sql.ForeignKeyTable.
|
||||
func (db *SingleTableInfoDatabase) GetForeignKeys(ctx *sql.Context) ([]sql.ForeignKeyConstraint, error) {
|
||||
fks := make([]sql.ForeignKeyConstraint, len(db.foreignKeys))
|
||||
for i, fk := range db.foreignKeys {
|
||||
if parentSch, ok := db.parentSchs[fk.ReferencedTableName]; ok {
|
||||
var err error
|
||||
fks[i], err = toForeignKeyConstraint(fk, db.sch, parentSch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// We can skip here since the given schema may be purposefully incomplete (such as with diffs).
|
||||
continue
|
||||
}
|
||||
}
|
||||
return fks, nil
|
||||
}
|
||||
|
||||
// WithIndexLookup implements sql.IndexedTable.
|
||||
func (db *SingleTableInfoDatabase) WithIndexLookup(sql.IndexLookup) sql.Table {
|
||||
return db
|
||||
}
|
||||
|
||||
// GetIndexes implements sql.IndexedTable.
|
||||
func (db *SingleTableInfoDatabase) GetIndexes(ctx *sql.Context) ([]sql.Index, error) {
|
||||
var sqlIndexes []sql.Index
|
||||
for _, index := range db.sch.Indexes().AllIndexes() {
|
||||
cols := make([]schema.Column, index.Count())
|
||||
for i, tag := range index.IndexedColumnTags() {
|
||||
cols[i], _ = index.GetColumn(tag)
|
||||
}
|
||||
sqlIndexes = append(sqlIndexes, &doltIndex{
|
||||
cols: cols,
|
||||
db: db,
|
||||
id: index.Name(),
|
||||
indexRowData: types.EmptyMap,
|
||||
indexSch: index.Schema(),
|
||||
table: nil,
|
||||
tableData: types.EmptyMap,
|
||||
tableName: db.tableName,
|
||||
tableSch: db.sch,
|
||||
unique: index.IsUnique(),
|
||||
comment: index.Comment(),
|
||||
})
|
||||
}
|
||||
return sqlIndexes, nil
|
||||
}
|
||||
@@ -25,21 +25,9 @@ import (
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/row"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/schema/typeinfo"
|
||||
"github.com/liquidata-inc/dolt/go/libraries/doltcore/sql/sqltestutil"
|
||||
"github.com/liquidata-inc/dolt/go/store/types"
|
||||
)
|
||||
|
||||
const expectedCreateSQL = "CREATE TABLE `table_name` (\n" +
|
||||
" `id` BIGINT NOT NULL,\n" +
|
||||
" `first_name` LONGTEXT NOT NULL,\n" +
|
||||
" `last_name` LONGTEXT NOT NULL,\n" +
|
||||
" `is_married` BIT(1),\n" +
|
||||
" `age` BIGINT,\n" +
|
||||
" `rating` DOUBLE,\n" +
|
||||
" `uuid` CHAR(36) CHARACTER SET ascii COLLATE ascii_bin,\n" +
|
||||
" `num_episodes` BIGINT UNSIGNED,\n" +
|
||||
" PRIMARY KEY (`id`)\n" +
|
||||
");"
|
||||
const expectedDropSql = "DROP TABLE `table_name`;"
|
||||
const expectedDropIfExistsSql = "DROP TABLE IF EXISTS `table_name`;"
|
||||
const expectedAddColSql = "ALTER TABLE `table_name` ADD `c0` BIGINT NOT NULL;"
|
||||
@@ -54,13 +42,6 @@ type test struct {
|
||||
expectedOutput string
|
||||
}
|
||||
|
||||
func TestSchemaAsCreateStmt(t *testing.T) {
|
||||
tSchema := sqltestutil.PeopleTestSchema
|
||||
stmt := CreateTableStmt("table_name", tSchema, nil, nil)
|
||||
|
||||
assert.Equal(t, expectedCreateSQL, stmt)
|
||||
}
|
||||
|
||||
func TestTableDropStmt(t *testing.T) {
|
||||
stmt := DropTableStmt("table_name")
|
||||
|
||||
|
||||
@@ -121,63 +121,6 @@ func FmtForeignKey(fk doltdb.ForeignKey, sch, parentSch schema.Schema) string {
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// CreateTableStmtWithTags generates a SQL CREATE TABLE command
|
||||
func CreateTableStmt(tableName string, sch schema.Schema, foreignKeys []doltdb.ForeignKey, parentSchs map[string]schema.Schema) string {
|
||||
return createTableStmt(tableName, sch, func(col schema.Column) string {
|
||||
return FmtCol(2, 0, 0, col)
|
||||
}, foreignKeys, parentSchs)
|
||||
}
|
||||
|
||||
type fmtColFunc func(col schema.Column) string
|
||||
|
||||
func createTableStmt(tableName string, sch schema.Schema, fmtCol fmtColFunc, foreignKeys []doltdb.ForeignKey, parentSchs map[string]schema.Schema) string {
|
||||
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString(fmt.Sprintf("CREATE TABLE %s (\n", QuoteIdentifier(tableName)))
|
||||
|
||||
firstLine := true
|
||||
_ = sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
|
||||
if firstLine {
|
||||
firstLine = false
|
||||
} else {
|
||||
sb.WriteString(",\n")
|
||||
}
|
||||
|
||||
s := fmtCol(col)
|
||||
sb.WriteString(s)
|
||||
|
||||
return false, nil
|
||||
})
|
||||
|
||||
firstPK := true
|
||||
_ = sch.GetPKCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) {
|
||||
if firstPK {
|
||||
sb.WriteString(",\n PRIMARY KEY (")
|
||||
firstPK = false
|
||||
} else {
|
||||
sb.WriteRune(',')
|
||||
}
|
||||
sb.WriteString(QuoteIdentifier(col.Name))
|
||||
return false, nil
|
||||
})
|
||||
|
||||
sb.WriteRune(')')
|
||||
|
||||
for _, idx := range sch.Indexes().AllIndexes() {
|
||||
sb.WriteString(",\n ")
|
||||
sb.WriteString(FmtIndex(idx))
|
||||
}
|
||||
|
||||
for _, fk := range foreignKeys {
|
||||
sb.WriteString(",\n ")
|
||||
sb.WriteString(FmtForeignKey(fk, sch, parentSchs[fk.ReferencedTableName]))
|
||||
}
|
||||
|
||||
sb.WriteString("\n);")
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func DropTableStmt(tableName string) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("DROP TABLE ")
|
||||
|
||||
@@ -27,6 +27,10 @@ type UserSpaceDatabase struct {
|
||||
|
||||
var _ SqlDatabase = (*UserSpaceDatabase)(nil)
|
||||
|
||||
func NewUserSpaceDatabase(root *doltdb.RootValue) *UserSpaceDatabase {
|
||||
return &UserSpaceDatabase{RootValue: root}
|
||||
}
|
||||
|
||||
func (db *UserSpaceDatabase) Name() string {
|
||||
return "dolt"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func (w *SqlExportWriter) maybeWriteDropCreate(ctx context.Context) error {
|
||||
var b strings.Builder
|
||||
b.WriteString(sqlfmt.DropTableIfExistsStmt(w.tableName))
|
||||
b.WriteRune('\n')
|
||||
sqlCtx, engine, _ := dsqle.PrepareCreateTableStmt(ctx, w.root)
|
||||
sqlCtx, engine, _ := dsqle.PrepareCreateTableStmt(ctx, dsqle.NewUserSpaceDatabase(w.root))
|
||||
createTableStmt, err := dsqle.GetCreateTableStmt(sqlCtx, engine, w.tableName)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user