ClickHouse / ClickHouse/clickhouse-go
{identifier:Type} pattern in SQL comment forces server-side mode, breaking @name substitution in same query
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 3.3k
- Forks
- 684
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 14
Description
## Summary
When a SQL query contains a `{identifier:Type}` pattern inside a `--` comment, the driver switches the entire query to server-side query-settings mode. Any `@name` parameter in the actual SQL is then left unsubstituted and reaches ClickHouse as a bare `@name` token, producing error code 26.
The bug reproduces whether or not the identifier in the comment matches a named parameter.
## Environment
- **clickhouse-go**: v2.43.0
- **ClickHouse server**: 26.2.5.45
- **Go**: 1.25.0
- **Protocol**: native TCP (port 9000)
## Reproduction
```go
package main
import (
"context"
"fmt"
"os"
"github.com/ClickHouse/clickhouse-go/v2"
)
func main() {
opts, _ := clickhouse.ParseDSN(os.Getenv("CLICKHOUSE_DSN"))
conn, _ := clickhouse.Open(opts)
defer conn.Close()
ctx := context.Background()
run := func(label, query string, args ...any) {
rows, err := conn.Query(ctx, query, args...)
if err != nil {
fmt.Printf("FAIL %s\n %v\n", label, err)
return
}
rows.Close()
fmt.Printf("PASS %s\n", label)
}
// PASS: @name alone, no {x:T} anywhere in the SQL
run("baseline",
`SELECT number FROM numbers(@limit)`,
clickhouse.Named("limit", uint32(5)),
)
// PASS: @name in a comment is fine when no {x:T} is present
run("@name in comment, no {x:T}",
"-- uses @limit\nSELECT number FROM numbers(@limit)",
clickhouse.Named("limit", uint32(5)),
)
// FAIL: {x:T} in a comment — identifier matches a named param
// Driver forces server-side mode; @limit in SQL is never substituted.
run("{x:T} in comment, identifier matches param",
"-- server-side equivalent: {limit:UInt32}\nSELECT number FROM numbers(@limit)",
clickhouse.Named("limit", uint32(5)),
)
// FAIL: {x:T} in a comment — identifier does not match any param
// Same failure regardless of whether the identifier is in the params map.
run("{x:T} in comment, identifier not in params",
"-- see {name:Type} style for expression positions\nSELECT number FROM numbers(@limit)",
clickhouse.Named("limit", uint32(5)),
)
}
```
**Output:**
```
PASS baseline
PASS @name in comment, no {x:T}
FAIL {x:T} in comment, identifier matches param
code: 26, message: Cannot parse quoted string: expected opening quote ''', got '5'
FAIL {x:T} in comment, identifier not in params
code: 26, message: Cannot parse quoted string: expected opening quote ''', got '5'
```
## Expected behaviour
SQL comments should not be scanned for parameter patterns. `{identifier:Type}` inside a `--` comment should have no effect on how `@name` parameters in the actual query are processed.
## Actual behaviour
Any `{identifier:Type}` found in a `--` comment forces the driver into server-side query-settings mode for the whole query. `@name` in the SQL is then passed through to ClickHouse unsubstituted, which rejects it (code 62 "Syntax error") or misinterprets the bound value (code 26 "Cannot parse quoted string") depending on the specific query structure.
## Suggested fix
Strip or skip SQL comment regions before scanning for `{identifier:Type}` and `@name` patterns. Single-line (`--`) and block (`/* */`) comments should both be excluded from parameter scanning.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the provided Go reproduction against ClickHouse to confirm the failure for both matching and non-matching identifiers. Inspect the driver's parameter scanning path; done means `{identifier:Type}` in both `--` and `/* */` comments is ignored while `@name` in SQL is substituted normally, with coverage for both comment forms.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100