Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 8 additions & 24 deletions parser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ type AlterTable struct {
TableIdentifier *TableIdentifier
OnCluster *ClusterClause
AlterExprs []AlterTableClause
// Settings holds the query-level SETTINGS clause. ClickHouse only
// accepts it once, after the last alter clause.
Settings *SettingsClause
}

func (a *AlterTable) Pos() Pos {
Expand Down Expand Up @@ -233,6 +236,11 @@ func (a *AlterTable) Accept(visitor ASTVisitor) error {
return err
}
}
if a.Settings != nil {
if err := a.Settings.Accept(visitor); err != nil {
return err
}
}
return visitor.VisitAlterTable(a)
}

Expand Down Expand Up @@ -275,7 +283,6 @@ func (a *AlterTableAttachPartition) Accept(visitor ASTVisitor) error {
type AlterTableDetachPartition struct {
DetachPos Pos
Partition *PartitionClause
Settings *SettingsClause
}

func (a *AlterTableDetachPartition) Pos() Pos {
Expand All @@ -296,29 +303,20 @@ func (a *AlterTableDetachPartition) Accept(visitor ASTVisitor) error {
if err := a.Partition.Accept(visitor); err != nil {
return err
}
if a.Settings != nil {
if err := a.Settings.Accept(visitor); err != nil {
return err
}
}
return visitor.VisitAlterTableDetachPartition(a)
}

type AlterTableDropPartition struct {
DropPos Pos
HasDetached bool
Partition *PartitionClause
Settings *SettingsClause
}

func (a *AlterTableDropPartition) Pos() Pos {
return a.DropPos
}

func (a *AlterTableDropPartition) End() Pos {
if a.Settings != nil {
return a.Settings.End()
}
return a.Partition.End()
}

Expand All @@ -332,11 +330,6 @@ func (a *AlterTableDropPartition) Accept(visitor ASTVisitor) error {
if err := a.Partition.Accept(visitor); err != nil {
return err
}
if a.Settings != nil {
if err := a.Settings.Accept(visitor); err != nil {
return err
}
}
return visitor.VisitAlterTableDropPartition(a)
}

Expand Down Expand Up @@ -444,17 +437,13 @@ type AlterTableAddColumn struct {
Column *ColumnDef
IfNotExists bool
After *NestedIdentifier
Settings *SettingsClause
}

func (a *AlterTableAddColumn) Pos() Pos {
return a.AddPos
}

func (a *AlterTableAddColumn) End() Pos {
if a.Settings != nil {
return a.Settings.End()
}
return a.StatementEnd
}

Expand All @@ -473,11 +462,6 @@ func (a *AlterTableAddColumn) Accept(visitor ASTVisitor) error {
return err
}
}
if a.Settings != nil {
if err := a.Settings.Accept(visitor); err != nil {
return err
}
}
return visitor.VisitAlterTableAddColumn(a)
}

Expand Down
26 changes: 12 additions & 14 deletions parser/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ func (a *AlterTable) FormatSQL(formatter *Formatter) {
formatter.WriteString(",")
}
}
if a.Settings != nil {
formatter.Break()
formatter.WriteExpr(a.Settings)
}
}

func (a *AlterTableAddColumn) FormatSQL(formatter *Formatter) {
Expand All @@ -242,18 +246,14 @@ func (a *AlterTableAddColumn) FormatSQL(formatter *Formatter) {
formatter.WriteString(" AFTER ")
formatter.WriteExpr(a.After)
}
if a.Settings != nil {
formatter.Break()
formatter.WriteExpr(a.Settings)
}
}

