Skip to content

Commit 17e7864

Browse files
Copilotgit-hulk
andauthored
Add support for SHOW and DESC/DESCRIBE statements (#180)
Co-authored-by: Copilot <[email protected]> Co-authored-by: git-hulk <[email protected]>
1 parent 4f49fc6 commit 17e7864

20 files changed

+269
-5
lines changed

parser/ast.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8225,3 +8225,73 @@ func (g *GrantPrivilegeStmt) Accept(visitor ASTVisitor) error {
82258225
}
82268226
return visitor.VisitGrantPrivilegeExpr(g)
82278227
}
8228+
8229+
type ShowStmt struct {
8230+
ShowPos Pos
8231+
StatementEnd Pos
8232+
ShowType string // e.g., "CREATE TABLE", "DATABASES", "TABLES"
8233+
Target *TableIdentifier // for SHOW CREATE TABLE table_name
8234+
}
8235+
8236+
func (s *ShowStmt) Pos() Pos {
8237+
return s.ShowPos
8238+
}
8239+
8240+
func (s *ShowStmt) End() Pos {
8241+
if s.Target != nil {
8242+
return s.Target.End()
8243+
}
8244+
return s.StatementEnd
8245+
}
8246+
8247+
func (s *ShowStmt) String() string {
8248+
var builder strings.Builder
8249+
builder.WriteString("SHOW ")
8250+
builder.WriteString(s.ShowType)
8251+
if s.Target != nil {
8252+
builder.WriteString(" ")
8253+
builder.WriteString(s.Target.String())
8254+
}
8255+
return builder.String()
8256+
}
8257+
8258+
func (s *ShowStmt) Accept(visitor ASTVisitor) error {
8259+
visitor.Enter(s)
8260+
defer visitor.Leave(s)
8261+
if s.Target != nil {
8262+
if err := s.Target.Accept(visitor); err != nil {
8263+
return err
8264+
}
8265+
}
8266+
return visitor.VisitShowExpr(s)
8267+
}
8268+
8269+
type DescribeStmt struct {
8270+
DescribePos Pos
8271+
StatementEnd Pos
8272+
Target *TableIdentifier
8273+
}
8274+
8275+
func (d *DescribeStmt) Pos() Pos {
8276+
return d.DescribePos
8277+
}
8278+
8279+
func (d *DescribeStmt) End() Pos {
8280+
return d.Target.End()
8281+
}
8282+
8283+
func (d *DescribeStmt) String() string {
8284+
var builder strings.Builder
8285+
builder.WriteString("DESCRIBE ")
8286+
builder.WriteString(d.Target.String())
8287+
return builder.String()
8288+
}
8289+
8290+
func (d *DescribeStmt) Accept(visitor ASTVisitor) error {
8291+
visitor.Enter(d)
8292+
defer visitor.Leave(d)
8293+
if err := d.Target.Accept(visitor); err != nil {
8294+
return err
8295+
}
8296+
return visitor.VisitDescribeExpr(d)
8297+
}

parser/ast_visitor.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ type ASTVisitor interface {
178178
VisitExplainExpr(expr *ExplainStmt) error
179179
VisitPrivilegeExpr(expr *PrivilegeClause) error
180180
VisitGrantPrivilegeExpr(expr *GrantPrivilegeStmt) error
181+
VisitShowExpr(expr *ShowStmt) error
182+
VisitDescribeExpr(expr *DescribeStmt) error
181183
VisitSelectItem(expr *SelectItem) error
182184
VisitTargetPairExpr(expr *TargetPair) error
183185

@@ -1430,6 +1432,20 @@ func (v *DefaultASTVisitor) VisitGrantPrivilegeExpr(expr *GrantPrivilegeStmt) er
14301432
return nil
14311433
}
14321434

