Skip to content

Commit 5314c7f

Browse files
committed
Add schema name to views for doltgres
1 parent ec0bc7c commit 5314c7f

File tree

4 files changed

+123
-31
lines changed

4 files changed

+123
-31
lines changed

go/libraries/doltcore/doltdb/system_table.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,9 @@ const (
286286
// SchemasTablesSqlModeCol is the name of the column that stores the SQL_MODE string used when this fragment
287287
// was originally defined. Mode settings, such as ANSI_QUOTES, are needed to correctly parse the fragment.
288288
SchemasTablesSqlModeCol = "sql_mode"
289+
// SchemasTablesSchemaNameCol is the name of the column that stores the name of the schema that the fragment
290+
// is part of. Used by Doltgres only.
291+
SchemasTablesSchemaNameCol = "schema_name"
289292
)
290293

291294
const (

go/libraries/doltcore/schema/reserved_tags.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ const (
8080
DoltSchemasFragmentTag
8181
DoltSchemasExtraTag
8282
DoltSchemasSqlModeTag
83+
DoltSchemasSchemaNameTag
8384
)
8485

8586
// Tags for hidden columns in keyless rows

go/libraries/doltcore/sqle/database.go

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,7 @@ func (db Database) GetViewDefinition(ctx *sql.Context, viewName string) (sql.Vie
17581758
}
17591759
}
17601760

1761+
schemaName := db.schemaName
17611762
lwrViewName := strings.ToLower(viewName)
17621763
switch {
17631764
case strings.HasPrefix(lwrViewName, doltdb.DoltBlameViewPrefix):
@@ -1767,7 +1768,12 @@ func (db Database) GetViewDefinition(ctx *sql.Context, viewName string) (sql.Vie
17671768
if err != nil {
17681769
return sql.ViewDefinition{}, false, err
17691770
}
1770-
return sql.ViewDefinition{Name: viewName, TextDefinition: blameViewTextDef, CreateViewStatement: fmt.Sprintf("CREATE VIEW `%s` AS %s", viewName, blameViewTextDef)}, true, nil
1771+
return sql.ViewDefinition{
1772+
Name: viewName,
1773+
SchemaName: db.schemaName,
1774+
TextDefinition: blameViewTextDef,
1775+
CreateViewStatement: fmt.Sprintf("CREATE VIEW `%s` AS %s", viewName, blameViewTextDef)},
1776+
true, nil
17711777
}
17721778

17731779
schemasTableName := getDoltSchemasTableName()
@@ -1809,22 +1815,22 @@ func (db Database) GetViewDefinition(ctx *sql.Context, viewName string) (sql.Vie
18091815
}
18101816

18111817
if wrapper.backingTable == nil {
1812-
dbState.SessionCache().CacheViews(key, nil, db.schemaName)
1818+
dbState.SessionCache().CacheViews(key, nil, schemaName)
18131819
return sql.ViewDefinition{}, false, nil
18141820
}
18151821

1816-
views, viewDef, found, err := getViewDefinitionFromSchemaFragmentsOfView(ctx, wrapper.backingTable, viewName)
1822+
views, viewDef, found, err := getViewDefinitionFromSchemaFragmentsOfView(ctx, wrapper.backingTable, viewName, schemaName)
18171823
if err != nil {
18181824
return sql.ViewDefinition{}, false, err
18191825
}
18201826

18211827
// TODO: only cache views from a single schema here
1822-
dbState.SessionCache().CacheViews(key, views, db.schemaName)
1828+
dbState.SessionCache().CacheViews(key, views, schemaName)
18231829

18241830
return viewDef, found, nil
18251831
}
18261832

