Skip to content
Merged
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/ClickHouse/clickhouse-go/v2 v2.40.3
github.com/google/go-cmp v0.7.0
github.com/hashicorp/hcl/v2 v2.24.0
github.com/orian/clickhouse-sql-parser v0.0.0-20260813141301-768a69c3d95a
github.com/orian/clickhouse-sql-parser v1.0.1
github.com/pmezard/go-difflib v1.0.0
github.com/rs/zerolog v1.34.0
github.com/stretchr/testify v1.11.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/orian/clickhouse-sql-parser v0.0.0-20260813141301-768a69c3d95a h1:pEpE55SB1MrdR7O8Vow1zDmUeAJxKQ1PeRVNyXS5L4g=
github.com/orian/clickhouse-sql-parser v0.0.0-20260813141301-768a69c3d95a/go.mod h1:22D/qoWV/Ipbn5Gcub+0ttta1wgzSDaJMprQRZWghoE=
github.com/orian/clickhouse-sql-parser v1.0.1 h1:jxNed69Vax3V3xTwBLz0nAiNPHL2qtlLThpoK1bdOIQ=
github.com/orian/clickhouse-sql-parser v1.0.1/go.mod h1:22D/qoWV/Ipbn5Gcub+0ttta1wgzSDaJMprQRZWghoE=
github.com/paulmach/orb v0.12.0 h1:z+zOwjmG3MyEEqzv92UN49Lg1JFYx0L9GpGKNVDKk1s=
github.com/paulmach/orb v0.12.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
Expand Down
14 changes: 4 additions & 10 deletions internal/loader/hcl/introspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,7 @@ func upsertView(db *DatabaseSpec, v ViewSpec) {
// Parser panics become errors so introspection can use its normal -allow-raw
// fallback instead of terminating the process.
func parseCreateStatement(createSQL string) (chparser.Expr, error) {
stmts, err := safeParseStmts(createSQL)
if err != nil {
normalized := stripDefaultTimeSeriesTargetShorthand(createSQL)
if normalized != createSQL {
stmts, err = safeParseStmts(normalized)
}
}
stmts, err := safeParseStmts(stripDefaultTimeSeriesTargetShorthand(createSQL))
if err != nil {
return nil, fmt.Errorf("parser: %w", err)
}
Expand All @@ -253,9 +247,9 @@ var defaultTimeSeriesTargetShorthandRE = regexp.MustCompile(
// table. The schema model already represents these exact auto-generated
// targets as nil, so retaining the suffix would create a permanent diff.
//
// The SQL parser supports the documented INNER COLUMNS / INNER ENGINE form,
// but not this newer server spelling (orian/clickhouse-sql-parser#24). The
// matcher is suffix-anchored and requires every default clause, so custom
// Normalize before parsing even when the parser supports this shorthand:
// these defaults must still map to nil targets in the schema (issue #246).
// The matcher is suffix-anchored and requires every default clause, so custom
// target definitions are never discarded.
func stripDefaultTimeSeriesTargetShorthand(createSQL string) string {
if !strings.Contains(createSQL, "ENGINE = TimeSeries") {
Expand Down
18 changes: 18 additions & 0 deletions internal/loader/hcl/timeseries_tags_escape_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package hcl

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -40,6 +41,23 @@ ORDER BY metric_family_name`
engine, ok := db.Tables[0].Engine.Decoded.(EngineTimeSeries)
require.True(t, ok)
assert.Equal(t, map[string]string{"foo'bar": "foo_bar"}, engine.TagsToColumns)
assert.Nil(t, engine.Samples)
assert.Nil(t, engine.Tags)
assert.Nil(t, engine.Metrics)

// SHOW CREATE's default targets must not introduce drift from the same
// table declared without explicit targets, regardless of parser support.
bareSQL := strings.Split(sql, " DATA\n")[0]
bare := &DatabaseSpec{Name: "default"}
require.NoError(t, processIntrospectRows(bare, "default", &fakeRows{rows: []fakeRow{{name: "m", sql: bareSQL}}}))
changes := Diff(&Schema{Databases: []DatabaseSpec{*bare}}, &Schema{Databases: []DatabaseSpec{*db}})
assert.Empty(t, changes.Databases)

// A custom target must not be silently normalized away. Engine-only
// custom targets are still unsupported by the schema converter.
customSQL := strings.Replace(sql, "ORDER BY (id, timestamp)", "ORDER BY (timestamp, id)", 1)
_, err := buildTableFromCreateSQL(customSQL)
require.ErrorContains(t, err, "samples target: clause has neither external table nor inner columns")
}

func TestSQLGen_TimeSeriesTagsToColumns_HCLFirstEscaping(t *testing.T) {
Expand Down