func (a *AlterTableAddIndex) FormatSQL(formatter *Formatter) {
formatter.WriteString("ADD ")
formatter.WriteString("ADD INDEX ")
if a.IfNotExists {
formatter.WriteString("IF NOT EXISTS ")
}
formatter.WriteExpr(a.Index)
a.Index.formatDefinition(formatter)
if a.After != nil {
formatter.WriteString(" AFTER ")
formatter.WriteExpr(a.After)
Expand Down Expand Up @@ -333,10 +333,6 @@ func (a *AlterTableDelete) FormatSQL(formatter *Formatter) {
func (a *AlterTableDetachPartition) FormatSQL(formatter *Formatter) {
formatter.WriteString("DETACH ")
formatter.WriteExpr(a.Partition)
if a.Settings != nil {
formatter.Break()
formatter.WriteExpr(a.Settings)
}
}

func (a *AlterTableDropColumn) FormatSQL(formatter *Formatter) {
Expand All @@ -361,10 +357,6 @@ func (a *AlterTableDropPartition) FormatSQL(formatter *Formatter) {
formatter.WriteString("DETACHED ")
}
formatter.WriteExpr(a.Partition)
if a.Settings != nil {
formatter.Break()
formatter.WriteExpr(a.Settings)
}
}

func (a *AlterTableDropProjection) FormatSQL(formatter *Formatter) {
Expand Down Expand Up @@ -2656,6 +2648,12 @@ func (t *TableIdentifier) FormatSQL(formatter *Formatter) {
func (a *TableIndex) FormatSQL(formatter *Formatter) {
formatter.WriteString("INDEX")
formatter.WriteByte(whitespace)
a.formatDefinition(formatter)
}

// formatDefinition writes everything after the INDEX keyword, so ALTER TABLE
// can place IF NOT EXISTS between INDEX and the index name.
func (a *TableIndex) formatDefinition(formatter *Formatter) {
formatter.WriteExpr(a.Name)
// Add space only if column expression doesn't start with '('
columnExprStr := Format(a.ColumnExpr)
Expand Down
30 changes: 9 additions & 21 deletions parser/parser_alter.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,15 @@ func (p *Parser) parseAlterTable(pos Pos) (*AlterTable, error) {
}
alterTable.StatementEnd = alterTable.AlterExprs[len(alterTable.AlterExprs)-1].End()

settings, err := p.tryParseSettingsClause(p.Pos())
if err != nil {
return nil, err
}
if settings != nil {
alterTable.Settings = settings
alterTable.StatementEnd = settings.End()
}

return alterTable, nil
}

Expand Down Expand Up @@ -120,21 +129,12 @@ func (p *Parser) parseAlterTableAddColumn(pos Pos) (*AlterTableAddColumn, error)
statementEnd = after.End()
}

settings, err := p.tryParseSettingsClause(p.Pos())
if err != nil {
return nil, err
}
if settings != nil {
statementEnd = settings.End()
}

return &AlterTableAddColumn{
AddPos: pos,
StatementEnd: statementEnd,
Column: column,
IfNotExists: ifNotExists,
After: after,
Settings: settings,
}, nil
}

Expand Down Expand Up @@ -342,15 +342,9 @@ func (p *Parser) parseAlterTableDetachPartition(pos Pos) (AlterTableClause, erro
}
partition.Expr = expr

settings, err := p.tryParseSettingsClause(p.Pos())
if err != nil {
return nil, err
}

return &AlterTableDetachPartition{
DetachPos: pos,
Partition: partition,
Settings: settings,
}, nil
}

Expand Down Expand Up @@ -483,16 +477,10 @@ func (p *Parser) parseAlterTableDropPartition(pos Pos) (AlterTableClause, error)
}
partition.Expr = expr

settings, err := p.tryParseSettingsClause(p.Pos())
if err != nil {
return nil, err
}

return &AlterTableDropPartition{
DropPos: pos,
Partition: partition,
HasDetached: hasDetached,
Settings: settings,
}, nil
}

Expand Down
11 changes: 5 additions & 6 deletions parser/position_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,13 @@ func TestAlterDetachPartitionPos(t *testing.T) {
require.Equal(t, Pos(14), detach.Pos())
}

