Skip to content

Commit 5b6fdc6

Browse files
Copilotgit-hulk
andauthored
Enhance SHOW DATABASES statement to support LIKE, ILIKE, LIMIT, OUTFILE, and FORMAT clauses (#182)
--------- Co-authored-by: Copilot <[email protected]> Co-authored-by: git-hulk <[email protected]>
1 parent 17e7864 commit 5b6fdc6

34 files changed

+469
-16
lines changed

parser/ast.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8231,13 +8231,34 @@ type ShowStmt struct {
82318231
StatementEnd Pos
82328232
ShowType string // e.g., "CREATE TABLE", "DATABASES", "TABLES"
82338233
Target *TableIdentifier // for SHOW CREATE TABLE table_name
8234+
8235+
// Optional clauses for SHOW DATABASES
8236+
NotLike bool // true if NOT LIKE/ILIKE
8237+
LikeType string // "LIKE" or "ILIKE", empty if not used
8238+
LikePattern Expr // pattern expression for LIKE/ILIKE
8239+
Limit Expr // limit expression
8240+
OutFile *StringLiteral // filename for INTO OUTFILE
8241+
Format *StringLiteral // format specification
82348242
}
82358243

82368244
func (s *ShowStmt) Pos() Pos {
82378245
return s.ShowPos
82388246
}
82398247

82408248
func (s *ShowStmt) End() Pos {
8249+
// Find the rightmost element to determine the end position
8250+
if s.Format != nil {
8251+
return s.Format.End()
8252+
}
8253+
if s.OutFile != nil {
8254+
return s.OutFile.End()
8255+
}
8256+
if s.Limit != nil {
8257+
return s.Limit.End()
8258+
}
8259+
if s.LikePattern != nil {
8260+
return s.LikePattern.End()
8261+
}
82418262
if s.Target != nil {
82428263
return s.Target.End()
82438264
}
@@ -8252,6 +8273,34 @@ func (s *ShowStmt) String() string {
82528273
builder.WriteString(" ")
82538274
builder.WriteString(s.Target.String())
82548275
}
8276+
8277+
// Add optional clauses for SHOW DATABASES
8278+
if s.LikeType != "" && s.LikePattern != nil {
8279+
if s.NotLike {
8280+
builder.WriteString(" NOT ")
8281+
} else {
8282+
builder.WriteString(" ")
8283+
}
8284+
builder.WriteString(s.LikeType)
8285+
builder.WriteString(" ")
8286+
builder.WriteString(s.LikePattern.String())
8287+
}
8288+
8289+
if s.Limit != nil {
8290+
builder.WriteString(" LIMIT ")
8291+
builder.WriteString(s.Limit.String())
8292+
}
8293+
8294+
if s.OutFile != nil {
8295+
builder.WriteString(" INTO OUTFILE ")
8296+
builder.WriteString(s.OutFile.String())
8297+
}
8298+
8299+
if s.Format != nil {
8300+
builder.WriteString(" FORMAT ")
8301+
builder.WriteString(s.Format.String())
8302+
}
8303+
82558304
return builder.String()
82568305
}
82578306

@@ -8263,6 +8312,26 @@ func (s *ShowStmt) Accept(visitor ASTVisitor) error {
82638312
return err
82648313
}
82658314
}
8315+
if s.LikePattern != nil {
8316+
if err := s.LikePattern.Accept(visitor); err != nil {
8317+
return err
8318+
}
8319+
}
8320+
if s.Limit != nil {
8321+
if err := s.Limit.Accept(visitor); err != nil {
8322+
return err
8323+
}
8324+
}
8325+
if s.OutFile != nil {
8326+
if err := s.OutFile.Accept(visitor); err != nil {
8327+
return err
8328+
}
8329+
}
8330+
if s.Format != nil {
8331+
if err := s.Format.Accept(visitor); err != nil {
8332+
return err
8333+
}
8334+
}
82668335
return visitor.VisitShowExpr(s)
82678336
}
82688337