1435+
func (v *DefaultASTVisitor) VisitShowExpr(expr *ShowStmt) error {
1436+
if v.Visit != nil {
1437+
return v.Visit(expr)
1438+
}
1439+
return nil
1440+
}
1441+
1442+
func (v *DefaultASTVisitor) VisitDescribeExpr(expr *DescribeStmt) error {
1443+
if v.Visit != nil {
1444+
return v.Visit(expr)
1445+
}
1446+
return nil
1447+
}
1448+
14331449
func (v *DefaultASTVisitor) VisitSelectItem(expr *SelectItem) error {
14341450
if v.Visit != nil {
14351451
return v.Visit(expr)

parser/parser_table.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,10 @@ func (p *Parser) parseStmt(pos Pos) (Expr, error) {
11161116
expr, err = p.parseExplainStmt(pos)
11171117
case p.matchKeyword(KeywordGrant):
11181118
expr, err = p.parseGrantPrivilegeStmt(pos)
1119+
case p.matchKeyword(KeywordShow):
1120+
expr, err = p.parseShowStmt(pos)
1121+
case p.matchKeyword(KeywordDesc), p.matchKeyword(KeywordDescribe):
1122+
expr, err = p.parseDescribeStmt(pos)
11191123
default:
11201124
return nil, fmt.Errorf("unexpected token: %q", p.last().String)
11211125
}
@@ -1170,6 +1174,80 @@ func (p *Parser) parseUseStmt(pos Pos) (*UseStmt, error) {
11701174
}, nil
11711175
}
11721176

1177+
func (p *Parser) parseShowStmt(pos Pos) (*ShowStmt, error) {
1178+
if err := p.expectKeyword(KeywordShow); err != nil {
1179+
return nil, err
1180+
}
1181+
1182+
var showType string
1183+
var target *TableIdentifier
1184+
1185+
// Parse the type of SHOW statement
1186+
switch {
1187+
case p.matchKeyword(KeywordCreate):
1188+
// SHOW CREATE TABLE table_name
1189+
showType = "CREATE"
1190+
_ = p.lexer.consumeToken()
1191+
1192+
if err := p.expectKeyword(KeywordTable); err != nil {
1193+
return nil, err
1194+
}
1195+
showType += " TABLE"
1196+
1197+
tableIdent, err := p.parseTableIdentifier(p.Pos())
1198+
if err != nil {
1199+
return nil, err
1200+
}
1201+
target = tableIdent
1202+
1203+
case p.matchKeyword(KeywordDatabases):
1204+
// SHOW DATABASES
1205+
showType = "DATABASES"
1206+
_ = p.lexer.consumeToken()
1207+
1208+
case p.matchKeyword(KeywordTables):
1209+
// SHOW TABLES
1210+
showType = "TABLES"
1211+
_ = p.lexer.consumeToken()
1212+
1213+
default:
1214+
return nil, fmt.Errorf("expected CREATE, DATABASES, or TABLES after SHOW, got %q", p.last().String)
1215+
}
1216+
1217+
var statementEnd Pos
1218+
if target != nil {
1219+
statementEnd = target.End()
1220+
} else {
1221+
statementEnd = p.End()
1222+
}
1223+
1224+
return &ShowStmt{
1225+
ShowPos: pos,
1226+
StatementEnd: statementEnd,
1227+
ShowType: showType,
1228+
Target: target,
1229+
}, nil
1230+
}
1231+
1232+
func (p *Parser) parseDescribeStmt(pos Pos) (*DescribeStmt, error) {
1233+
// DESC and DESCRIBE are both supported
1234+
if !p.matchKeyword(KeywordDesc) && !p.matchKeyword(KeywordDescribe) {
1235+
return nil, fmt.Errorf("expected DESC or DESCRIBE")
1236+
}
1237+
_ = p.lexer.consumeToken()
1238+
1239+
tableIdent, err := p.parseTableIdentifier(p.Pos())
1240+
if err != nil {
1241+
return nil, err
1242+
}
1243+
1244+
return &DescribeStmt{
1245+
DescribePos: pos,
1246+
StatementEnd: tableIdent.End(),
1247+
Target: tableIdent,
1248+
}, nil
1249+
}
1250+
11731251
// syntax: TRUNCATE TEMPORARY? TABLE (IF EXISTS)? tableIdentifier clusterClause?;
11741252
func (p *Parser) parseTruncateTable(pos Pos) (*TruncateTable, error) {
11751253
if err := p.expectKeyword(KeywordTruncate); err != nil {

parser/testdata/ddl/desc_table.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DESC mytable
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DESCRIBE mytable
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
DESC mytable
3+
4+
-- Format SQL:
5+
DESCRIBE mytable;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
DESCRIBE mytable
3+
4+
-- Format SQL:
5+
DESCRIBE mytable;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW CREATE TABLE mytable
3+
4+
-- Format SQL:
5+
SHOW CREATE TABLE mytable;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES
3+
4+
-- Format SQL:
5+
SHOW DATABASES;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW TABLES
3+
4+
-- Format SQL:
5+
SHOW TABLES;

0 commit comments

Comments
 (0)