Skip to content

Commit 24f2c2a

Browse files
author
James Cor
committed
progress
1 parent 3cdb14e commit 24f2c2a

File tree

10 files changed

+282
-149
lines changed

10 files changed

+282
-149
lines changed

sql/plan/call.go

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,14 @@ package plan
1717
import (
1818
"fmt"
1919

20-
"github.com/dolthub/go-mysql-server/sql/types"
21-
2220
"github.com/dolthub/go-mysql-server/sql"
2321
"github.com/dolthub/go-mysql-server/sql/expression"
22+
"github.com/dolthub/go-mysql-server/sql/procedures"
23+
"github.com/dolthub/go-mysql-server/sql/types"
2424
)
2525

2626

27-
// TODO: we need different types of calls: one for extrenal procedures one for stored procedures
28-
27+
// TODO: we need different types of calls: one for external procedures one for stored procedures
2928

3029
type Call struct {
3130
db sql.Database
@@ -38,24 +37,26 @@ type Call struct {
3837
Analyzed bool
3938

4039
// this will have list of parsed operations to run
41-
runner sql.StatementRunner
40+
Runner sql.StatementRunner
41+
Ops []procedures.InterpreterOperation
4242
}
4343

4444
var _ sql.Node = (*Call)(nil)
4545
var _ sql.CollationCoercible = (*Call)(nil)
4646
var _ sql.Expressioner = (*Call)(nil)
47-
var _ sql.InterpreterNode = (*Call)(nil)
47+
var _ procedures.InterpreterNode = (*Call)(nil)
4848
var _ Versionable = (*Call)(nil)
4949

5050
// NewCall returns a *Call node.
51-
func NewCall(db sql.Database, name string, params []sql.Expression, proc *Procedure, asOf sql.Expression, catalog sql.Catalog) *Call {
51+
func NewCall(db sql.Database, name string, params []sql.Expression, proc *Procedure, asOf sql.Expression, catalog sql.Catalog, ops []procedures.InterpreterOperation) *Call {
5252
return &Call{
5353
db: db,
5454
Name: name,
5555
Params: params,
5656
Procedure: proc,
5757
asOf: asOf,
5858
cat: catalog,
59+
Ops: ops,
5960
}
6061
}
6162

@@ -178,9 +179,6 @@ func (c *Call) DebugString() string {
178179
} else {
179180
tp.WriteNode("CALL %s.%s(%s)", c.db.Name(), c.Name, paramStr)
180181
}
181-
if c.Procedure != nil {
182-
tp.WriteChildren(sql.DebugString(c.Procedure.Body))
183-
}
184182

185183
return tp.String()
186184
}
@@ -209,6 +207,35 @@ func (c *Call) Dispose() {
209207
// SetStatementRunner implements the sql.InterpreterNode interface.
210208
func (c *Call) SetStatementRunner(ctx *sql.Context, runner sql.StatementRunner) sql.Node {
211209
nc := *c
212-
nc.runner = runner
210+
nc.Runner = runner
213211
return &nc
214212
}
213+
214+
// GetRunner implements the sql.InterpreterNode interface.
215+
func (c *Call) GetRunner() sql.StatementRunner {
216+
return c.Runner
217+
}
218+
219+
// GetParameters implements the sql.InterpreterNode interface.
220+
func (c *Call) GetParameters() []sql.Type {
221+
return nil
222+
}
223+
224+
// GetParameterNames implements the sql.InterpreterNode interface.
225+
func (c *Call) GetParameterNames() []string {
226+
return nil
227+
}
228+
229+
// GetStatements implements the sql.InterpreterNode interface.
230+
func (c *Call) GetStatements() []procedures.InterpreterOperation {
231+
return c.Ops
232+
}
233+
234+
// GetReturn implements the sql.InterpreterNode interface.
235+
func (c *Call) GetReturn() sql.Type {
236+
return nil
237+
}
238+
239+
240+
241+

sql/plan/procedure.go

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ import (
2020
"strings"
2121
"time"
2222

23-
"github.com/dolthub/go-mysql-server/sql/expression"
24-
2523
"github.com/dolthub/go-mysql-server/sql"
24+
"github.com/dolthub/go-mysql-server/sql/expression"
25+
"github.com/dolthub/go-mysql-server/sql/procedures"
26+
"github.com/dolthub/go-mysql-server/sql/types"
2627
)
2728

2829
// ProcedureSecurityContext determines whether the stored procedure is executed using the privileges of the definer or
@@ -80,7 +81,8 @@ type Procedure struct {
8081
Comment string
8182
Characteristics []Characteristic
8283
CreateProcedureString string
83-
Body sql.Node
84+
Ops []procedures.InterpreterOperation
85+
ExternalProc sql.Node
8486
CreatedAt time.Time
8587
ModifiedAt time.Time
8688
ValidationError error
@@ -100,7 +102,7 @@ func NewProcedure(
100102
comment string,
101103
characteristics []Characteristic,
102104
createProcedureString string,
103-
body sql.Node,
105+
ops []procedures.InterpreterOperation,
104106
createdAt time.Time,
105107
modifiedAt time.Time,
106108
) *Procedure {
@@ -121,55 +123,49 @@ func NewProcedure(
121123
Comment: comment,
122124
Characteristics: characteristics,
123125
CreateProcedureString: createProcedureString,
124-
Body: body,
126+
Ops: ops,
125127
CreatedAt: createdAt,
126128
ModifiedAt: modifiedAt,
127129
}
128130
}
129131

130132
// Resolved implements the sql.Node interface.
131133
func (p *Procedure) Resolved() bool {
132-
return p.Body.Resolved()
134+
return true
133135
}
134136

135137
func (p *Procedure) IsReadOnly() bool {
136-
return p.Body.IsReadOnly()
138+
return false
137139
}
138140

139141
// String implements the sql.Node interface.
140142
func (p *Procedure) String() string {
141-
return p.Body.String()
143+
return ""
142144
}
143145

144146
// DebugString implements the sql.DebugStringer interface.
145147
func (p *Procedure) DebugString() string {
146-
return sql.DebugString(p.Body)
148+
return sql.DebugString(p.Ops)
147149
}
148150

149151
// Schema implements the sql.Node interface.
150152
func (p *Procedure) Schema() sql.Schema {
151-
return p.Body.Schema()
153+
return types.OkResultSchema
152154
}
153155

154156
// Children implements the sql.Node interface.
155157
func (p *Procedure) Children() []sql.Node {
156-
return []sql.Node{p.Body}
158+
return nil
157159
}
158160

159161
// WithChildren implements the sql.Node interface.
160162
func (p *Procedure) WithChildren(children ...sql.Node) (sql.Node, error) {
161-
if len(children) != 1 {
162-
return nil, sql.ErrInvalidChildrenNumber.New(p, len(children), 1)
163-
}
164-
165-
np := *p
166-
np.Body = children[0]
167-
return &np, nil
163+
return p, nil
168164
}
169165

170166
// CollationCoercibility implements the interface sql.CollationCoercible.
171167
func (p *Procedure) CollationCoercibility(ctx *sql.Context) (collation sql.CollationID, coercibility byte) {
172-
return sql.GetCoercibility(ctx, p.Body)
168+
return sql.GetCoercibility(ctx, p.Ops)
173169
}
174170

175171
// implementsRepresentsBlock implements the RepresentsBlock interface.
@@ -181,9 +177,9 @@ func (p *Procedure) ExtendVariadic(ctx *sql.Context, length int) *Procedure {
181177
return p
182178
}
183179
np := *p
184-
body := p.Body.(*ExternalProcedure)
180+
body := p.ExternalProc.(*ExternalProcedure)
185181
newBody := *body
186-
np.Body = &newBody
182+
np.ExternalProc = &newBody
187183

188184
newParamDefinitions := make([]ProcedureParam, length)
189185
newParams := make([]*expression.ProcedureParam, length)
@@ -226,7 +222,7 @@ func (p *Procedure) HasVariadicParameter() bool {
226222

227223
// IsExternal returns whether the stored procedure is external.
228224
func (p *Procedure) IsExternal() bool {
229-
if _, ok := p.Body.(*ExternalProcedure); ok {
225+
if _, ok := p.ExternalProc.(*ExternalProcedure); ok {
230226
return true
231227
}
232228
return false

sql/planbuilder/proc.go

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -257,24 +257,14 @@ func BuildProcedureHelper(ctx *sql.Context, cat sql.Catalog, isCreateProc bool,
257257

258258
// TODO: convert ast to operations
259259

260-
procedures.Parse(procStmt.ProcedureSpec.Body)
260+
ops, err := procedures.Parse(procStmt.ProcedureSpec.Body)
261+
if err != nil {
262+
b.handleErr(err)
263+
}
261264

262265
procParams := b.buildProcedureParams(procStmt.ProcedureSpec.Params)
263266
characteristics, securityType, comment := b.buildProcedureCharacteristics(procStmt.ProcedureSpec.Characteristics)
264267

265-
// populate inScope with the procedure parameters. this will be
266-
// subject maybe a bug where an inner procedure has access to
267-
// outer procedure parameters.
268-
if inScope == nil {
269-
inScope = b.newScope()
270-
}
271-
inScope.initProc()
272-
for _, p := range procParams {
273-
inScope.proc.AddVar(expression.NewProcedureParam(strings.ToLower(p.Name), p.Type))
274-
}
275-
276-
bodyStr := strings.TrimSpace(procDetails.CreateStatement[procStmt.SubStatementPositionStart:procStmt.SubStatementPositionEnd])
277-
bodyScope := b.buildSubquery(inScope, procStmt.ProcedureSpec.Body, bodyStr, procDetails.CreateStatement)
278268

279269
proc = plan.NewProcedure(
280270
procDetails.Name,
@@ -284,12 +274,12 @@ func BuildProcedureHelper(ctx *sql.Context, cat sql.Catalog, isCreateProc bool,
284274
comment,
285275
characteristics,
286276
procDetails.CreateStatement,
287-
bodyScope.node,
277+
ops,
288278
procDetails.CreatedAt,
289279
procDetails.ModifiedAt,
290280
)
291-
qFlags = b.qFlags
292-
return
281+
282+
return proc, qFlags, nil
293283
}
294284

295285
func (b *Builder) buildCall(inScope *scope, c *ast.Call) (outScope *scope) {
@@ -332,7 +322,7 @@ func (b *Builder) buildCall(inScope *scope, c *ast.Call) (outScope *scope) {
332322
procDetails, ok, err = spdb.GetStoredProcedure(b.ctx, procName)
333323
if err == nil {
334324
if ok {
335-
proc, innerQFlags, err = BuildProcedureHelper(b.ctx, b.cat, false, inScope, db, asOf, procDetails)
325+
ops, innerQFlags, err = BuildProcedureHelper(b.ctx, b.cat, false, inScope, db, asOf, procDetails)
336326
// TODO: somewhat hacky way of preserving this flag
337327
// This is necessary so that the resolveSubqueries analyzer rule
338328
// will apply NodeExecBuilder to Subqueries in procedure body

sql/procedures.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"fmt"
1919
"time"
2020

21+
"github.com/dolthub/go-mysql-server/sql/procedures"
22+
2123
"github.com/dolthub/vitess/go/vt/sqlparser"
2224
)
2325

@@ -34,6 +36,10 @@ type Interpreter interface {
3436
// implemented as a set of operations that are interpreted during runtime).
3537
type InterpreterNode interface {
3638
SetStatementRunner(ctx *Context, runner StatementRunner) Node
39+
GetParameters() []Type
40+
GetParameterNames() []string
41+
GetReturn() Type
42+
GetStatements() []procedures.InterpreterOperation
3743
}
3844

3945
// StatementRunner is essentially an interface that the engine will implement. We cannot directly reference the engine

0 commit comments

Comments
 (0)