parser/parser_table.go

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@ func (p *Parser) parseShowStmt(pos Pos) (*ShowStmt, error) {
12011201
target = tableIdent
12021202

12031203
case p.matchKeyword(KeywordDatabases):
1204-
// SHOW DATABASES
1204+
// SHOW DATABASES [optional clauses]
12051205
showType = "DATABASES"
12061206
_ = p.lexer.consumeToken()
12071207

@@ -1214,19 +1214,91 @@ func (p *Parser) parseShowStmt(pos Pos) (*ShowStmt, error) {
12141214
return nil, fmt.Errorf("expected CREATE, DATABASES, or TABLES after SHOW, got %q", p.last().String)
12151215
}
12161216

1217-
var statementEnd Pos
1218-
if target != nil {
1219-
statementEnd = target.End()
1220-
} else {
1221-
statementEnd = p.End()
1217+
stmt := &ShowStmt{
1218+
ShowPos: pos,
1219+
ShowType: showType,
1220+
Target: target,
12221221
}
12231222

1224-
return &ShowStmt{
1225-
ShowPos: pos,
1226-
StatementEnd: statementEnd,
1227-
ShowType: showType,
1228-
Target: target,
1229-
}, nil
1223+
// Parse optional clauses for SHOW DATABASES
1224+
if showType == "DATABASES" {
1225+
// Parse [[NOT] LIKE | ILIKE '<pattern>']
1226+
if p.matchKeyword(KeywordNot) {
1227+
stmt.NotLike = true
1228+
_ = p.lexer.consumeToken()
1229+
}
1230+
1231+
if p.matchKeyword(KeywordLike) || p.matchKeyword(KeywordIlike) {
1232+
if p.matchKeyword(KeywordLike) {
1233+
stmt.LikeType = "LIKE"
1234+
} else {
1235+
stmt.LikeType = "ILIKE"
1236+
}
1237+
_ = p.lexer.consumeToken()
1238+
1239+
// Parse pattern expression
1240+
pattern, err := p.parseExpr(p.Pos())
1241+
if err != nil {
1242+
return nil, err
1243+
}
1244+
stmt.LikePattern = pattern
1245+
}
1246+
1247+
// Parse [LIMIT <N>]
1248+
if p.matchKeyword(KeywordLimit) {
1249+
_ = p.lexer.consumeToken()
1250+
limit, err := p.parseExpr(p.Pos())
1251+
if err != nil {
1252+
return nil, err
1253+
}
1254+
stmt.Limit = limit
1255+
}
1256+
1257+
// Parse [INTO OUTFILE filename]
1258+
if p.matchKeyword(KeywordInto) {
1259+
_ = p.lexer.consumeToken()
1260+
if err := p.expectKeyword(KeywordOutfile); err != nil {
1261+
return nil, err
1262+
}
1263+
1264+
// Parse filename as a string literal
1265+
outFile, err := p.parseString(p.Pos())
1266+
if err != nil {
1267+
return nil, err
1268+
}
1269+
stmt.OutFile = outFile
1270+
}
1271+
1272+
// Parse [FORMAT format]
1273+
if p.matchKeyword(KeywordFormat) {
1274+
_ = p.lexer.consumeToken()
1275+
1276+
// Format can be an identifier or a string
1277+
if p.matchTokenKind(TokenKindString) {
1278+
format, err := p.parseString(p.Pos())
1279+
if err != nil {
1280+
return nil, err
1281+
}
1282+
stmt.Format = format
1283+
} else if p.matchTokenKind(TokenKindIdent) {
1284+
// Handle format as identifier (like JSON, CSV, etc.)
1285+
token := p.last()
1286+
_ = p.lexer.consumeToken()
1287+
stmt.Format = &StringLiteral{
1288+
LiteralPos: token.Pos,
1289+
LiteralEnd: token.End,
1290+
Literal: token.String,
1291+
}
1292+
} else {
1293+
return nil, fmt.Errorf("expected format specification after FORMAT, got %q", p.last().String)
1294+
}
1295+
}
1296+
}
1297+
1298+
// Set statement end position
1299+
stmt.StatementEnd = p.End()
1300+
1301+
return stmt, nil
12301302
}
12311303

12321304
func (p *Parser) parseDescribeStmt(pos Pos) (*DescribeStmt, error) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT JSON
3+
4+
-- Format SQL:
5+
SHOW DATABASES LIKE 'prod%' LIMIT 5 INTO OUTFILE '/tmp/prod_dbs.txt' FORMAT 'JSON';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES FORMAT JSON
3+
4+
-- Format SQL:
5+
SHOW DATABASES FORMAT 'JSON';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES FORMAT 'TabSeparated'
3+
4+
-- Format SQL:
5+
SHOW DATABASES FORMAT 'TabSeparated';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES ILIKE 'Test%'
3+
4+
-- Format SQL:
5+
SHOW DATABASES ILIKE 'Test%';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES LIKE 'test%'
3+
4+
-- Format SQL:
5+
SHOW DATABASES LIKE 'test%';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES LIMIT 10
3+
4+
-- Format SQL:
5+
SHOW DATABASES LIMIT 10;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES NOT ILIKE 'Temp%'
3+
4+
-- Format SQL:
5+
SHOW DATABASES NOT ILIKE 'Temp%';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Origin SQL:
2+
SHOW DATABASES NOT LIKE 'temp%'
3+
4+
-- Format SQL:
5+
SHOW DATABASES NOT LIKE 'temp%';

0 commit comments

Comments
 (0)