Skip to content

Commit 3201167

Browse files
committed
Add support for nested named/unnamed tuple types
1 parent c35e37e commit 3201167

File tree

4 files changed

+608
-2
lines changed

4 files changed

+608
-2
lines changed

parser/parser_column.go

Lines changed: 123 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -901,11 +901,16 @@ func (p *Parser) parseColumnCaseExpr(pos Pos) (*CaseExpr, error) {
901901
return caseExpr, nil
902902
}
903903

904-
func (p *Parser) parseColumnType(_ Pos) (ColumnType, error) { // nolint:funlen
904+
func (p *Parser) parseColumnType(_ Pos) (ColumnType, error) {
905905
ident, err := p.parseIdent()
906906
if err != nil {
907907
return nil, err
908908
}
909+
910+
return p.parseColumnTypeArgs(ident)
911+
}
912+
913+
func (p *Parser) parseColumnTypeArgs(ident *Ident) (ColumnType, error) { // nolint:funlen
909914
if lParen := p.tryConsumeTokenKind(TokenKindLParen); lParen != nil {
910915
switch {
911916
case p.matchTokenKind(TokenKindIdent):
@@ -1185,10 +1190,11 @@ func (p *Parser) parseJSONType(name *Ident, pos Pos) (*JSONType, error) {
11851190
}
11861191

11871192
func (p *Parser) parseNestedType(name *Ident, pos Pos) (*NestedType, error) {
1188-
columns, err := p.parseTableColumns()
1193+
columns, err := p.parseNestedTypeFields()
11891194
if err != nil {
11901195
return nil, err
11911196
}
1197+
11921198
rightParenPos := p.Pos()
11931199
if err := p.expectTokenKind(TokenKindRParen); err != nil {
11941200
return nil, err
@@ -1201,6 +1207,121 @@ func (p *Parser) parseNestedType(name *Ident, pos Pos) (*NestedType, error) {
12011207
}, nil
12021208
}
12031209

1210+
func (p *Parser) parseNestedTypeFields() ([]Expr, error) {
1211+
switch {
1212+
case p.lexer.isEOF() || p.matchTokenKind(TokenKindRParen):
1213+
// Cases like `Tuple()`
1214+
return []Expr{}, nil
1215+
case p.matchTokenKind(TokenKindIdent):
1216+
ident, err := p.parseIdent()
1217+
if err != nil {
1218+
return nil, err
1219+
}
1220+
1221+
if p.matchTokenKind(TokenKindIdent) {
1222+
// Cases like `Tuple(a Int, b String)` or `Nested(a Int, b String)`
1223+
return p.parseNestedTypeFieldsWithNames(ident)
1224+
}
1225+
1226+
// Cases like `Tuple(Int, String)`
1227+
return p.parseNestedTypeFieldsWithoutNames(ident)
1228+
default:
1229+
return nil, fmt.Errorf("unexpected token kind: %s", p.lastTokenKind())
1230+
}
1231+
}
1232+
1233+
func (p *Parser) parseNestedTypeFieldsWithNames(firstIdent *Ident) ([]Expr, error) {
1234+
columns := make([]Expr, 0)
1235+
1236+
columnType, err := p.parseColumnType(p.Pos())
1237+
if err != nil {
1238+
return nil, err
1239+
}
1240+
1241+
columns = append(columns, &ColumnDef{
1242+
NamePos: firstIdent.Pos(),
1243+
Name: &NestedIdentifier{
1244+
Ident: firstIdent,
1245+
},
1246+
Type: columnType,
1247+
ColumnEnd: columnType.End(),
1248+
})
1249+
1250+
if p.tryConsumeTokenKind(TokenKindComma) == nil {
1251+
return columns, nil
1252+
}
1253+
1254+
for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {
1255+
column, err := p.parseNestedTypeFieldWithName()
1256+
if err != nil {
1257+
return nil, err
1258+
}
1259+
if column == nil {
1260+
break
1261+
}
1262+
columns = append(columns, column)
1263+
1264+
if p.tryConsumeTokenKind(TokenKindComma) == nil {
1265+
break
1266+
}
1267+
}
1268+
1269+
return columns, nil
1270+
}
1271+
1272+
func (p *Parser) parseNestedTypeFieldsWithoutNames(firstIdent *Ident) ([]Expr, error) {
1273+
columns := make([]Expr, 0)
1274+
1275+
column, err := p.parseColumnTypeArgs(firstIdent)
1276+
if err != nil {
1277+
return nil, err
1278+
}
1279+
1280+
columns = append(columns, column)
1281+
1282+
if p.tryConsumeTokenKind(TokenKindComma) == nil {
1283+
return columns, nil
1284+
}
1285+
1286+
for !p.lexer.isEOF() && !p.matchTokenKind(TokenKindRParen) {
1287+
column, err := p.parseColumnType(p.Pos())
1288+
if err != nil {
1289+
return nil, err
1290+
}
1291+
if column == nil {
1292+
break
1293+
}
1294+
columns = append(columns, column)
1295+
1296+
if p.tryConsumeTokenKind(TokenKindComma) == nil {
1297+
break
1298+
}
1299+
}
1300+
1301+
return columns, nil
1302+
}
1303+
1304+
func (p *Parser) parseNestedTypeFieldWithName() (Expr, error) {
1305+
name, err := p.parseIdent()
1306+
if err != nil {
1307+
return nil, err
1308+
}
1309+
1310+
columnType, err := p.parseColumnType(p.Pos())
1311+
if err != nil {
1312+
return nil, err
1313+
}
1314+
1315+
return &ColumnDef{
1316+
NamePos: name.Pos(),
1317+
Name: &NestedIdentifier{
1318+
Ident: name,
1319+
},
1320+
Type: columnType,
1321+
ColumnEnd: columnType.End(),
1322+
}, nil
1323+
}
1324+
12041325
func (p *Parser) tryParseCompressionCodecs(pos Pos) (*CompressionCodec, error) {
12051326
if !p.tryConsumeKeywords(KeywordCodec) {
12061327
return nil, nil // nolint
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CREATE TABLE t0 on cluster default_cluster
2+
(
3+
`tup0` Tuple(),
4+
`tup1` Tuple(String, Int64),
5+
`tup2` Tuple(String, Tuple(String, String)),
6+
`tup3` Tuple(a String, cd Tuple(c String, d String))
7+
)
8+
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')
9+
ORDER BY (tup1, tup2, tup3)
10+
SETTINGS index_granularity = 8192;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- Origin SQL:
2+
CREATE TABLE t0 on cluster default_cluster
3+
(
4+
`tup0` Tuple(),
5+
`tup1` Tuple(String, Int64),
6+
`tup2` Tuple(String, Tuple(String, String)),
7+
`tup3` Tuple(a String, cd Tuple(c String, d String))
8+
)
9+
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}')
10+
ORDER BY (tup1, tup2, tup3)
11+
SETTINGS index_granularity = 8192;
12+
13+
14+
-- Format SQL:
15+
CREATE TABLE t0 ON CLUSTER default_cluster (`tup0` Tuple(), `tup1` Tuple(String, Int64), `tup2` Tuple(String, Tuple(String, String)), `tup3` Tuple(a String, cd Tuple(c String, d String))) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{layer}-{shard}', '{replica}') ORDER BY (tup1, tup2, tup3) SETTINGS index_granularity=8192;

0 commit comments

Comments
 (0)