This commit is contained in:
Nuno Cruces
2024-06-19 23:25:05 +01:00
parent 5c1c0f03a5
commit 65af8065cd
4 changed files with 51 additions and 47 deletions

View File

@@ -12,8 +12,13 @@ import (
)
const (
code = 4
base = 8
_NONE = iota
_MEMORY
_SYNTAX
_UNSUPPORTEDSQL
codeptr = 4
baseptr = 8
)
var (
@@ -22,6 +27,7 @@ var (
ctx context.Context
once sync.Once
runtime wazero.Runtime
module wazero.CompiledModule
)
// Table holds metadata about a table.
@@ -35,32 +41,38 @@ type Table struct {
//
// [CREATE]: https://sqlite.org/lang_createtable.html
// [ALTER TABLE]: https://sqlite.org/lang_altertable.html
func Parse(sql string) (*Table, error) {
func Parse(sql string) (_ *Table, err error) {
once.Do(func() {
ctx = context.Background()
cfg := wazero.NewRuntimeConfigInterpreter().WithDebugInfoEnabled(false)
runtime = wazero.NewRuntimeWithConfig(ctx, cfg)
module, err = runtime.CompileModule(ctx, binary)
})
mod, err := runtime.InstantiateWithConfig(ctx, binary, wazero.NewModuleConfig().WithName(""))
if err != nil {
return nil, err
}
if buf, ok := mod.Memory().Read(base, uint32(len(sql))); ok {
mod, err := runtime.InstantiateModule(ctx, module, wazero.NewModuleConfig().WithName(""))
if err != nil {
return nil, err
}
if buf, ok := mod.Memory().Read(baseptr, uint32(len(sql))); ok {
copy(buf, sql)
}
r, err := mod.ExportedFunction("sql3parse_table").Call(ctx, base, uint64(len(sql)), code)
r, err := mod.ExportedFunction("sql3parse_table").Call(ctx, baseptr, uint64(len(sql)), codeptr)
if err != nil {
return nil, err
}
c, _ := mod.Memory().ReadUint32Le(code)
if c == uint32(_MEMORY) {
c, _ := mod.Memory().ReadUint32Le(codeptr)
switch c {
case _MEMORY:
panic(util.OOMErr)
}
if c != uint32(_NONE) {
return nil, ecode(c)
case _SYNTAX:
return nil, util.ErrorString("sql3parse: invalid syntax")
case _UNSUPPORTEDSQL:
return nil, util.ErrorString("sql3parse: unsupported SQL")
}
if r[0] == 0 {
return nil, nil
@@ -102,6 +114,15 @@ func (t *Table) Column(i int) Column {
}
}
func (t *Table) string(ptr uint32) string {
if ptr == 0 {
return ""
}
off, _ := t.mod.Memory().ReadUint32Le(ptr + 0)
len, _ := t.mod.Memory().ReadUint32Le(ptr + 4)
return t.sql[off-baseptr : off+len-baseptr]
}
// Column holds metadata about a column.
type Column struct {
tab *Table
@@ -116,30 +137,5 @@ func (c Column) Type() string {
if err != nil {
panic(err)
}
if r[0] == 0 {
return ""
}
off, _ := c.tab.mod.Memory().ReadUint32Le(uint32(r[0]) + 0)
len, _ := c.tab.mod.Memory().ReadUint32Le(uint32(r[0]) + 4)
return c.tab.sql[off-base : off+len-base]
}
type ecode uint32
const (
_NONE ecode = iota
_MEMORY
_SYNTAX
_UNSUPPORTEDSQL
)
func (e ecode) Error() string {
switch e {
case _SYNTAX:
return "sql3parse: invalid syntax"
case _UNSUPPORTEDSQL:
return "sql3parse: unsupported SQL"
default:
panic(util.AssertErr())
}
return c.tab.string(uint32(r[0]))
}