8 "github.com/tetratelabs/wazero"
9 "github.com/tetratelabs/wazero/api"
11 "github.com/ncruces/go-sqlite3/internal/util"
20 //go:embed wasm/sql3parse_table.wasm
23 runtime wazero.Runtime
24 compiled wazero.CompiledModule
27// ParseTable parses a [CREATE] or [ALTER TABLE] command.
29// [CREATE]: https://sqlite.org/lang_createtable.html
30// [ALTER TABLE]: https://sqlite.org/lang_altertable.html
31func ParseTable(sql string) (_ *Table, err error) {
33 ctx := context.Background()
34 cfg := wazero.NewRuntimeConfigInterpreter()
35 runtime = wazero.NewRuntimeWithConfig(ctx, cfg)
36 compiled, err = runtime.CompileModule(ctx, binary)
42 ctx := context.Background()
43 mod, err := runtime.InstantiateModule(ctx, compiled, wazero.NewModuleConfig().WithName(""))
49 if buf, ok := mod.Memory().Read(sqlp, uint32(len(sql))); ok {
53 stack := [...]util.Stk_t{sqlp, util.Stk_t(len(sql)), errp}
54 err = mod.ExportedFunction("sql3parse_table").CallWithStack(ctx, stack[:])
59 c, _ := mod.Memory().ReadUint32Le(errp)
64 return nil, util.ErrorString("sql3parse: invalid syntax")
66 return nil, util.ErrorString("sql3parse: unsupported SQL")
70 tab.load(mod, uint32(stack[0]), sql)
74// Table holds metadata about a table.
89func (t *Table) load(mod api.Module, ptr uint32, sql string) {
90 t.Name = loadString(mod, ptr+0, sql)
91 t.Schema = loadString(mod, ptr+8, sql)
92 t.Comment = loadString(mod, ptr+16, sql)
94 t.IsTemporary = loadBool(mod, ptr+24)
95 t.IsIfNotExists = loadBool(mod, ptr+25)
96 t.IsWithoutRowID = loadBool(mod, ptr+26)
97 t.IsStrict = loadBool(mod, ptr+27)
99 t.Columns = loadSlice(mod, ptr+28, func(ptr uint32, ret *Column) {
100 p, _ := mod.Memory().ReadUint32Le(ptr)
101 ret.load(mod, p, sql)
104 t.Type = loadEnum[StatementType](mod, ptr+44)
105 t.CurrentName = loadString(mod, ptr+48, sql)
106 t.NewName = loadString(mod, ptr+56, sql)
109// Column holds metadata about a column.
114 ConstraintName string
121 PKConflictClause ConflictClause
122 NotNullConflictClause ConflictClause
123 UniqueConflictClause ConflictClause
127 ForeignKeyClause *ForeignKey
130func (c *Column) load(mod api.Module, ptr uint32, sql string) {
131 c.Name = loadString(mod, ptr+0, sql)
132 c.Type = loadString(mod, ptr+8, sql)
133 c.Length = loadString(mod, ptr+16, sql)
134 c.ConstraintName = loadString(mod, ptr+24, sql)
135 c.Comment = loadString(mod, ptr+32, sql)
137 c.IsPrimaryKey = loadBool(mod, ptr+40)
138 c.IsAutoIncrement = loadBool(mod, ptr+41)
139 c.IsNotNull = loadBool(mod, ptr+42)
140 c.IsUnique = loadBool(mod, ptr+43)
142 c.PKOrder = loadEnum[OrderClause](mod, ptr+44)
143 c.PKConflictClause = loadEnum[ConflictClause](mod, ptr+48)
144 c.NotNullConflictClause = loadEnum[ConflictClause](mod, ptr+52)
145 c.UniqueConflictClause = loadEnum[ConflictClause](mod, ptr+56)
147 c.CheckExpr = loadString(mod, ptr+60, sql)
148 c.DefaultExpr = loadString(mod, ptr+68, sql)
149 c.CollateName = loadString(mod, ptr+76, sql)
151 if ptr, _ := mod.Memory().ReadUint32Le(ptr + 84); ptr != 0 {
152 c.ForeignKeyClause = &ForeignKey{}
153 c.ForeignKeyClause.load(mod, ptr, sql)
157type ForeignKey struct {
166func (f *ForeignKey) load(mod api.Module, ptr uint32, sql string) {
167 f.Table = loadString(mod, ptr+0, sql)
169 f.Columns = loadSlice(mod, ptr+8, func(ptr uint32, ret *string) {
170 *ret = loadString(mod, ptr, sql)
173 f.OnDelete = loadEnum[FKAction](mod, ptr+16)
174 f.OnUpdate = loadEnum[FKAction](mod, ptr+20)
175 f.Match = loadString(mod, ptr+24, sql)
176 f.Deferrable = loadEnum[FKDefType](mod, ptr+32)
179func loadString(mod api.Module, ptr uint32, sql string) string {
180 off, _ := mod.Memory().ReadUint32Le(ptr + 0)
184 len, _ := mod.Memory().ReadUint32Le(ptr + 4)
185 return sql[off-sqlp : off+len-sqlp]
188func loadSlice[T any](mod api.Module, ptr uint32, fn func(uint32, *T)) []T {
189 ref, _ := mod.Memory().ReadUint32Le(ptr + 4)
193 len, _ := mod.Memory().ReadUint32Le(ptr + 0)
194 ret := make([]T, len)
202func loadEnum[T ~uint32](mod api.Module, ptr uint32) T {
203 val, _ := mod.Memory().ReadUint32Le(ptr)
207func loadBool(mod api.Module, ptr uint32) bool {
208 val, _ := mod.Memory().ReadByte(ptr)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list