Merge branch 'main' into fulghum/dolt-7956

This commit is contained in:
Jason Fulghum
2024-06-07 11:27:03 -07:00
10 changed files with 119 additions and 37 deletions

View File

@@ -57,7 +57,7 @@ require (
github.com/cespare/xxhash v1.1.0
github.com/creasty/defaults v1.6.0
github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2
github.com/dolthub/go-mysql-server v0.18.2-0.20240604235838-5d11cec1718f
github.com/dolthub/go-mysql-server v0.18.2-0.20240606230452-b64d0222abc5
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63
github.com/dolthub/swiss v0.1.0
github.com/goccy/go-json v0.10.2

View File

@@ -183,8 +183,8 @@ 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-icu-regex v0.0.0-20230524105445-af7e7991c97e h1:kPsT4a47cw1+y/N5SSCkma7FhAPw7KeGmD6c9PBZW9Y=
github.com/dolthub/go-icu-regex v0.0.0-20230524105445-af7e7991c97e/go.mod h1:KPUcpx070QOfJK1gNe0zx4pA5sicIK1GMikIGLKC168=
github.com/dolthub/go-mysql-server v0.18.2-0.20240604235838-5d11cec1718f h1:e2Xyty29+ht/mL8ffvPyeKiVjaFcTo3N1OYuj6EnlmA=
github.com/dolthub/go-mysql-server v0.18.2-0.20240604235838-5d11cec1718f/go.mod h1:GT7JcQavIf7bAO17/odujkgHM/N0t4b1HfAPBJ2jzXo=
github.com/dolthub/go-mysql-server v0.18.2-0.20240606230452-b64d0222abc5 h1:UX5N4VwYOrrPNF15IJIlWp7ka27K6/nJSuMqzU7d04Y=
github.com/dolthub/go-mysql-server v0.18.2-0.20240606230452-b64d0222abc5/go.mod h1:GT7JcQavIf7bAO17/odujkgHM/N0t4b1HfAPBJ2jzXo=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63 h1:OAsXLAPL4du6tfbBgK0xXHZkOlos63RdKYS3Sgw/dfI=
github.com/dolthub/gozstd v0.0.0-20240423170813-23a2903bca63/go.mod h1:lV7lUeuDhH5thVGDCKXbatwKy2KW80L4rMT46n+Y2/Q=
github.com/dolthub/ishell v0.0.0-20221214210346-d7db0b066488 h1:0HHu0GWJH0N6a6keStrHhUAK5/o9LVfkh44pvsV4514=

View File

@@ -337,10 +337,20 @@ func (rs *RemoteChunkStore) getHost(md metadata.MD) string {
return host
}
func (rs *RemoteChunkStore) getScheme(md metadata.MD) string {
scheme := rs.httpScheme
forwardedSchemes := md.Get("x-forwarded-proto")
if len(forwardedSchemes) > 0 {
scheme = forwardedSchemes[0]
}
return scheme
}
func (rs *RemoteChunkStore) getDownloadUrl(md metadata.MD, path string) *url.URL {
host := rs.getHost(md)
scheme := rs.getScheme(md)
return &url.URL{
Scheme: rs.httpScheme,
Scheme: scheme,
Host: host,
Path: path,
}

View File

@@ -0,0 +1,36 @@
// Copyright 2024 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 remotesrv
import (
"testing"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/metadata"
)
func TestGRPCSchemeSelection(t *testing.T) {
rs := &RemoteChunkStore{
httpScheme: "http",
}
md := metadata.New(nil)
scheme := rs.getScheme(md)
assert.Equal(t, scheme, "http")
md.Append("x-forwarded-proto", "https")
scheme = rs.getScheme(md)
assert.Equal(t, scheme, "https")
}

View File

@@ -677,29 +677,17 @@ func (db Database) getTable(ctx *sql.Context, root doltdb.RootValue, tableName s
}
}
var tbl *doltdb.Table
// TODO: dolt_schemas needs work to be compatible with multiple schemas
if resolve.UseSearchPath && db.schemaName == "" && !doltdb.HasDoltPrefix(tableName) {
var tblName doltdb.TableName
tblName, tbl, ok, err = resolve.TableWithSearchPath(ctx, root, tableName)
if err != nil {
return nil, false, err
} else if !ok {
return nil, false, nil
}
// For the remainder of this method, we will use the schema name that was resolved and the table resolved
// will inherit it
db.schemaName = tblName.Schema
} else {
tableName, tbl, ok, err = db.resolveTable(ctx, root, tableName)
if err != nil {
return nil, false, err
} else if !ok {
return nil, false, nil
}
tblName, tbl, tblExists, err := db.resolveUserTable(ctx, root, tableName)
if err != nil {
return nil, false, err
} else if !tblExists {
return nil, false, nil
}
tableName = tblName.Name
// for remainder of this operation, all db operations will use the name resolved here
db.schemaName = tblName.Schema
sch, err := tbl.GetSchema(ctx)
if err != nil {
return nil, false, err
@@ -729,27 +717,57 @@ func (db Database) getTable(ctx *sql.Context, root doltdb.RootValue, tableName s
return table, true, nil
}
func (db Database) resolveTable(ctx *sql.Context, root doltdb.RootValue, tableName string) (string, *doltdb.Table, bool, error) {
// resolveUserTable returns the table with the given name from the root given. The table name is resolved in a
// case-insensitive manner. The table is returned along with its case-sensitive matched name. An error is returned if
// no such table exists.
func (db Database) resolveUserTable(ctx *sql.Context, root doltdb.RootValue, tableName string) (doltdb.TableName, *doltdb.Table, bool, error) {
var tbl *doltdb.Table
var tblName doltdb.TableName
var tblExists bool
// TODO: dolt_schemas needs work to be compatible with multiple schemas
if resolve.UseSearchPath && db.schemaName == "" && !doltdb.HasDoltPrefix(tableName) {
var err error
tblName, tbl, tblExists, err = resolve.TableWithSearchPath(ctx, root, tableName)
if err != nil {
return doltdb.TableName{}, nil, false, err
}
} else {
var err error
tblName, tbl, tblExists, err = db.tableInsensitive(ctx, root, tableName)
if err != nil {
return doltdb.TableName{}, nil, false, err
}
}
return tblName, tbl, tblExists, nil
}
// tableInsensitive returns the name of this table in the root given with the db's schema name, if it exists.
// Name matching is applied in a case-insensitive manner, and the table's case-corrected name is returned as the
// first result.
func (db Database) tableInsensitive(ctx *sql.Context, root doltdb.RootValue, tableName string) (doltdb.TableName, *doltdb.Table, bool, error) {
tableNames, err := db.getAllTableNames(ctx, root)
if err != nil {
return "", nil, false, err
return doltdb.TableName{}, nil, false, err
}
tableName, ok := sql.GetTableNameInsensitive(tableName, tableNames)
if !ok {
return "", nil, false, nil
return doltdb.TableName{}, nil, false, nil
}
// TODO: should we short-circuit the schema name for system tables?
tbl, ok, err := root.GetTable(ctx, doltdb.TableName{Name: tableName, Schema: db.schemaName})
tname := doltdb.TableName{Name: tableName, Schema: db.schemaName}
tbl, ok, err := root.GetTable(ctx, tname)
if err != nil {
return "", nil, false, err
return doltdb.TableName{}, nil, false, err
} else if !ok {
// Should be impossible
return "", nil, false, doltdb.ErrTableNotFound
return doltdb.TableName{}, nil, false, doltdb.ErrTableNotFound
}
return tableName, tbl, true, nil
return tname, tbl, true, nil
}
// newDoltTable returns a sql.Table wrapping the given underlying dolt table
@@ -901,16 +919,18 @@ func (db Database) dropTable(ctx *sql.Context, tableName string) error {
}
root := ws.WorkingRoot()
tbl, tableExists, err := root.GetTable(ctx, doltdb.TableName{Name: tableName})
tblName, tbl, tblExists, err := db.resolveUserTable(ctx, root, tableName)
if err != nil {
return err
}
if !tableExists {
} else if !tblExists {
return sql.ErrTableNotFound.New(tableName)
}
newRoot, err := root.RemoveTables(ctx, true, false, doltdb.TableName{Name: tableName, Schema: db.schemaName})
tableName = tblName.Name
// for remainder of this operation, all db operations will use the name resolved here
db.schemaName = tblName.Schema
newRoot, err := root.RemoveTables(ctx, true, false, tblName)
if err != nil {
return err
}

View File

@@ -2709,6 +2709,7 @@ func (t *WritableDoltTable) UpdateForeignKey(ctx *sql.Context, fkName string, sq
return sql.ErrForeignKeyNotFound.New(fkName, t.tableName)
}
fkc.RemoveKeyByName(doltFk.Name)
doltFk.Name = sqlFk.Name
doltFk.TableName = sqlFk.Table
doltFk.ReferencedTableName = sqlFk.ParentTable
doltFk.UnresolvedFKDetails.TableColumns = sqlFk.Columns

View File

@@ -58,6 +58,7 @@ func TestIncrementalLoadList(t *testing.T) {
ts := &chunks.TestStorage{}
cs := ts.NewView()
vs := NewValueStore(cs)
vs.skipWriteCaching = true
expected, err := NewList(context.Background(), vs, getTestVals(vs)...)
require.NoError(t, err)

View File

@@ -1134,6 +1134,8 @@ func TestListDiffLargeWithSameMiddle(t *testing.T) {
cs1 := storage.NewView()
vs1 := NewValueStore(cs1)
vs1.skipWriteCaching = true
nums1 := generateNumbersAsValues(vs1.Format(), 4000)
l1, err := NewList(context.Background(), vs1, nums1...)
require.NoError(t, err)
@@ -1151,6 +1153,8 @@ func TestListDiffLargeWithSameMiddle(t *testing.T) {
cs2 := storage.NewView()
vs2 := NewValueStore(cs2)
vs2.skipWriteCaching = true
nums2 := generateNumbersAsValuesFromToBy(vs2.Format(), 5, 3550, 1)
l2, err := NewList(context.Background(), vs2, nums2...)
require.NoError(t, err)

View File

@@ -78,6 +78,7 @@ type ValueStore struct {
decodedChunks *sizecache.SizeCache
nbf *NomsBinFormat
versOnce sync.Once
skipWriteCaching bool
gcMu sync.Mutex
gcCond *sync.Cond
@@ -343,6 +344,10 @@ func (lvs *ValueStore) WriteValue(ctx context.Context, v Value) (Ref, error) {
return Ref{}, err
}
if !lvs.skipWriteCaching {
lvs.decodedChunks.Add(c.Hash(), uint64(c.Size()), v)
}
return r, nil
}

View File

@@ -37,6 +37,7 @@ func TestValueReadWriteRead(t *testing.T) {
s := String("hello")
vs := newTestValueStore()
vs.skipWriteCaching = true
assert.Nil(vs.ReadValue(context.Background(), mustHash(s.Hash(vs.Format())))) // nil
h := mustRef(vs.WriteValue(context.Background(), s)).TargetHash()
rt, err := vs.Root(context.Background())
@@ -55,6 +56,7 @@ func TestReadWriteCache(t *testing.T) {
storage := &chunks.TestStorage{}
ts := storage.NewView()
vs := NewValueStore(ts)
vs.skipWriteCaching = true
var v Value = Bool(true)
r, err := vs.WriteValue(context.Background(), v)
@@ -82,6 +84,7 @@ func TestValueReadMany(t *testing.T) {
vals := ValueSlice{String("hello"), Bool(true), Float(42)}
vs := newTestValueStore()
vs.skipWriteCaching = true
hashes := hash.HashSlice{}
for _, v := range vals {
h := mustRef(vs.WriteValue(context.Background(), v)).TargetHash()
@@ -149,6 +152,7 @@ func TestPanicOnBadVersion(t *testing.T) {
func TestErrorIfDangling(t *testing.T) {
t.Skip("WriteValue errors with dangling ref error")
vs := newTestValueStore()
vs.skipWriteCaching = true
r, err := NewRef(Bool(true), vs.Format())
require.NoError(t, err)
@@ -168,6 +172,7 @@ func TestGC(t *testing.T) {
ctx := context.Background()
vs := newTestValueStore()
vs.skipWriteCaching = true
r1 := mustRef(vs.WriteValue(ctx, String("committed")))
r2 := mustRef(vs.WriteValue(ctx, String("unreferenced")))
set1 := mustSet(NewSet(ctx, vs, r1))