From 086b851bb82fa5a8429b4bb99d82986462f0b641 Mon Sep 17 00:00:00 2001 From: apstndb <803393+apstndb@users.noreply.github.com> Date: Mon, 25 May 2026 03:42:08 +0900 Subject: [PATCH] feat: expose ParseSchemaType --- ast/ast.go | 1 + parse_helpers.go | 6 ++++++ parse_helpers_test.go | 13 +++++++++++++ parser.go | 23 +++++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/ast/ast.go b/ast/ast.go index 6fa26736..e012e818 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -528,6 +528,7 @@ func (SizedSchemaType) isSchemaType() {} func (ArraySchemaType) isSchemaType() {} func (StructType) isSchemaType() {} func (NamedType) isSchemaType() {} +func (BadType) isSchemaType() {} // IndexAlteration represents ALTER INDEX action. type IndexAlteration interface { diff --git a/parse_helpers.go b/parse_helpers.go index 6eaafed2..acd51ae4 100644 --- a/parse_helpers.go +++ b/parse_helpers.go @@ -43,6 +43,12 @@ func ParseType(filepath, s string) (ast.Type, error) { return newParser(filepath, s).ParseType() } +// ParseSchemaType parses an input string containing a schema type. +// filepath can be empty, it is only used in error message. +func ParseSchemaType(filepath, s string) (ast.SchemaType, error) { + return newParser(filepath, s).ParseSchemaType() +} + // ParseDDL parses an input string containing a DDL statement. // filepath can be empty, it is only used in error message. func ParseDDL(filepath, s string) (ast.DDL, error) { diff --git a/parse_helpers_test.go b/parse_helpers_test.go index 490e5ee6..1f3bb49c 100644 --- a/parse_helpers_test.go +++ b/parse_helpers_test.go @@ -70,6 +70,19 @@ func ExampleParseType() { // Output: // ARRAY> } + +func ExampleParseSchemaType() { + typ, err := memefish.ParseSchemaType("", "ARRAY") + if err != nil { + panic(err) + } + + fmt.Println(typ.SQL()) + + // Output: + // ARRAY +} + func ExampleParseDDL() { sql := heredoc.Doc(` CREATE TABLE foo ( diff --git a/parser.go b/parser.go index 4ced5189..4111faf7 100644 --- a/parser.go +++ b/parser.go @@ -137,6 +137,29 @@ func (p *Parser) ParseType() (ast.Type, error) { return t, nil } +// ParseSchemaType parses a schema type. +func (p *Parser) ParseSchemaType() (t ast.SchemaType, err error) { + p.nextToken() + l := p.Clone() + defer func() { + if r := recover(); r != nil { + t = p.handleParseTypeError(r, l) + } + if len(p.errors) > 0 { + // Reset the errors and allow processing to continue + err = MultiError(p.errors) + p.errors = nil + } + }() + + t = p.parseSchemaType() + if p.Token.Kind != token.TokenEOF { + p.errors = append(p.errors, p.errorfAtToken(&p.Token, "expected token: , but: %s", p.Token.Kind)) + } + + return t, nil +} + // ParseDDL parses a CREATE/ALTER/DROP statement. func (p *Parser) ParseDDL() (ast.DDL, error) { p.nextToken()