fixes for changes on info_schema tables (#5074)

This commit is contained in:
jennifersp
2023-01-13 11:31:22 -08:00
committed by GitHub
parent 7989e5ef13
commit fe9d51f2c1
16 changed files with 124 additions and 105 deletions

View File

@@ -58,7 +58,7 @@ require (
github.com/cenkalti/backoff/v4 v4.1.3
github.com/cespare/xxhash v1.1.0
github.com/creasty/defaults v1.6.0
github.com/dolthub/go-mysql-server v0.14.1-0.20230112120305-8fb0ede68a8d
github.com/dolthub/go-mysql-server v0.14.1-0.20230113174939-020f13f24a03
github.com/google/flatbuffers v2.0.6+incompatible
github.com/kch42/buzhash v0.0.0-20160816060738-9bdec3dec7c6
github.com/mitchellh/go-ps v1.0.0

View File

@@ -161,8 +161,8 @@ github.com/dolthub/flatbuffers v1.13.0-dh.1 h1:OWJdaPep22N52O/0xsUevxJ6Qfw1M2txC
github.com/dolthub/flatbuffers v1.13.0-dh.1/go.mod h1:CorYGaDmXjHz1Z7i50PYXG1Ricn31GcA2wNOTFIQAKE=
github.com/dolthub/fslock v0.0.3 h1:iLMpUIvJKMKm92+N1fmHVdxJP5NdyDK5bK7z7Ba2s2U=
github.com/dolthub/fslock v0.0.3/go.mod h1:QWql+P17oAAMLnL4HGB5tiovtDuAjdDTPbuqx7bYfa0=
github.com/dolthub/go-mysql-server v0.14.1-0.20230112120305-8fb0ede68a8d h1:/ESsatXy+1nZZQmq8zow6hDnbSzPfvgAoBCcyQDVHc8=
github.com/dolthub/go-mysql-server v0.14.1-0.20230112120305-8fb0ede68a8d/go.mod h1:ykkkC0nmCN0Dd7bpm+AeM6w4jcxfV9vIfLQEmajj20I=
github.com/dolthub/go-mysql-server v0.14.1-0.20230113174939-020f13f24a03 h1:H4U928DxGBK1YsngCOnix7EkKKVf6MTD3+C2RP2tfoo=
github.com/dolthub/go-mysql-server v0.14.1-0.20230113174939-020f13f24a03/go.mod h1:ykkkC0nmCN0Dd7bpm+AeM6w4jcxfV9vIfLQEmajj20I=
github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514=
github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488/go.mod h1:ehexgi1mPxRTk0Mok/pADALuHbvATulTh6gzr7NzZto=
github.com/dolthub/jsonpath v0.0.0-20210609232853-d49537a30474 h1:xTrR+l5l+1Lfq0NvhiEsctylXinUMFhhsqaEcl414p8=

View File

@@ -24,6 +24,8 @@ import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/mysql_db"
"github.com/dolthub/go-mysql-server/sql/parse"
"github.com/dolthub/go-mysql-server/sql/plan"
"gopkg.in/src-d/go-errors.v1"
"github.com/dolthub/dolt/go/libraries/doltcore/branch_control"
@@ -1061,11 +1063,11 @@ func (db Database) Flush(ctx *sql.Context) error {
return db.SetRoot(ctx, ws.WorkingRoot())
}
// GetView implements sql.ViewDatabase
func (db Database) GetView(ctx *sql.Context, viewName string) (string, bool, error) {
// GetViewDefinition implements sql.ViewDatabase
func (db Database) GetViewDefinition(ctx *sql.Context, viewName string) (sql.ViewDefinition, bool, error) {
root, err := db.GetRoot(ctx)
if err != nil {
return "", false, err
return sql.ViewDefinition{}, false, err
}
lwrViewName := strings.ToLower(viewName)
@@ -1073,62 +1075,79 @@ func (db Database) GetView(ctx *sql.Context, viewName string) (string, bool, err
case strings.HasPrefix(lwrViewName, doltdb.DoltBlameViewPrefix):
tableName := lwrViewName[len(doltdb.DoltBlameViewPrefix):]
view, err := dtables.NewBlameView(ctx, tableName, root)
blameViewTextDef, err := dtables.NewBlameView(ctx, tableName, root)
if err != nil {
return "", false, err
return sql.ViewDefinition{}, false, err
}
return view, true, nil
return sql.ViewDefinition{Name: viewName, TextDefinition: blameViewTextDef, CreateViewStatement: fmt.Sprintf("CREATE VIEW %s AS %s", viewName, blameViewTextDef)}, true, nil
}
key, err := doltdb.NewDataCacheKey(root)
if err != nil {
return "", false, err
return sql.ViewDefinition{}, false, err
}
ds := dsess.DSessFromSess(ctx.Session)
dbState, _, err := ds.LookupDbState(ctx, db.name)
if err != nil {
return "", false, err
return sql.ViewDefinition{}, false, err
}
if dbState.SessionCache().ViewsCached(key) {
view, ok := dbState.SessionCache().GetCachedView(key, viewName)
view, ok := dbState.SessionCache().GetCachedViewDefinition(key, viewName)
return view, ok, nil
}
tbl, ok, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName)
if err != nil {
return "", false, err
return sql.ViewDefinition{}, false, err
}
if !ok {
dbState.SessionCache().CacheViews(key, nil, nil)
return "", false, nil
dbState.SessionCache().CacheViews(key, nil)
return sql.ViewDefinition{}, false, nil
}
fragments, err := getSchemaFragmentsOfType(ctx, tbl.(*WritableDoltTable), viewFragment)
views, viewDef, found, err := getViewDefinitionFromSchemaFragmentsOfView(ctx, tbl.(*WritableDoltTable), viewName)
if err != nil {
return "", false, err
return sql.ViewDefinition{}, false, err
}
found := false
viewDef := ""
viewNames := make([]string, len(fragments))
viewDefs := make([]string, len(fragments))
for i, fragment := range fragments {
if strings.ToLower(fragment.name) == strings.ToLower(viewName) {
found = true
viewDef = fragments[i].fragment
}
viewNames[i] = fragments[i].name
viewDefs[i] = fragments[i].fragment
}
dbState.SessionCache().CacheViews(key, viewNames, viewDefs)
dbState.SessionCache().CacheViews(key, views)
return viewDef, found, nil
}
func getViewDefinitionFromSchemaFragmentsOfView(ctx *sql.Context, tbl *WritableDoltTable, viewName string) ([]sql.ViewDefinition, sql.ViewDefinition, bool, error) {
fragments, err := getSchemaFragmentsOfType(ctx, tbl, viewFragment)
if err != nil {
return nil, sql.ViewDefinition{}, false, err
}
var found = false
var viewDef sql.ViewDefinition
var views = make([]sql.ViewDefinition, len(fragments))
for i, fragment := range fragments {
cv, err := parse.Parse(ctx, fragments[i].fragment)
if err != nil {
return nil, sql.ViewDefinition{}, false, err
}
createView, ok := cv.(*plan.CreateView)
if ok {
views[i] = sql.ViewDefinition{Name: fragments[i].name, TextDefinition: createView.Definition.TextDefinition, CreateViewStatement: fragments[i].fragment}
} else {
views[i] = sql.ViewDefinition{Name: fragments[i].name, TextDefinition: fragments[i].fragment, CreateViewStatement: fmt.Sprintf("CREATE VIEW %s AS %s", fragments[i].name, fragments[i].fragment)}
}
if strings.ToLower(fragment.name) == strings.ToLower(viewName) {
found = true
viewDef = views[i]
}
}
return views, viewDef, found, nil
}
// AllViews implements sql.ViewDatabase
func (db Database) AllViews(ctx *sql.Context) ([]sql.ViewDefinition, error) {
tbl, ok, err := db.GetTableInsensitive(ctx, doltdb.SchemasTableName)
@@ -1139,18 +1158,7 @@ func (db Database) AllViews(ctx *sql.Context) ([]sql.ViewDefinition, error) {
return nil, nil
}
frags, err := getSchemaFragmentsOfType(ctx, tbl.(*WritableDoltTable), viewFragment)
if err != nil {
return nil, err
}
var views []sql.ViewDefinition
for _, frag := range frags {
views = append(views, sql.ViewDefinition{
Name: frag.name,
TextDefinition: frag.fragment,
})
}
views, _, _, err := getViewDefinitionFromSchemaFragmentsOfView(ctx, tbl.(*WritableDoltTable), "")
if err != nil {
return nil, err
}
@@ -1161,9 +1169,9 @@ func (db Database) AllViews(ctx *sql.Context) ([]sql.ViewDefinition, error) {
// CreateView implements sql.ViewCreator. Persists the view in the dolt database, so
// it can exist in a sql session later. Returns sql.ErrExistingView if a view
// with that name already exists.
func (db Database) CreateView(ctx *sql.Context, name string, definition string) error {
func (db Database) CreateView(ctx *sql.Context, name string, selectStatement, createViewStmt string) error {
err := sql.ErrExistingView.New(db.name, name)
return db.addFragToSchemasTable(ctx, "view", name, definition, time.Unix(0, 0).UTC(), err)
return db.addFragToSchemasTable(ctx, "view", name, createViewStmt, time.Unix(0, 0).UTC(), err)
}
// DropView implements sql.ViewDropper. Removes a view from persistence in the

View File

@@ -28,7 +28,7 @@ import (
type SessionCache struct {
indexes map[doltdb.DataCacheKey]map[string][]sql.Index
tables map[doltdb.DataCacheKey]map[string]sql.Table
views map[doltdb.DataCacheKey]map[string]string
views map[doltdb.DataCacheKey]map[string]sql.ViewDefinition
mu sync.RWMutex
}
@@ -125,23 +125,23 @@ func (c *SessionCache) GetCachedTable(key doltdb.DataCacheKey, tableName string)
}
// CacheViews caches all views in a database for the cache key given
func (c *SessionCache) CacheViews(key doltdb.DataCacheKey, viewNames []string, viewDefs []string) {
func (c *SessionCache) CacheViews(key doltdb.DataCacheKey, views []sql.ViewDefinition) {
c.mu.Lock()
defer c.mu.Unlock()
if c.views == nil {
c.views = make(map[doltdb.DataCacheKey]map[string]string)
c.views = make(map[doltdb.DataCacheKey]map[string]sql.ViewDefinition)
}
viewsForKey, ok := c.views[key]
if !ok {
viewsForKey = make(map[string]string)
viewsForKey = make(map[string]sql.ViewDefinition)
c.views[key] = viewsForKey
}
for i := range viewNames {
viewName := strings.ToLower(viewNames[i])
viewsForKey[viewName] = viewDefs[i]
for i := range views {
viewName := strings.ToLower(views[i].Name)
viewsForKey[viewName] = views[i]
}
}
@@ -158,19 +158,19 @@ func (c *SessionCache) ViewsCached(key doltdb.DataCacheKey) bool {
return ok
}
// GetCachedView returns the cached view named, and whether the cache was present
func (c *SessionCache) GetCachedView(key doltdb.DataCacheKey, viewName string) (string, bool) {
// GetCachedViewDefinition returns the cached view named, and whether the cache was present
func (c *SessionCache) GetCachedViewDefinition(key doltdb.DataCacheKey, viewName string) (sql.ViewDefinition, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
viewName = strings.ToLower(viewName)
if c.views == nil {
return "", false
return sql.ViewDefinition{}, false
}
viewsForKey, ok := c.views[key]
if !ok {
return "", false
return sql.ViewDefinition{}, false
}
table, ok := viewsForKey[viewName]

View File

@@ -745,8 +745,8 @@ var DoltScripts = []queries.ScriptTest{
{
Query: "SELECT type, name, fragment, id FROM dolt_schemas ORDER BY 1, 2",
Expected: []sql.Row{
{"view", "view1", "SELECT v1 FROM viewtest", int64(1)},
{"view", "view2", "SELECT v2 FROM viewtest", int64(2)},
{"view", "view1", "CREATE VIEW view1 AS SELECT v1 FROM viewtest", int64(1)},
{"view", "view2", "CREATE VIEW view2 AS SELECT v2 FROM viewtest", int64(2)},
},
},
},

View File

@@ -814,7 +814,7 @@ func TestAlterSystemTables(t *testing.T) {
CreateTestTable(t, dEnv, doltdb.DoltQueryCatalogTableName, dtables.DoltQueryCatalogSchema,
"INSERT INTO dolt_query_catalog VALUES ('abc123', 1, 'example', 'select 2+2 from dual', 'description')")
CreateTestTable(t, dEnv, doltdb.SchemasTableName, SchemasTableSchema(),
"INSERT INTO dolt_schemas (type, name, fragment, id) VALUES ('view', 'name', 'select 2+2 from dual', 1)")
"INSERT INTO dolt_schemas (type, name, fragment, id) VALUES ('view', 'name', 'create view name as select 2+2 from dual', 1)")
}
t.Run("Create", func(t *testing.T) {

View File

@@ -199,7 +199,7 @@ var systemTableDeleteTests = []DeleteTest{
{
Name: "delete dolt_query_catalog",
AdditionalSetup: CreateTableFn(doltdb.DoltQueryCatalogTableName, dtables.DoltQueryCatalogSchema,
"INSERT INTO dolt_query_catalog VALUES ('abc123', 1, 'example', 'select 2+2 from dual', 'description')"),
"INSERT INTO dolt_query_catalog VALUES ('abc123', 1, 'example', 'create view example as select 2+2 from dual', 'description')"),
DeleteQuery: "delete from dolt_query_catalog",
SelectQuery: "select * from dolt_query_catalog",
ExpectedRows: ToSqlRows(dtables.DoltQueryCatalogSchema),
@@ -208,7 +208,7 @@ var systemTableDeleteTests = []DeleteTest{
{
Name: "delete dolt_schemas",
AdditionalSetup: CreateTableFn(doltdb.SchemasTableName, SchemasTableSchema(),
"INSERT INTO dolt_schemas (type, name, fragment, id) VALUES ('view', 'name', 'select 2+2 from dual', 1)"),
"INSERT INTO dolt_schemas (type, name, fragment, id) VALUES ('view', 'name', 'create view name as select 2+2 from dual', 1)"),
DeleteQuery: "delete from dolt_schemas",
SelectQuery: "select * from dolt_schemas",
ExpectedRows: ToSqlRows(dtables.DoltQueryCatalogSchema),

View File

@@ -272,30 +272,33 @@ func SqlRowAsCreateProcStmt(r sql.Row) (string, error) {
func SqlRowAsCreateFragStmt(r sql.Row) (string, error) {
var b strings.Builder
// Write create
b.WriteString("CREATE ")
// Write type
// If type is view, add DROP VIEW IF EXISTS statement before CREATE VIEW STATEMENT
typeStr := strings.ToUpper(r[0].(string))
b.WriteString(typeStr)
b.WriteString(" ") // add a space
// Write view/trigger name
nameStr := r[1].(string)
b.WriteString(QuoteIdentifier(nameStr))
b.WriteString(" ") // add a space
if typeStr == "VIEW" {
nameStr := r[1].(string)
dropStmt := fmt.Sprintf("DROP VIEW IF EXISTS `%s`", nameStr)
b.WriteString(dropStmt)
b.WriteString(";\n")
}
// Parse statement to extract definition (and remove any weird whitespace issues)
defStmt, err := sqlparser.Parse(r[2].(string))
if err != nil {
return "", err
}
defStr := sqlparser.String(defStmt)
if typeStr == "TRIGGER" { // triggers need the create trigger <trig_name> to be cut off
defStr = defStr[len("CREATE TRIGGER ")+len(nameStr)+1:]
} else { // views need the prefixed with "AS"
defStr = "AS " + defStr
// TODO: this is temporary fix for create statements
if typeStr == "TRIGGER" {
nameStr := r[1].(string)
defStr = fmt.Sprintf("CREATE TRIGGER `%s` %s", nameStr, defStr[len("CREATE TRIGGER ")+len(nameStr)+1:])
} else {
defStr = strings.Replace(defStr, "create ", "CREATE ", -1)
defStr = strings.Replace(defStr, " view ", " VIEW ", -1)
defStr = strings.Replace(defStr, " as ", " AS ", -1)
}
b.WriteString(defStr)
b.WriteString(";")

View File

@@ -398,10 +398,10 @@ var systemTableInsertTests = []InsertTest{
{
Name: "insert into dolt_schemas",
AdditionalSetup: CreateTableFn(doltdb.SchemasTableName, SchemasTableSchema(), ""),
InsertQuery: "insert into dolt_schemas (id, type, name, fragment) values (1, 'view', 'name', 'select 2+2 from dual')",
InsertQuery: "insert into dolt_schemas (id, type, name, fragment) values (1, 'view', 'name', 'create view name as select 2+2 from dual')",
SelectQuery: "select * from dolt_schemas ORDER BY id",
ExpectedRows: ToSqlRows(CompressSchema(SchemasTableSchema()),
NewRow(types.String("view"), types.String("name"), types.String("select 2+2 from dual"), types.Int(1)),
NewRow(types.String("view"), types.String("name"), types.String("create view name as select 2+2 from dual"), types.Int(1)),
),
ExpectedSchema: CompressSchema(SchemasTableSchema()),
},

View File

@@ -273,10 +273,10 @@ var systemTableReplaceTests = []ReplaceTest{
{
Name: "replace into dolt_schemas",
AdditionalSetup: CreateTableFn(doltdb.SchemasTableName, SchemasTableSchema(),
"INSERT INTO dolt_schemas VALUES ('view', 'name', 'select 2+2 from dual', 1, NULL)"),
ReplaceQuery: "replace into dolt_schemas (id, type, name, fragment) values ('1', 'view', 'name', 'select 1+1 from dual')",
"INSERT INTO dolt_schemas VALUES ('view', 'name', 'create view name as select 2+2 from dual', 1, NULL)"),
ReplaceQuery: "replace into dolt_schemas (id, type, name, fragment) values ('1', 'view', 'name', 'create view name as select 1+1 from dual')",
SelectQuery: "select type, name, fragment, id, extra from dolt_schemas",
ExpectedRows: []sql.Row{{"view", "name", "select 1+1 from dual", int64(1), nil}},
ExpectedRows: []sql.Row{{"view", "name", "create view name as select 1+1 from dual", int64(1), nil}},
ExpectedSchema: CompressSchema(SchemasTableSchema()),
},
}

View File

@@ -1309,9 +1309,9 @@ var systemTableSelectTests = []SelectTest{
{
Name: "select from dolt_schemas",
AdditionalSetup: CreateTableFn(doltdb.SchemasTableName, SchemasTableSchema(),
`INSERT INTO dolt_schemas VALUES ('view', 'name', 'select 2+2 from dual', 1, NULL)`),
`INSERT INTO dolt_schemas VALUES ('view', 'name', 'create view name as select 2+2 from dual', 1, NULL)`),
Query: "select * from dolt_schemas",
ExpectedRows: []sql.Row{{"view", "name", "select 2+2 from dual", int64(1), nil}},
ExpectedRows: []sql.Row{{"view", "name", "create view name as select 2+2 from dual", int64(1), nil}},
ExpectedSchema: CompressSchema(SchemasTableSchema()),
},
}

View File

@@ -378,10 +378,10 @@ var systemTableUpdateTests = []UpdateTest{
{
Name: "update dolt_schemas",
AdditionalSetup: CreateTableFn(doltdb.SchemasTableName, SchemasTableSchema(),
`INSERT INTO dolt_schemas VALUES ('view', 'name', 'select 2+2 from dual', 1, NULL)`),
`INSERT INTO dolt_schemas VALUES ('view', 'name', 'create view name as select 2+2 from dual', 1, NULL)`),
UpdateQuery: "update dolt_schemas set type = 'not a view'",
SelectQuery: "select * from dolt_schemas",
ExpectedRows: []sql.Row{{"not a view", "name", "select 2+2 from dual", int64(1), nil}},
ExpectedRows: []sql.Row{{"not a view", "name", "create view name as select 2+2 from dual", int64(1), nil}},
ExpectedSchema: CompressSchema(SchemasTableSchema()),
},
}

View File

@@ -291,10 +291,10 @@ func (t *DoltTable) HasIndex(ctx *sql.Context, idx sql.Index) (bool, error) {
}
// GetAutoIncrementValue gets the last AUTO_INCREMENT value
func (t *DoltTable) GetAutoIncrementValue(ctx *sql.Context) (interface{}, error) {
func (t *DoltTable) GetAutoIncrementValue(ctx *sql.Context) (uint64, error) {
table, err := t.DoltTable(ctx)
if err != nil {
return nil, err
return 0, err
}
return table.GetAutoIncrementValue(ctx)
}
@@ -746,12 +746,12 @@ func (t *WritableDoltTable) AutoIncrementSetter(ctx *sql.Context) sql.AutoIncrem
}
// PeekNextAutoIncrementValue implements sql.AutoIncrementTable
func (t *WritableDoltTable) PeekNextAutoIncrementValue(ctx *sql.Context) (interface{}, error) {
func (t *WritableDoltTable) PeekNextAutoIncrementValue(ctx *sql.Context) (uint64, error) {
if !t.autoIncCol.AutoIncrement {
return nil, sql.ErrNoAutoIncrementCol
return 0, sql.ErrNoAutoIncrementCol
}
return t.getTableAutoIncrementValue(ctx)
return t.DoltTable.GetAutoIncrementValue(ctx)
}
// GetNextAutoIncrementValue implements sql.AutoIncrementTable
@@ -768,10 +768,6 @@ func (t *WritableDoltTable) GetNextAutoIncrementValue(ctx *sql.Context, potentia
return ed.GetNextAutoIncrementValue(ctx, potentialVal)
}
func (t *WritableDoltTable) getTableAutoIncrementValue(ctx *sql.Context) (interface{}, error) {
return t.DoltTable.GetAutoIncrementValue(ctx)
}
func (t *DoltTable) GetChecks(ctx *sql.Context) ([]sql.CheckDefinition, error) {
table, err := t.DoltTable(ctx)
if err != nil {

View File

@@ -67,8 +67,8 @@ SQL
[ "$status" -eq "0" ]
[[ "$output" =~ "type,name,fragment,id" ]] || false
[[ "$output" =~ "trigger,trigger1,CREATE TRIGGER trigger1 BEFORE INSERT ON test FOR EACH ROW SET new.v1 = -new.v1,1" ]] || false
[[ "$output" =~ "view,view1,SELECT v1 FROM test,2" ]] || false
[[ "$output" =~ "view,view2,SELECT y FROM b,3" ]] || false
[[ "$output" =~ "view,view1,CREATE VIEW view1 AS SELECT v1 FROM test,2" ]] || false
[[ "$output" =~ "view,view2,CREATE VIEW view2 AS SELECT y FROM b,3" ]] || false
[[ "$output" =~ "trigger,trigger2,CREATE TRIGGER trigger2 AFTER INSERT ON a FOR EACH ROW INSERT INTO b VALUES (new.x * 2),4" ]] || false
[[ "${#lines[@]}" = "5" ]] || false
}
@@ -214,8 +214,8 @@ SQL
run dolt sql -q "SELECT * FROM dolt_schemas" -r=csv
[ "$status" -eq "0" ]
[[ "$output" =~ "type,name,fragment,id" ]] || false
[[ "$output" =~ "view,view1,SELECT 2+2 FROM dual,1" ]] || false
[[ "$output" =~ "view,view2,SELECT 3+3 FROM dual,2" ]] || false
[[ "$output" =~ "view,view1,CREATE VIEW view1 AS SELECT 2+2 FROM dual,1" ]] || false
[[ "$output" =~ "view,view2,CREATE VIEW view2 AS SELECT 3+3 FROM dual,2" ]] || false
[[ "${#lines[@]}" = "3" ]] || false
run dolt sql -q "SELECT * FROM view1" -r=csv

View File

@@ -65,7 +65,7 @@ function test_backward_compatibility() {
PATH="`pwd`"/"$bin":"$PATH" setup_repo "$ver"
echo "Run the bats tests with current Dolt version hitting repositories from older Dolt version $ver"
DEFAULT_BRANCH="$DEFAULT_BRANCH" REPO_DIR="`pwd`"/repos/"$ver" bats ./test_files/bats
DEFAULT_BRANCH="$DEFAULT_BRANCH" REPO_DIR="`pwd`"/repos/"$ver" DOLT_VERSION="$ver" bats ./test_files/bats
}
function list_forward_compatible_versions() {

View File

@@ -207,11 +207,23 @@ EOF
}
@test "dolt_schemas" {
run dolt sql -q "select * from dolt_schemas"
[ "$status" -eq 0 ]
[[ "${lines[1]}" =~ "| type | name | fragment |" ]] || false
[[ "${lines[2]}" =~ "+------+-------+----------------------+" ]] || false
[[ "${lines[3]}" =~ "| view | view1 | SELECT 2+2 FROM dual |" ]] || false
dolt_version=$( echo $DOLT_VERSION | sed -e "s/^v//" )
echo $dolt_version
if [[ ! -z $dolt_version ]]; then
run dolt sql -q "select * from dolt_schemas"
[ "$status" -eq 0 ]
[[ "${lines[1]}" =~ "| type | name | fragment |" ]] || false
[[ "${lines[2]}" =~ "+------+-------+----------------------+" ]] || false
[[ "${lines[3]}" =~ "| view | view1 | SELECT 2+2 FROM dual |" ]] || false
else
run dolt sql -q "select * from dolt_schemas"
[ "$status" -eq 0 ]
[[ "${lines[1]}" =~ "| type | name | fragment |" ]] || false
[[ "${lines[2]}" =~ "+------+-------+-------------------------------------------+" ]] || false
[[ "${lines[3]}" =~ "| view | view1 | CREATE VIEW view1 AS SELECT 2+2 FROM dual |" ]] || false
fi
run dolt sql -q 'select * from view1'
[ "$status" -eq 0 ]
[[ "${lines[1]}" =~ "2+2" ]] || false