func TestAlterDropPartitionEndIncludesSettings(t *testing.T) {
func TestAlterTableEndIncludesSettings(t *testing.T) {
sql := "ALTER TABLE t DROP PARTITION p SETTINGS mutations_sync=1"
stmt := parseOneStmt(t, sql).(*AlterTable)
drop := stmt.AlterExprs[0].(*AlterTableDropPartition)
require.NotNil(t, drop.Settings)
// End() used to discard the Settings end and stop at the partition
require.Equal(t, drop.Settings.End(), drop.End())
require.Greater(t, drop.End(), drop.Partition.End())
require.NotNil(t, stmt.Settings)
// End() used to discard the Settings end and stop at the last alter clause
require.Equal(t, stmt.Settings.End(), stmt.End())
require.Greater(t, stmt.End(), stmt.AlterExprs[0].End())
}

func TestDictionaryAttributeEnd(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions parser/testdata/ddl/alter_table_add_index.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX IF NOT EXISTS created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync = 2;
3 changes: 3 additions & 0 deletions parser/testdata/ddl/alter_table_settings.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE test.events_local MODIFY COLUMN f0 Int64 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ADD COLUMN f1 String, DROP COLUMN f2 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' MATERIALIZE INDEX IF EXISTS created_at_idx SETTINGS mutations_sync = 2;
4 changes: 4 additions & 0 deletions parser/testdata/ddl/format/alter_table_add_index.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX IF NOT EXISTS created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync = 2;


-- Format SQL:
Expand All @@ -12,3 +14,5 @@ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync=2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX IF NOT EXISTS created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync=2;
10 changes: 10 additions & 0 deletions parser/testdata/ddl/format/alter_table_settings.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- Origin SQL:
ALTER TABLE test.events_local MODIFY COLUMN f0 Int64 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ADD COLUMN f1 String, DROP COLUMN f2 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' MATERIALIZE INDEX IF EXISTS created_at_idx SETTINGS mutations_sync = 2;


-- Format SQL:
ALTER TABLE test.events_local MODIFY COLUMN f0 Int64 SETTINGS alter_sync=2;
ALTER TABLE test.events_local ADD COLUMN f1 String, DROP COLUMN f2 SETTINGS alter_sync=2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' MATERIALIZE INDEX IF EXISTS created_at_idx SETTINGS mutations_sync=2;
12 changes: 12 additions & 0 deletions parser/testdata/ddl/format/beautify/alter_table_add_index.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX api_id_idx
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX arr_idx arr TYPE bloom_filter(0.01) GRANULARITY 3;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' ADD INDEX IF NOT EXISTS created_at_idx created_at TYPE minmax GRANULARITY 1 SETTINGS alter_sync = 2;


-- Beautify SQL:
Expand All @@ -22,3 +24,13 @@ ADD INDEX content_idx content TYPE tokenbf_v1(30720, 2, 0) GRANULARITY 1;
ALTER TABLE test.events_local
ON CLUSTER 'default_cluster'
ADD INDEX output_idx output TYPE ngrambf_v1(3, 10000, 2, 1) GRANULARITY 2;
ALTER TABLE test.events_local
ON CLUSTER 'default_cluster'
ADD INDEX created_at_idx created_at TYPE minmax GRANULARITY 1
SETTINGS
alter_sync=2;
ALTER TABLE test.events_local
ON CLUSTER 'default_cluster'
ADD INDEX IF NOT EXISTS created_at_idx created_at TYPE minmax GRANULARITY 1
SETTINGS
alter_sync=2;
21 changes: 21 additions & 0 deletions parser/testdata/ddl/format/beautify/alter_table_settings.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- Origin SQL:
ALTER TABLE test.events_local MODIFY COLUMN f0 Int64 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ADD COLUMN f1 String, DROP COLUMN f2 SETTINGS alter_sync = 2;
ALTER TABLE test.events_local ON CLUSTER 'default_cluster' MATERIALIZE INDEX IF EXISTS created_at_idx SETTINGS mutations_sync = 2;


-- Beautify SQL:
ALTER TABLE test.events_local
MODIFY COLUMN f0 Int64
SETTINGS
alter_sync=2;
ALTER TABLE test.events_local
ADD COLUMN f1 String,
DROP COLUMN f2
SETTINGS
alter_sync=2;
ALTER TABLE test.events_local
ON CLUSTER 'default_cluster'
MATERIALIZE INDEX IF EXISTS created_at_idx
SETTINGS
mutations_sync=2;
Loading
Loading