Skip to content

Commit f5ef614

Browse files
committed
chore(outputs.sql): Make default create table template suitable for ClickHouse
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.
1 parent cf56e4a commit f5ef614

5 files changed

Lines changed: 26 additions & 2 deletions

File tree

plugins/outputs/sql/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details.
9999
## {TABLE} - table name as a quoted identifier
100100
## {TABLELITERAL} - table name as a quoted string literal
101101
## {COLUMNS} - column definitions (list of quoted identifiers and types)
102+
## {TAG_COLUMNS} - tag column definitions (list of quoted identifiers)
102103
# table_template = "CREATE TABLE {TABLE}({COLUMNS})"
103104

104105
## Table existence check template

plugins/outputs/sql/sample.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
## {TABLE} - table name as a quoted identifier
1919
## {TABLELITERAL} - table name as a quoted string literal
2020
## {COLUMNS} - column definitions (list of quoted identifiers and types)
21+
## {TAG_COLUMNS} - tag column definitions (list of quoted identifiers)
2122
# table_template = "CREATE TABLE {TABLE}({COLUMNS})"
2223

2324
## Table existence check template

plugins/outputs/sql/sql.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,15 @@ func (p *SQL) deriveDatatype(value interface{}) string {
153153

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

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

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

165167
var datatype string
@@ -172,6 +174,7 @@ func (p *SQL) generateCreateTable(metric telegraf.Metric) string {
172174
query = strings.ReplaceAll(query, "{TABLE}", quoteIdent(metric.Name()))
173175
query = strings.ReplaceAll(query, "{TABLELITERAL}", quoteStr(metric.Name()))
174176
query = strings.ReplaceAll(query, "{COLUMNS}", strings.Join(columns, ","))
177+
query = strings.ReplaceAll(query, "{TAG_COLUMNS}", strings.Join(tagColumns, ","))
175178

176179
return query
177180
}
@@ -274,13 +277,25 @@ func (p *SQL) Write(metrics []telegraf.Metric) error {
274277
return nil
275278
}
276279

280+
func (p *SQL) Init() error {
281+
if p.TableTemplate == "" {
282+
if p.Driver == "clickhouse" {
283+
p.TableTemplate = "CREATE TABLE {TABLE}({COLUMNS}) ORDER BY ({TAG_COLUMNS}, " + p.TimestampColumn + ")"
284+
} else {
285+
p.TableTemplate = "CREATE TABLE {TABLE}({COLUMNS})"
286+
}
287+
}
288+
289+
return nil
290+
}
291+
277292
func init() {
278293
outputs.Add("sql", func() telegraf.Output { return newSQL() })
279294
}
280295

281296
func newSQL() *SQL {
282297
return &SQL{
283-
TableTemplate: "CREATE TABLE {TABLE}({COLUMNS})",
298+
TableTemplate: "",
284299
TableExistsTemplate: "SELECT 1 FROM {TABLE} LIMIT 1",
285300
TimestampColumn: "timestamp",
286301
Convert: ConvertStruct{

plugins/outputs/sql/sql_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ func TestMysqlIntegration(t *testing.T) {
201201
p.Driver = "mysql"
202202
p.DataSourceName = address
203203
p.InitSQL = "SET sql_mode='ANSI_QUOTES';"
204+
err = p.Init()
205+
require.NoError(t, err)
204206

205207
require.NoError(t, p.Connect())
206208
require.NoError(t, p.Write(
@@ -287,6 +289,8 @@ func TestPostgresIntegration(t *testing.T) {
287289
p.Convert.Real = "double precision"
288290
p.Convert.Unsigned = "bigint"
289291
p.Convert.ConversionStyle = "literal"
292+
err = p.Init()
293+
require.NoError(t, err)
290294

291295
require.NoError(t, p.Connect())
292296
defer p.Close()
@@ -372,14 +376,15 @@ func TestClickHouseIntegration(t *testing.T) {
372376
p.Log = testutil.Logger{}
373377
p.Driver = "clickhouse"
374378
p.DataSourceName = address
375-
p.TableTemplate = "CREATE TABLE {TABLE}({COLUMNS}) ENGINE MergeTree() ORDER by timestamp"
376379
p.Convert.Integer = "Int64"
377380
p.Convert.Text = "String"
378381
p.Convert.Timestamp = "DateTime"
379382
p.Convert.Defaultvalue = "String"
380383
p.Convert.Unsigned = "UInt64"
381384
p.Convert.Bool = "UInt8"
382385
p.Convert.ConversionStyle = "literal"
386+
err = p.Init()
387+
require.NoError(t, err)
383388

384389
require.NoError(t, p.Connect())
385390
require.NoError(t, p.Write(testMetrics))

plugins/outputs/sql/sqlite_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ func TestSqlite(t *testing.T) {
2525
p.Log = testutil.Logger{}
2626
p.Driver = "sqlite"
2727
p.DataSourceName = address
28+
err := p.Init()
29+
require.NoError(t, err)
2830

2931
require.NoError(t, p.Connect())
3032
defer p.Close()

0 commit comments

Comments
 (0)