1827-
func getViewDefinitionFromSchemaFragmentsOfView(ctx *sql.Context, tbl *WritableDoltTable, viewName string) ([]sql.ViewDefinition, sql.ViewDefinition, bool, error) {
1833+
func getViewDefinitionFromSchemaFragmentsOfView(ctx *sql.Context, tbl *WritableDoltTable, viewName, schemaName string) ([]sql.ViewDefinition, sql.ViewDefinition, bool, error) {
18281834
fragments, err := getSchemaFragmentsOfType(ctx, tbl, viewFragment)
18291835
if err != nil {
18301836
return nil, sql.ViewDefinition{}, false, err
@@ -1843,14 +1849,15 @@ func getViewDefinitionFromSchemaFragmentsOfView(ctx *sql.Context, tbl *WritableD
18431849
}
18441850
} else {
18451851
views[i] = sql.ViewDefinition{
1846-
Name: fragments[i].name,
1852+
Name: fragments[i].name,
1853+
SchemaName: fragments[i].schemaName,
18471854
// TODO: need to define TextDefinition
18481855
CreateViewStatement: fragments[i].fragment,
18491856
SqlMode: fragment.sqlMode,
18501857
}
18511858
}
18521859

1853-
if strings.EqualFold(fragment.name, viewName) {
1860+
if strings.EqualFold(fragment.name, viewName) && strings.EqualFold(fragment.schemaName, schemaName) {
18541861
found = true
18551862
viewDef = views[i]
18561863
}
@@ -1878,7 +1885,7 @@ func (db Database) AllViews(ctx *sql.Context) ([]sql.ViewDefinition, error) {
18781885
return nil, nil
18791886
}
18801887

1881-
views, _, _, err := getViewDefinitionFromSchemaFragmentsOfView(ctx, wrapper.backingTable, "")
1888+
views, _, _, err := getViewDefinitionFromSchemaFragmentsOfView(ctx, wrapper.backingTable, "", "")
18821889
if err != nil {
18831890
return nil, err
18841891
}
@@ -1974,7 +1981,7 @@ func (db Database) CreateTrigger(ctx *sql.Context, definition sql.TriggerDefinit
19741981
definition.Name,
19751982
definition.CreateStatement,
19761983
definition.CreatedAt,
1977-
fmt.Errorf("triggers `%s` already exists", definition.Name), //TODO: add a sql error and return that instead
1984+
fmt.Errorf("triggers `%s` already exists", definition.Name), // TODO: add a sql error and return that instead
19781985
)
19791986
}
19801987

@@ -2236,7 +2243,7 @@ func (db Database) addFragToSchemasTable(ctx *sql.Context, fragType, name, defin
22362243
return err
22372244
}
22382245

2239-
_, exists, err := fragFromSchemasTable(ctx, tbl, fragType, name)
2246+
_, exists, err := fragFromSchemasTable(ctx, tbl, fragType, name, db.schemaName)
22402247
if err != nil {
22412248
return err
22422249
}
@@ -2263,14 +2270,34 @@ func (db Database) addFragToSchemasTable(ctx *sql.Context, fragType, name, defin
22632270

22642271
sqlMode := sql.LoadSqlMode(ctx)
22652272

2266-
return inserter.Insert(ctx, sql.Row{fragType, name, definition, extraJSON, sqlMode.String()})
2273+
row := sql.Row{fragType, name, definition, extraJSON, sqlMode.String()}
2274+
2275+
// Include schema_name column for doltgres
2276+
if resolve.UseSearchPath && tbl.Schema().Contains(doltdb.SchemasTablesSchemaNameCol, tbl.Name()) {
2277+
if db.schemaName == "" {
2278+
root, err := db.GetRoot(ctx)
2279+
if err != nil {
2280+
return err
2281+
}
2282+
schemaName, err := resolve.FirstExistingSchemaOnSearchPath(ctx, root)
2283+
if err != nil {
2284+
return err
2285+
}
2286+
db.schemaName = schemaName
2287+
}
2288+
2289+
row = sql.Row{fragType, name, db.schemaName, definition, extraJSON, sqlMode.String()}
2290+
}
2291+
2292+
return inserter.Insert(ctx, row)
22672293
}
22682294

22692295
func (db Database) dropFragFromSchemasTable(ctx *sql.Context, fragType, name string, missingErr error) error {
22702296
if err := dsess.CheckAccessForDb(ctx, db, branch_control.Permissions_Write); err != nil {
22712297
return err
22722298
}
22732299

2300+
schemaName := db.schemaName
22742301
if resolve.UseSearchPath {
22752302
db.schemaName = "dolt"
22762303
}
@@ -2288,14 +2315,26 @@ func (db Database) dropFragFromSchemasTable(ctx *sql.Context, fragType, name str
22882315
return missingErr
22892316
}
22902317

2318+
if resolve.UseSearchPath && schemaName == "" {
2319+
root, err := db.GetRoot(ctx)
2320+
if err != nil {
2321+
return err
2322+
}
2323+
schemaName, err = resolve.FirstExistingSchemaOnSearchPath(ctx, root)
2324+
if err != nil {
2325+
return err
2326+
}
2327+
}
2328+
22912329
tbl := swrapper.backingTable
2292-
row, exists, err := fragFromSchemasTable(ctx, tbl, fragType, name)
2330+
row, exists, err := fragFromSchemasTable(ctx, tbl, fragType, name, schemaName)
22932331
if err != nil {
22942332
return err
22952333
}
22962334
if !exists {
22972335
return missingErr
22982336
}
2337+
22992338
deleter := tbl.Deleter(ctx)
23002339
err = deleter.Delete(ctx, row)
23012340
if err != nil {

go/libraries/doltcore/sqle/schema_table.go

Lines changed: 68 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,34 @@ func (st *SchemaTable) String() string {
5555
return doltdb.GetSchemasTableName()
5656
}
5757

58+
// GetSchemasSchema returns the schema of the dolt_schemas system table. This is used
59+
// by Doltgres to update the dolt_schemas schema with an additional schema_name column.
60+
var GetSchemasSchema = SchemaTableSchema
61+
62+
// func getDoltSchemasSchema(backingTable *WritableDoltTable) sql.Schema {
63+
// if backingTable == nil {
64+
// // No backing table; return a current schema.
65+
// return GetSchemasSchema().Schema
66+
// }
67+
68+
// if !backingTable.Schema().Contains(doltdb.SchemasTablesExtraCol, doltdb.GetSchemasTableName()) {
69+
// // No Extra column; return an ancient schema.
70+
// return SchemaTableAncientSqlSchema()
71+
// }
72+
73+
// if !backingTable.Schema().Contains(doltdb.SchemasTablesSqlModeCol, doltdb.GetSchemasTableName()) {
74+
// // No SQL_MODE column; return an old schema.
75+
// return SchemaTableV1SqlSchema()
76+
// }
77+
78+
// return GetSchemasSchema().Schema
79+
// }
80+
5881
func (st *SchemaTable) Schema() sql.Schema {
82+
currentSchema := toSqlSchemaTableSchema(GetSchemasSchema())
5983
if st.backingTable == nil {
6084
// No backing table; return a current schema.
61-
return SchemaTableSqlSchema().Schema
85+
return currentSchema.Schema
6286
}
6387

6488
if !st.backingTable.Schema().Contains(doltdb.SchemasTablesExtraCol, doltdb.GetSchemasTableName()) {
@@ -71,7 +95,7 @@ func (st *SchemaTable) Schema() sql.Schema {
7195
return SchemaTableV1SqlSchema()
7296
}
7397

74-
return SchemaTableSqlSchema().Schema
98+
return currentSchema.Schema
7599
}
76100

77101
func (st *SchemaTable) Collation() sql.CollationID {
@@ -127,14 +151,22 @@ var _ sql.IndexAddressableTable = (*SchemaTable)(nil)
127151
var _ sql.UpdatableTable = (*SchemaTable)(nil)
128152
var _ WritableDoltTableWrapper = (*SchemaTable)(nil)
129153

130-
func SchemaTableSqlSchema() sql.PrimaryKeySchema {
131-
sqlSchema, err := sqlutil.FromDoltSchema("", doltdb.GetSchemasTableName(), SchemaTableSchema())
154+
func toSqlSchemaTableSchema(sch schema.Schema) sql.PrimaryKeySchema {
155+
sqlSchema, err := sqlutil.FromDoltSchema("", doltdb.GetSchemasTableName(), sch)
132156
if err != nil {
133157
panic(err) // should never happen
134158
}
135159
return sqlSchema
136160
}
137161

162+
// func SchemaTableSqlSchema() sql.PrimaryKeySchema {
163+
// sqlSchema, err := sqlutil.FromDoltSchema("", doltdb.GetSchemasTableName(), SchemaTableSchema())
164+
// if err != nil {
165+
// panic(err) // should never happen
166+
// }
167+
// return sqlSchema
168+
// }
169+
138170
func mustNewColWithTypeInfo(name string, tag uint64, typeInfo typeinfo.TypeInfo, partOfPK bool, defaultVal string, autoIncrement bool, comment string, constraints ...schema.ColConstraint) schema.Column {
139171
col, err := schema.NewColumnWithTypeInfo(name, tag, typeInfo, partOfPK, defaultVal, autoIncrement, comment, constraints...)
140172
if err != nil {
@@ -250,7 +282,7 @@ func getOrCreateDoltSchemasTable(ctx *sql.Context, db Database) (retTbl *Writabl
250282
}
251283

252284
// Create new empty table
253-
err = db.createDoltTable(ctx, tname, root, SchemaTableSchema())
285+
err = db.createDoltTable(ctx, tname, root, GetSchemasSchema())
254286
if err != nil {
255287
return nil, err
256288
}
@@ -367,8 +399,8 @@ func migrateOldSchemasTableToNew(ctx *sql.Context, db Database, schemasTable *Wr
367399
}
368400

369401
// fragFromSchemasTable returns the row with the given schema fragment if it exists.
370-
func fragFromSchemasTable(ctx *sql.Context, tbl *WritableDoltTable, fragType string, name string) (r sql.Row, found bool, rerr error) {
371-
fragType, name = strings.ToLower(fragType), strings.ToLower(name)
402+
func fragFromSchemasTable(ctx *sql.Context, tbl *WritableDoltTable, fragType, name, schemaName string) (r sql.Row, found bool, rerr error) {
403+
fragType, name, schemaName = strings.ToLower(fragType), strings.ToLower(name), strings.ToLower(schemaName)
372404

373405
// This performs a full table scan in the worst case, but it's only used when adding or dropping a trigger or view
374406
iter, err := SqlTableToRowIter(ctx, tbl.DoltTable, nil)
@@ -387,6 +419,7 @@ func fragFromSchemasTable(ctx *sql.Context, tbl *WritableDoltTable, fragType str
387419
// need to get the column indexes from the current schema
388420
nameIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesNameCol)
389421
typeIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesTypeCol)
422+
schemaNameIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesSchemaNameCol)
390423

391424
for {
392425
sqlRow, err := iter.Next(ctx)
@@ -397,8 +430,13 @@ func fragFromSchemasTable(ctx *sql.Context, tbl *WritableDoltTable, fragType str
397430
return nil, false, err
398431
}
399432

433+
sqlRowSchemaName := ""
434+
if schemaNameIdx >= 0 {
435+
sqlRowSchemaName = sqlRow[schemaNameIdx].(string)
436+
}
437+
400438
// These columns are case insensitive, make sure to do a case-insensitive comparison
401-
if strings.EqualFold(sqlRow[typeIdx].(string), fragType) && strings.EqualFold(sqlRow[nameIdx].(string), name) {
439+
if strings.EqualFold(sqlRow[typeIdx].(string), fragType) && strings.EqualFold(sqlRow[nameIdx].(string), name) && strings.EqualFold(sqlRowSchemaName, schemaName) {
402440
return sqlRow, true, nil
403441
}
404442
}
@@ -407,9 +445,10 @@ func fragFromSchemasTable(ctx *sql.Context, tbl *WritableDoltTable, fragType str
407445
}
408446

409447
type schemaFragment struct {
410-
name string
411-
fragment string
412-
created time.Time
448+
name string
449+
schemaName string
450+
fragment string
451+
created time.Time
413452
// sqlMode indicates the SQL_MODE that was used when this schema fragment was initially parsed. SQL_MODE settings
414453
// such as ANSI_QUOTES control customized parsing behavior needed for some schema fragments.
415454
sqlMode string
@@ -424,6 +463,7 @@ func getSchemaFragmentsOfType(ctx *sql.Context, tbl *WritableDoltTable, fragType
424463
// The dolt_schemas table has undergone various changes over time and multiple possible schemas for it exist, so we
425464
// need to get the column indexes from the current schema
426465
nameIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesNameCol)
466+
schemaNameIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesSchemaNameCol)
427467
typeIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesTypeCol)
428468
fragmentIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesFragmentCol)
429469
extraIdx := tbl.sqlSchema().IndexOfColName(doltdb.SchemasTablesExtraCol)
@@ -463,13 +503,21 @@ func getSchemaFragmentsOfType(ctx *sql.Context, tbl *WritableDoltTable, fragType
463503
sqlModeString = defaultSqlMode
464504
}
465505

506+
schemaNameString := ""
507+
if schemaNameIdx >= 0 {
508+
if s, ok := sqlRow[schemaNameIdx].(string); ok {
509+
schemaNameString = s
510+
}
511+
}
512+
466513
// For older tables, use 1 as the trigger creation time
467514
if extraIdx < 0 || sqlRow[extraIdx] == nil {
468515
frags = append(frags, schemaFragment{
469-
name: sqlRow[nameIdx].(string),
470-
fragment: sqlRow[fragmentIdx].(string),
471-
created: time.Unix(1, 0).UTC(), // TablePlus editor thinks 0 is out of range
472-
sqlMode: sqlModeString,
516+
name: sqlRow[nameIdx].(string),
517+
schemaName: schemaNameString,
518+
fragment: sqlRow[fragmentIdx].(string),
519+
created: time.Unix(1, 0).UTC(), // TablePlus editor thinks 0 is out of range
520+
sqlMode: sqlModeString,
473521
})
474522
continue
475523
}
@@ -481,10 +529,11 @@ func getSchemaFragmentsOfType(ctx *sql.Context, tbl *WritableDoltTable, fragType
481529
}
482530

483531
frags = append(frags, schemaFragment{
484-
name: sqlRow[nameIdx].(string),
485-
fragment: sqlRow[fragmentIdx].(string),
486-
created: time.Unix(createdTime, 0).UTC(),
487-
sqlMode: sqlModeString,
532+
name: sqlRow[nameIdx].(string),
533+
schemaName: schemaNameString,
534+
fragment: sqlRow[fragmentIdx].(string),
535+
created: time.Unix(createdTime, 0).UTC(),
536+
sqlMode: sqlModeString,
488537
})
489538
}
490539

0 commit comments

Comments
 (0)