Skip to content

Commit 77d2616

Browse files
committed
Merge branch 'main' into fulghum/dolt-5735
2 parents d975b7b + dac7262 commit 77d2616

File tree

232 files changed

+14700
-11583
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

232 files changed

+14700
-11583
lines changed

engine.go

Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package sqle
1616

1717
import (
1818
"fmt"
19-
"os"
2019
"sync"
2120

2221
"github.com/pkg/errors"
@@ -224,7 +223,6 @@ func (e *Engine) QueryNodeWithBindings(
224223
var (
225224
analyzed sql.Node
226225
iter sql.RowIter
227-
iter2 sql.RowIter2
228226
err error
229227
)
230228

@@ -269,17 +267,7 @@ func (e *Engine) QueryNodeWithBindings(
269267
return nil, nil, err
270268
}
271269

272-
useIter2 := false
273-
if enableRowIter2 {
274-
useIter2 = allNode2(analyzed)
275-
}
276-
277-
if useIter2 {
278-
iter2, err = analyzed.(sql.Node2).RowIter2(ctx, nil)
279-
iter = iter2
280-
} else {
281-
iter, err = analyzed.RowIter(ctx, nil)
282-
}
270+
iter, err = e.Analyzer.ExecBuilder.Build(ctx, analyzed, nil)
283271
if err != nil {
284272
err2 := clearAutocommitTransaction(ctx)
285273
if err2 != nil {
@@ -289,14 +277,6 @@ func (e *Engine) QueryNodeWithBindings(
289277
return nil, nil, err
290278
}
291279

292-
if useIter2 {
293-
iter = rowFormatSelectorIter{
294-
iter: iter,
295-
iter2: iter2,
296-
isNode2: useIter2,
297-
}
298-
}
299-
300280
return analyzed.Schema(), iter, nil
301281
}
302282

@@ -480,95 +460,6 @@ func (e *Engine) analyzePreparedQuery(ctx *sql.Context, query string, analyzed s
480460
return analyzed, nil
481461
}
482462

483-
// allNode2 returns whether all the nodes in the tree implement Node2.
484-
func allNode2(n sql.Node) bool {
485-
allNode2 := true
486-
transform.Inspect(n, func(n sql.Node) bool {
487-
switch n := n.(type) {
488-
case *plan.ResolvedTable:
489-
table := n.Table
490-
if tw, ok := table.(sql.TableWrapper); ok {
491-
table = tw.Underlying()
492-
}
493-
if _, ok := table.(sql.Table2); !ok {
494-
allNode2 = false
495-
return false
496-
}
497-
}
498-
if _, ok := n.(sql.Node2); n != nil && !ok {
499-
allNode2 = false
500-
return false
501-
}
502-
return true
503-
})
504-
if !allNode2 {
505-
return allNode2
506-
}
507-
508-
// All expressions in the tree must likewise be Expression2, and all types Type2, or we can't use rowFrame iteration
509-
// TODO: likely that some nodes rely on expressions but don't implement sql.Expressioner, or implement it incompletely
510-
transform.InspectExpressions(n, func(e sql.Expression) bool {
511-
if e == nil {
512-
return false
513-
}
514-
if _, ok := e.(sql.Expression2); !ok {
515-
allNode2 = false
516-
return false
517-
}
518-
if _, ok := e.Type().(sql.Type2); !ok {
519-
allNode2 = false
520-
return false
521-
}
522-
return true
523-
})
524-
525-
return allNode2
526-
}
527-
528-
// rowFormatSelectorIter is a wrapping row iter that implements RowIterTypeSelector so that clients consuming rows from it
529-
// know whether it's safe to iterate as RowIter or RowIter2.
530-
type rowFormatSelectorIter struct {
531-
iter sql.RowIter
532-
iter2 sql.RowIter2
533-
isNode2 bool
534-
}
535-
536-
var _ sql.RowIterTypeSelector = rowFormatSelectorIter{}
537-
var _ sql.RowIter = rowFormatSelectorIter{}
538-
var _ sql.RowIter2 = rowFormatSelectorIter{}
539-
540-
func (t rowFormatSelectorIter) Next(context *sql.Context) (sql.Row, error) {
541-
return t.iter.Next(context)
542-
}
543-
544-
func (t rowFormatSelectorIter) Close(context *sql.Context) error {
545-
if t.iter2 != nil {
546-
return t.iter2.Close(context)
547-
}
548-
return t.iter.Close(context)
549-
}
550-
551-
func (t rowFormatSelectorIter) Next2(ctx *sql.Context, frame *sql.RowFrame) error {
552-
return t.iter2.Next2(ctx, frame)
553-
}
554-
555-
func (t rowFormatSelectorIter) IsNode2() bool {
556-
return t.isNode2
557-
}
558-
559-
const (
560-
enableIter2EnvVar = "ENABLE_ROW_ITER_2"
561-
)
562-
563-
var enableRowIter2 bool
564-
565-
func init() {
566-
_, ok := os.LookupEnv(enableIter2EnvVar)
567-
if ok {
568-
enableRowIter2 = true
569-
}
570-
}
571-
572463
func (e *Engine) beginTransaction(ctx *sql.Context, transactionDatabase string) error {
573464
beginNewTransaction := ctx.GetTransaction() == nil || plan.ReadCommitted(ctx)
574465
if beginNewTransaction {

enginetest/engine_only_test.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242
"github.com/dolthub/go-mysql-server/sql/expression/function"
4343
"github.com/dolthub/go-mysql-server/sql/parse"
4444
"github.com/dolthub/go-mysql-server/sql/plan"
45+
"github.com/dolthub/go-mysql-server/sql/rowexec"
4546
"github.com/dolthub/go-mysql-server/sql/types"
4647
)
4748

@@ -245,7 +246,7 @@ func TestShowProcessList(t *testing.T) {
245246

246247
n := plan.NewShowProcessList()
247248

248-
iter, err := n.RowIter(ctx, nil)
249+
iter, err := rowexec.DefaultBuilder.Build(ctx, n, nil)
249250
require.NoError(err)
250251
rows, err := sql.RowIterToRows(ctx, n.Schema(), iter)
251252
require.NoError(err)
@@ -320,7 +321,7 @@ func TestTrackProcess(t *testing.T) {
320321
_, ok = rhs.Table.(*plan.ProcessIndexableTable)
321322
require.True(ok)
322323

323-
iter, err := proc.RowIter(ctx, nil)
324+
iter, err := rowexec.DefaultBuilder.Build(ctx, proc, nil)
324325
require.NoError(err)
325326
_, err = sql.RowIterToRows(ctx, nil, iter)
326327
require.NoError(err)
@@ -357,7 +358,8 @@ func TestLockTables(t *testing.T) {
357358
})
358359
node.Catalog = analyzer.NewCatalog(sql.NewDatabaseProvider())
359360

360-
_, err := node.RowIter(sql.NewEmptyContext(), nil)
361+
_, err := rowexec.DefaultBuilder.Build(sql.NewEmptyContext(), node, nil)
362+
361363
require.NoError(err)
362364

363365
require.Equal(1, t1.writeLocks)
@@ -685,6 +687,8 @@ func TestTableFunctions(t *testing.T) {
685687
testDatabaseProvider := NewTestProvider(&databaseProvider, SimpleTableFunction{}, memory.IntSequenceTable{})
686688

687689
engine := enginetest.NewEngineWithProvider(t, harness, testDatabaseProvider)
690+
engine.Analyzer.ExecBuilder = rowexec.DefaultBuilder
691+
688692
engine, err := enginetest.RunSetupScripts(harness.NewContext(), engine, setup.MydbData, true)
689693
require.NoError(t, err)
690694

@@ -868,6 +872,7 @@ func TestCollationCoercion(t *testing.T) {
868872

869873
var _ sql.TableFunction = (*SimpleTableFunction)(nil)
870874
var _ sql.CollationCoercible = (*SimpleTableFunction)(nil)
875+
var _ sql.ExecSourceRel = (*SimpleTableFunction)(nil)
871876

872877
// SimpleTableFunction an extremely simple implementation of TableFunction for testing.
873878
// When evaluated, returns a single row: {"foo", 123}
@@ -879,6 +884,14 @@ func (s SimpleTableFunction) NewInstance(_ *sql.Context, _ sql.Database, _ []sql
879884
return SimpleTableFunction{}, nil
880885
}
881886

887+
func (s SimpleTableFunction) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) {
888+
if s.returnedResults == true {
889+
return nil, io.EOF
890+
}
891+
s.returnedResults = true
892+
return &SimpleTableFunctionRowIter{}, nil
893+
}
894+
882895
func (s SimpleTableFunction) Resolved() bool {
883896
return true
884897
}
@@ -906,16 +919,6 @@ func (s SimpleTableFunction) Children() []sql.Node {
906919
return []sql.Node{}
907920
}
908921

909-
func (s SimpleTableFunction) RowIter(_ *sql.Context, _ sql.Row) (sql.RowIter, error) {
910-
if s.returnedResults == true {
911-
return nil, io.EOF
912-
}
913-
914-
s.returnedResults = true
915-
rowIter := &SimpleTableFunctionRowIter{}
916-
return rowIter, nil
917-
}
918-
919922
func (s SimpleTableFunction) WithChildren(_ ...sql.Node) (sql.Node, error) {
920923
return s, nil
921924
}

enginetest/enginetests.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/dolthub/go-mysql-server/server"
3939
"github.com/dolthub/go-mysql-server/sql"
4040
"github.com/dolthub/go-mysql-server/sql/analyzer"
41+
"github.com/dolthub/go-mysql-server/sql/analyzer/analyzererrors"
4142
"github.com/dolthub/go-mysql-server/sql/expression"
4243
"github.com/dolthub/go-mysql-server/sql/expression/function/aggregation"
4344
"github.com/dolthub/go-mysql-server/sql/mysql_db"
@@ -299,7 +300,7 @@ func TestReadOnlyDatabases(t *testing.T, harness ReadOnlyDatabaseHarness) {
299300
} {
300301
for _, tt := range querySet {
301302
t.Run(tt.WriteQuery, func(t *testing.T) {
302-
AssertErrWithBindings(t, engine, harness, tt.WriteQuery, tt.Bindings, analyzer.ErrReadOnlyDatabase)
303+
AssertErrWithBindings(t, engine, harness, tt.WriteQuery, tt.Bindings, analyzererrors.ErrReadOnlyDatabase)
303304
})
304305
}
305306
}
@@ -1818,6 +1819,12 @@ func TestStoredProcedures(t *testing.T, harness Harness) {
18181819
})
18191820
}
18201821

1822+
func TestEvents(t *testing.T, h Harness) {
1823+
for _, script := range queries.EventTests {
1824+
TestScript(t, h, script)
1825+
}
1826+
}
1827+
18211828
func TestTriggerErrors(t *testing.T, harness Harness) {
18221829
for _, script := range queries.TriggerErrorTests {
18231830
TestScript(t, harness, script)
@@ -1890,10 +1897,6 @@ func TestRecursiveViewDefinition(t *testing.T, harness Harness) {
18901897
db, err := e.Analyzer.Catalog.Database(ctx, "mydb")
18911898
require.NoError(t, err)
18921899

1893-
if pdb, ok := db.(mysql_db.PrivilegedDatabase); ok {
1894-
db = pdb.Unwrap()
1895-
}
1896-
18971900
vdb, ok := db.(sql.ViewDatabase)
18981901
require.True(t, ok, "expected sql.ViewDatabase")
18991902

enginetest/evaluation.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"github.com/dolthub/go-mysql-server/enginetest/queries"
3030
"github.com/dolthub/go-mysql-server/enginetest/scriptgen/setup"
3131
"github.com/dolthub/go-mysql-server/sql"
32-
"github.com/dolthub/go-mysql-server/sql/analyzer"
3332
"github.com/dolthub/go-mysql-server/sql/expression"
3433
"github.com/dolthub/go-mysql-server/sql/parse"
3534
"github.com/dolthub/go-mysql-server/sql/plan"
@@ -766,7 +765,7 @@ func ExtractQueryNode(node sql.Node) sql.Node {
766765
switch node := node.(type) {
767766
case *plan.QueryProcess:
768767
return ExtractQueryNode(node.Child())
769-
case *analyzer.Releaser:
768+
case *plan.Releaser:
770769
return ExtractQueryNode(node.Child)
771770
default:
772771
return node

enginetest/memory_engine_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,10 @@ func TestStoredProcedures(t *testing.T) {
645645
enginetest.TestStoredProcedures(t, enginetest.NewDefaultMemoryHarness())
646646
}
647647

648+
func TestEvents(t *testing.T) {
649+
enginetest.TestEvents(t, enginetest.NewDefaultMemoryHarness())
650+
}
651+
648652
func TestTriggersErrors(t *testing.T) {
649653
enginetest.TestTriggerErrors(t, enginetest.NewDefaultMemoryHarness())
650654
}

enginetest/mysqlshim/database.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ var _ sql.TableRenamer = Database{}
3636
var _ sql.TriggerDatabase = Database{}
3737
var _ sql.StoredProcedureDatabase = Database{}
3838
var _ sql.ViewDatabase = Database{}
39+
var _ sql.EventDatabase = Database{}
3940

4041
// Name implements the interface sql.Database.
4142
func (d Database) Name() string {
@@ -199,6 +200,63 @@ func (d Database) DropStoredProcedure(ctx *sql.Context, name string) error {
199200
return d.shim.Exec(d.name, fmt.Sprintf("DROP PROCEDURE `%s`;", name))
200201
}
201202

203+
// GetEvent implements sql.EventDatabase
204+
func (d Database) GetEvent(ctx *sql.Context, name string) (sql.EventDefinition, bool, error) {
205+
name = strings.ToLower(name)
206+
events, err := d.GetEvents(ctx)
207+
if err != nil {
208+
return sql.EventDefinition{}, false, err
209+
}
210+
for _, event := range events {
211+
if name == strings.ToLower(event.Name) {
212+
return event, true, nil
213+
}
214+
}
215+
return sql.EventDefinition{}, false, nil
216+
}
217+
218+
// GetEvents implements sql.EventDatabase
219+
func (d Database) GetEvents(ctx *sql.Context) ([]sql.EventDefinition, error) {
220+
events, err := d.shim.QueryRows("", fmt.Sprintf("SHOW EVENTS WHERE Db = '%s';", d.name))
221+
if err != nil {
222+
return nil, err
223+
}
224+
eventDefinition := make([]sql.EventDefinition, len(events))
225+
for i, event := range events {
226+
// Db, Name, Definer, Time Zone, Type, ...
227+
eventStmt, err := d.shim.QueryRows("", fmt.Sprintf("SHOW CREATE EVENT `%s`.`%s`;", d.name, event[1]))
228+
if err != nil {
229+
return nil, err
230+
}
231+
// Event, sql_mode, time_zone, Create Event, ...
232+
eventDefinition[i] = sql.EventDefinition{
233+
Name: eventStmt[0][0].(string),
234+
CreateStatement: eventStmt[0][3].(string),
235+
// TODO: other fields should be added such as Created, LastAltered
236+
}
237+
}
238+
return eventDefinition, nil
239+
}
240+
241+
// SaveEvent implements sql.EventDatabase
242+
func (d Database) SaveEvent(ctx *sql.Context, ed sql.EventDefinition) error {
243+
return d.shim.Exec(d.name, ed.CreateStatement)
244+
}
245+
246+
// DropEvent implements sql.EventDatabase
247+
func (d Database) DropEvent(ctx *sql.Context, name string) error {
248+
return d.shim.Exec(d.name, fmt.Sprintf("DROP EVENT `%s`;", name))
249+
}
250+
251+
// UpdateEvent implements sql.EventDatabase
252+
func (d Database) UpdateEvent(ctx *sql.Context, ed sql.EventDefinition) error {
253+
err := d.shim.Exec(d.name, fmt.Sprintf("DROP EVENT `%s`;", ed.Name))
254+
if err != nil {
255+
return err
256+
}
257+
return d.shim.Exec(d.name, ed.CreateStatement)
258+
}
259+
202260
// CreateView implements the interface sql.ViewDatabase.
203261
func (d Database) CreateView(ctx *sql.Context, name string, selectStatement, createViewStmt string) error {
204262
return d.shim.Exec(d.name, createViewStmt)

enginetest/queries/charset_collation_engine.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ type CharsetCollationEngineTestQuery struct {
4343
// CharsetCollationEngineTests are used to ensure that character sets and collations have the correct behavior over the
4444
// engine. Return values should all have the `utf8mb4` encoding, as it's returning the internal encoding type.
4545
var CharsetCollationEngineTests = []CharsetCollationEngineTest{
46+
{
47+
Name: "Uppercase and lowercase collations",
48+
Queries: []CharsetCollationEngineTestQuery{
49+
{
50+
Query: "CREATE TABLE test1 (v1 VARCHAR(255) COLLATE utf16_unicode_ci, v2 VARCHAR(255) COLLATE UTF16_UNICODE_CI);",
51+
Expected: []sql.Row{{types.NewOkResult(0)}},
52+
},
53+
{
54+
Query: "CREATE TABLE test2 (v1 VARCHAR(255) CHARACTER SET utf16, v2 VARCHAR(255) CHARACTER SET UTF16);",
55+
Expected: []sql.Row{{types.NewOkResult(0)}},
56+
},
57+
},
58+
},
4659
{
4760
Name: "Insert multiple character sets",
4861
SetUpScript: []string{

0 commit comments

Comments
 (0)