Skip to content

Commit

Permalink
Make default create table template suitable for ClickHouse
Browse files Browse the repository at this point in the history
This changes the default TableTemplate of the SQL output plugin so that
it can be used with ClickHouse. Previously it was invalid for ClickHouse
because it didn't include a PRIMARY KEY or ORDER BY clause, which is
required for ClickHouse.

This then also allows to remove the custom TableTemplate from the
ClickHouse unit test.

This also adds another placeholder {TAG_COLUMNS} that allows to get a
list of all tag columns in a TableTemplate. This can then be used to use
the tag columns as a primary or sort key, especially in ClickHouse.
  • Loading branch information
AndreKR committed Jan 22, 2025
1 parent 59702c1 commit f1c28d0
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 2 deletions.
1 change: 1 addition & 0 deletions plugins/outputs/sql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
## {TABLE} - table name as a quoted identifier
## {TABLELITERAL} - table name as a quoted string literal
## {COLUMNS} - column definitions (list of quoted identifiers and types)
## {TAG_COLUMNS} - tag column definitions (list of quoted identifiers)
# table_template = "CREATE TABLE {TABLE}({COLUMNS})"

## Table existence check template
Expand Down
11 changes: 10 additions & 1 deletion plugins/outputs/sql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,15 @@ func (p *SQL) deriveDatatype(value interface{}) string {

func (p *SQL) generateCreateTable(metric telegraf.Metric) string {
columns := make([]string, 0, len(metric.TagList())+len(metric.FieldList())+1)
tagColumns := make([]string, 0, len(metric.TagList()))

if p.TimestampColumn != "" {
columns = append(columns, fmt.Sprintf("%s %s", quoteIdent(p.TimestampColumn), p.Convert.Timestamp))
}

for _, tag := range metric.TagList() {
columns = append(columns, fmt.Sprintf("%s %s", quoteIdent(tag.Key), p.Convert.Text))
tagColumns = append(tagColumns, quoteIdent(tag.Key))
}

var datatype string
Expand All @@ -165,6 +167,13 @@ func (p *SQL) generateCreateTable(metric telegraf.Metric) string {
query = strings.ReplaceAll(query, "{TABLE}", quoteIdent(metric.Name()))
query = strings.ReplaceAll(query, "{TABLELITERAL}", quoteStr(metric.Name()))
query = strings.ReplaceAll(query, "{COLUMNS}", strings.Join(columns, ","))
query = strings.ReplaceAll(query, "{TAG_COLUMNS}", strings.Join(tagColumns, ","))

if p.Driver == "clickhouse" {
query = strings.ReplaceAll(query, "{SORT_KEY_CLAUSE}", fmt.Sprintf("ORDER BY (%s, %s)", strings.Join(tagColumns, ","), p.TimestampColumn))
} else {
query = strings.ReplaceAll(query, "{SORT_KEY_CLAUSE}", "")
}

return query
}
Expand Down Expand Up @@ -273,7 +282,7 @@ func init() {

func newSQL() *SQL {
return &SQL{
TableTemplate: "CREATE TABLE {TABLE}({COLUMNS})",
TableTemplate: "CREATE TABLE {TABLE}({COLUMNS}) {SORT_KEY_CLAUSE}",
TableExistsTemplate: "SELECT 1 FROM {TABLE} LIMIT 1",
TimestampColumn: "timestamp",
Convert: ConvertStruct{
Expand Down
1 change: 0 additions & 1 deletion plugins/outputs/sql/sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ func TestClickHouseIntegration(t *testing.T) {
p.Log = testutil.Logger{}
p.Driver = "clickhouse"
p.DataSourceName = address
p.TableTemplate = "CREATE TABLE {TABLE}({COLUMNS}) ENGINE MergeTree() ORDER by timestamp"
p.Convert.Integer = "Int64"
p.Convert.Text = "String"
p.Convert.Timestamp = "DateTime"
Expand Down

0 comments on commit f1c28d0

Please sign in to comment.