Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
3cdb14e
temp
Feb 13, 2025
24f2c2a
progress
Feb 14, 2025
d9efee5
compiling?
Feb 14, 2025
0ce2416
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Feb 14, 2025
e9ef941
compiling now?
Feb 14, 2025
3259879
merge
Feb 14, 2025
117410e
simplest select statement working
Feb 14, 2025
513f53d
better
Feb 17, 2025
eb6d741
progress
Feb 18, 2025
b653154
simple declare
Feb 19, 2025
ceb8331
implement if else
Feb 19, 2025
337227f
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Feb 19, 2025
f204d8c
implement while loops
Feb 19, 2025
5b3f720
tmp
Feb 19, 2025
7272c8b
Merge branch 'james/proc' of https://github.com/dolthub/go-mysql-serv…
Feb 20, 2025
9b8cc89
repeat test
Feb 20, 2025
b19b8b5
implemented repeat
Feb 20, 2025
da6db05
double replace issue
Feb 21, 2025
347cdd3
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Feb 21, 2025
75caa07
introduce new ast type
Feb 24, 2025
159888b
Merge branch 'james/proc' of https://github.com/dolthub/go-mysql-serv…
Mar 4, 2025
a14047c
merge with main
Mar 4, 2025
9baa293
Merge branch 'main' into james/proc
Mar 11, 2025
c41fed4
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Mar 11, 2025
bf5a416
implement case errors
Mar 11, 2025
176bd60
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Mar 11, 2025
dd870f7
fix
Mar 12, 2025
4b451f6
asdf
Mar 12, 2025
0ae1290
out tests
Mar 12, 2025
37981e0
fix out params
Mar 12, 2025
ba3fc05
convert booleans
Mar 13, 2025
98dee06
merge
Mar 13, 2025
913db9e
vitess bump
Mar 13, 2025
0d935c6
test
Mar 13, 2025
0d59d6e
merge with main
Mar 13, 2025
1c4f9d5
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Mar 13, 2025
8c0243b
handle else if
Mar 13, 2025
d125dec
handle insert
Mar 13, 2025
7752521
error
Mar 13, 2025
08f8e72
test
Mar 13, 2025
b96bbc3
fix user vras
Mar 14, 2025
586c990
asdf
Mar 14, 2025
b0e0452
merge
Mar 14, 2025
fae1af9
declare
Mar 14, 2025
c42d39f
Merge branch 'main' into james/proc
Mar 14, 2025
ba4fedf
fix some typing issues
Mar 17, 2025
27f7b46
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Mar 17, 2025
ea7551d
select into and some declare
Mar 18, 2025
784cbd2
condition and signal logic
Mar 20, 2025
421ac42
fix
Mar 20, 2025
57ef575
updating test
Mar 20, 2025
a725615
cursor implementation
Mar 20, 2025
2501280
replace limit vals
Mar 20, 2025
227e6c3
fix declare logic
Mar 20, 2025
7e618d8
handlers
Mar 21, 2025
909d7df
fixing some handlers
Mar 21, 2025
967a4f5
asdf
Mar 21, 2025
4f915d2
various fixes
Mar 21, 2025
2f321d4
Merge branch 'james/proc' of https://github.com/dolthub/go-mysql-serv…
Mar 21, 2025
95b5bd9
debugging out params being null
Mar 22, 2025
9edbf92
fix assigning user vars
Mar 22, 2025
ca8e957
fix views in procs
Mar 22, 2025
fc036a0
fix table errors
Mar 22, 2025
4247bb7
adsf
Mar 24, 2025
ce59b97
merge with main
Mar 24, 2025
db95360
bump
Mar 24, 2025
c0a76f2
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Mar 24, 2025
70ea89f
fix handler scopes
Mar 24, 2025
e5bbdfc
fix declares
Mar 25, 2025
6a12f7a
debugging
Mar 25, 2025
6b7413b
external procs
Mar 25, 2025
247c5d4
fix external procs kinda
Mar 26, 2025
b826c32
merge
Mar 26, 2025
5717a23
merge with main
Mar 26, 2025
1462fc7
bump
Mar 26, 2025
a5de726
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Mar 26, 2025
77d7501
todos
Mar 27, 2025
423e8bd
fix as of
Mar 31, 2025
a7feeda
fix join
Mar 31, 2025
2027f89
not sure what's wrong with double insert yet
Mar 31, 2025
3fc5e1d
merge with main
Apr 1, 2025
9df3d57
fixing triggers
Apr 1, 2025
742e9a8
stored procedures from triggers
Apr 2, 2025
7514559
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Apr 2, 2025
7969c06
go mod tidy
Apr 2, 2025
e7c820f
Merge branch 'james/proc' of https://github.com/dolthub/go-mysql-serv…
Apr 2, 2025
6f570b0
fix parameters
Apr 4, 2025
0872ac1
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Apr 4, 2025
35c46fe
test
Apr 4, 2025
981ed7f
Merge branch 'james/proc' of https://github.com/dolthub/go-mysql-serv…
Apr 4, 2025
c137d53
fix external procs
Apr 4, 2025
cdfc450
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Apr 4, 2025
ba4c923
debugging
Apr 4, 2025
112769f
fix?
Apr 8, 2025
b89f244
merge with main
Apr 8, 2025
d364eef
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Apr 8, 2025
d77b59a
fix
Apr 8, 2025
8c87be3
asdf
Apr 8, 2025
4e5e399
cleaning up
Apr 8, 2025
d35aea7
merge with main
Apr 11, 2025
50fbea8
bump
Apr 11, 2025
a205f74
fix schemas
Apr 11, 2025
7509fb7
this?
Apr 11, 2025
25087dd
asdfasdfafdg
Apr 11, 2025
de57c56
aaaaaaaa
Apr 11, 2025
64ad194
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Apr 11, 2025
5de9a32
dfasdfasdf
Apr 11, 2025
2d4d652
remove todos
Apr 11, 2025
58466c3
skip for the server
Apr 11, 2025
0d1adac
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Apr 11, 2025
fa59db2
merge with main
Apr 14, 2025
4d62d31
bump
jycor Apr 14, 2025
523207e
Merge branch 'main' into james/proc
jycor Apr 14, 2025
611dd73
merge with main
Apr 18, 2025
b7d7c61
bump
Apr 18, 2025
e64f37f
some feedback
Apr 21, 2025
70a3a2b
Merge branch 'main' into james/proc
Apr 22, 2025
8450a2a
preserve transactions
Apr 22, 2025
4f4eac7
comments
Apr 22, 2025
74a0a8e
progress
Apr 24, 2025
15d34c0
progress
Apr 24, 2025
a34f76e
progress
Apr 24, 2025
4823d27
merge with main
Apr 24, 2025
c127a7e
Merge branch 'james/proc' of github.com:dolthub/go-mysql-server into …
Apr 24, 2025
b67e4ec
bump
Apr 25, 2025
7862ef1
fix?
Apr 25, 2025
c601f3f
remove unused functions
Apr 25, 2025
3cbd94d
rename interpreter expression
Apr 26, 2025
bd61442
close iters when popping
Apr 26, 2025
9b72c7e
fixing comments
Apr 26, 2025
e8c7fbe
merge with main
Apr 27, 2025
9d3cb59
better context
Apr 28, 2025
f6f4b91
[ga-format-pr] Run ./format_repo.sh to fix formatting
jycor Apr 28, 2025
8527450
Merge branch 'main' into james/proc
Apr 29, 2025
a6f8e51
add missing ast nodes
Apr 29, 2025
9b13d2c
remove unused file
Apr 30, 2025
f106722
bump
Apr 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ type Engine struct {
Parser sql.Parser
}

var _ analyzer.StatementRunner = (*Engine)(nil)
var _ sql.StatementRunner = (*Engine)(nil)

type ColumnWithRawDefault struct {
SqlColumn *sql.Column
Expand Down
28 changes: 23 additions & 5 deletions enginetest/memory_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,24 +198,42 @@ func TestSingleQueryPrepared(t *testing.T) {

// Convenience test for debugging a single query. Unskip and set to the desired query.
func TestSingleScript(t *testing.T) {
t.Skip()
//t.Skip()
var scripts = []queries.ScriptTest{
{
Name: "test script",
Name: "Simple SELECT",
SetUpScript: []string{
"create table t (i int);",
`
create procedure proc(i int)
begin
set @x = 0;
repeat set @x = @x + 1;
until @x > i
end repeat;
end`,
//"create procedure proc(x int) select x > 1;",
},
Assertions: []queries.ScriptTestAssertion{
{
Query: "select 1 into @a",
Expected: []sql.Row{},
Query: "call proc(10);",
Expected: []sql.Row{
{types.NewOkResult(0)},
},
},
{
Query: "select @x;",
Expected: []sql.Row{
{11},
},
},
},
},
}

for _, test := range scripts {
harness := enginetest.NewMemoryHarness("", 1, testNumPartitions, true, nil)
// TODO: fix this
//harness.UseServer()
engine, err := harness.NewEngine(t)
if err != nil {
panic(err)
Expand Down
112 changes: 101 additions & 11 deletions enginetest/queries/procedure_queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"time"

"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/plan"
"github.com/dolthub/go-mysql-server/sql/types"
)

Expand Down Expand Up @@ -75,17 +76,13 @@ var ProcedureLogicTests = []ScriptTest{
{
Query: "CALL testabc(2, 3)",
Expected: []sql.Row{
{
6.0,
},
{6.0},
},
},
{
Query: "CALL testabc(9, 9.5)",
Expected: []sql.Row{
{
85.5,
},
{85.5},
},
},
},
Expand Down Expand Up @@ -2831,19 +2828,112 @@ var ProcedureCreateInSubroutineTests = []ScriptTest{
},
},
},

{
Name: "procedure must not contain CREATE TABLE",
Name: "table ddl statements in stored procedures",
Assertions: []ScriptTestAssertion{
{
Query: "create procedure p() create table t (pk int);",
ExpectedErrStr: "CREATE statements in CREATE PROCEDURE not yet supported",
Query: "create procedure create_proc() create table t (i int primary key, j int);",
Expected: []sql.Row{
{types.NewOkResult(0)},
},
},
{
Query: "create procedure p() begin create table t (pk int); end;",
ExpectedErrStr: "CREATE statements in CREATE PROCEDURE not yet supported",
Query: "call create_proc()",
Expected: []sql.Row{
{types.NewOkResult(0)},
},
},
{
Query: "show create table t;",
Expected: []sql.Row{
{"t", "CREATE TABLE `t` (\n" +
" `i` int NOT NULL,\n" +
" `j` int,\n" +
" PRIMARY KEY (`i`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin"},
},
},
{
Query: "call create_proc()",
ExpectedErrStr: "table with name t already exists",
},

{
Query: "create procedure insert_proc() insert into t values (1, 1), (2, 2), (3, 3);",
Expected: []sql.Row{
{types.NewOkResult(0)},
},
},
{
Query: "call insert_proc()",
Expected: []sql.Row{
{types.NewOkResult(3)},
},
},
{
Query: "select * from t",
Expected: []sql.Row{
{1, 1},
{2, 2},
{3, 3},
},
},
{
Query: "call insert_proc()",
ExpectedErrStr: "duplicate primary key given: [1]",
},

{
Query: "create procedure update_proc() update t set j = 999 where i > 1;",
Expected: []sql.Row{
{types.NewOkResult(0)},
},
},
{
Query: "call update_proc()",
Expected: []sql.Row{
{types.OkResult{RowsAffected: 2, Info: plan.UpdateInfo{Matched: 2, Updated: 2}}},
},
},
{
Query: "select * from t",
Expected: []sql.Row{
{1, 1},
{2, 999},
{3, 999},
},
},
{
Query: "call update_proc()",
Expected: []sql.Row{
{types.OkResult{RowsAffected: 0, Info: plan.UpdateInfo{Matched: 2}}},
},
},

{
Query: "create procedure drop_proc() drop table t;",
Expected: []sql.Row{
{types.NewOkResult(0)},
},
},
{
Query: "call drop_proc()",
Expected: []sql.Row{
{types.NewOkResult(0)},
},
},
{
Query: "show tables like 't'",
Expected: []sql.Row{},
},
{
Query: "call drop_proc()",
ExpectedErrStr: "Unknown table 't'",
},
},
},

{
Name: "procedure must not contain CREATE TRIGGER",
SetUpScript: []string{
Expand Down
2 changes: 1 addition & 1 deletion sql/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ type Analyzer struct {
// ExecBuilder converts a sql.Node tree into an executable iterator.
ExecBuilder sql.NodeExecBuilder
// Runner represents the engine, which is represented as a separate interface to work around circular dependencies
Runner StatementRunner
Runner sql.StatementRunner
}

// NewDefault creates a default Analyzer instance with all default Rules and configuration.
Expand Down
38 changes: 19 additions & 19 deletions sql/analyzer/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,33 @@
package analyzer

import (
"github.com/dolthub/vitess/go/vt/sqlparser"

"github.com/dolthub/go-mysql-server/sql/transform"

"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/plan"
"github.com/dolthub/go-mysql-server/sql/procedures"
"github.com/dolthub/go-mysql-server/sql/transform"
)

// Interpreter is an interface that implements an interpreter. These are typically used for functions (which may be
// implemented as a set of operations that are interpreted during runtime).
type Interpreter interface {
SetStatementRunner(ctx *sql.Context, runner StatementRunner) sql.Expression
}

// StatementRunner is essentially an interface that the engine will implement. We cannot directly reference the engine
// here as it will cause an import cycle, so this may be updated to suit any function changes that the engine
// experiences.
type StatementRunner interface {
QueryWithBindings(ctx *sql.Context, query string, parsed sqlparser.Statement, bindings map[string]sqlparser.Expr, qFlags *sql.QueryFlags) (sql.Schema, sql.RowIter, *sql.QueryFlags, error)
}

// interpreter hands the engine to any interpreter expressions.
func interpreter(ctx *sql.Context, a *Analyzer, n sql.Node, scope *plan.Scope, sel RuleSelector, qFlags *sql.QueryFlags) (sql.Node, transform.TreeIdentity, error) {
return transform.NodeExprs(n, func(expr sql.Expression) (sql.Expression, transform.TreeIdentity, error) {
if interp, ok := expr.(Interpreter); ok {
newNode, sameNode, err := transform.Node(n, func(node sql.Node) (sql.Node, transform.TreeIdentity, error) {
if interp, ok := node.(procedures.InterpreterNode); ok {
return interp.SetStatementRunner(ctx, a.Runner), transform.NewTree, nil
}
return node, transform.SameTree, nil
})
if err != nil {
return nil, transform.SameTree, err
}

newNode, sameExpr, err := transform.NodeExprs(newNode, func(expr sql.Expression) (sql.Expression, transform.TreeIdentity, error) {
if interp, ok := expr.(sql.Interpreter); ok {
return interp.SetStatementRunner(ctx, a.Runner), transform.NewTree, nil
}
return expr, transform.SameTree, nil
})
if err != nil {
return nil, transform.SameTree, err
}

return newNode, sameNode && sameExpr, err
}
2 changes: 2 additions & 0 deletions sql/expression/procedurereference.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"github.com/dolthub/go-mysql-server/sql/types"
)

// TODO: instead of procedure reference, copy stack from doltgres

// ProcedureReference contains the state for a single CALL statement of a stored procedure.
type ProcedureReference struct {
InnermostScope *procedureScope
Expand Down
49 changes: 43 additions & 6 deletions sql/plan/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ package plan
import (
"fmt"

"github.com/dolthub/go-mysql-server/sql/types"

"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/expression"
"github.com/dolthub/go-mysql-server/sql/procedures"
"github.com/dolthub/go-mysql-server/sql/types"
)

// TODO: we need different types of calls: one for external procedures one for stored procedures

type Call struct {
db sql.Database
Name string
Expand All @@ -32,22 +34,28 @@ type Call struct {
Pref *expression.ProcedureReference
cat sql.Catalog
Analyzed bool

// this will have list of parsed operations to run
Runner sql.StatementRunner
Ops []procedures.InterpreterOperation
}

var _ sql.Node = (*Call)(nil)
var _ sql.CollationCoercible = (*Call)(nil)
var _ sql.Expressioner = (*Call)(nil)
var _ procedures.InterpreterNode = (*Call)(nil)
var _ Versionable = (*Call)(nil)

// NewCall returns a *Call node.
func NewCall(db sql.Database, name string, params []sql.Expression, proc *Procedure, asOf sql.Expression, catalog sql.Catalog) *Call {
func NewCall(db sql.Database, name string, params []sql.Expression, proc *Procedure, asOf sql.Expression, catalog sql.Catalog, ops []procedures.InterpreterOperation) *Call {
return &Call{
db: db,
Name: name,
Params: params,
Procedure: proc,
asOf: asOf,
cat: catalog,
Ops: ops,
}
}

Expand Down Expand Up @@ -170,9 +178,6 @@ func (c *Call) DebugString() string {
} else {
tp.WriteNode("CALL %s.%s(%s)", c.db.Name(), c.Name, paramStr)
}
if c.Procedure != nil {
tp.WriteChildren(sql.DebugString(c.Procedure.Body))
}

return tp.String()
}
Expand All @@ -197,3 +202,35 @@ func (c *Call) Dispose() {
disposeNode(c.Procedure)
}
}

// SetStatementRunner implements the sql.InterpreterNode interface.
func (c *Call) SetStatementRunner(ctx *sql.Context, runner sql.StatementRunner) sql.Node {
nc := *c
nc.Runner = runner
return &nc
}

// GetRunner implements the sql.InterpreterNode interface.
func (c *Call) GetRunner() sql.StatementRunner {
return c.Runner
}

// GetParameters implements the sql.InterpreterNode interface.
func (c *Call) GetParameters() []sql.Type {
return nil
}

// GetParameterNames implements the sql.InterpreterNode interface.
func (c *Call) GetParameterNames() []string {
return nil
}

// GetStatements implements the sql.InterpreterNode interface.
func (c *Call) GetStatements() []*procedures.InterpreterOperation {
return c.Procedure.Ops
}

// GetReturn implements the sql.InterpreterNode interface.
func (c *Call) GetReturn() sql.Type {
return nil
}
2 changes: 1 addition & 1 deletion sql/plan/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func NodeRepresentsSelect(s sql.Node) bool {
case *Call:
return NodeRepresentsSelect(node.Procedure)
case *Procedure:
return NodeRepresentsSelect(node.Body)
return NodeRepresentsSelect(node.ExternalProc)
case *Block:
for _, stmt := range node.statements {
if NodeRepresentsSelect(stmt) {
Expand Down
Loading
Loading