Skip to content

Commit

Permalink
Merge branch 'main' into remove-suuid
Browse files Browse the repository at this point in the history
  • Loading branch information
jkaflik authored Oct 3, 2023
2 parents f9fce92 + 78ccf39 commit 1dce1c8
Show file tree
Hide file tree
Showing 21 changed files with 443 additions and 237 deletions.
39 changes: 39 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: publish draft release

permissions: write-all

on:
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main

- name: Install Go 1.21
uses: actions/[email protected]
with:
stable: false
go-version: 1.21

- name: Prepare release
id: release_prep
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
go run internal/cmd/release_prep/main.go
- name: Commit and push hanges
run: |
git config --local user.email "[email protected]"
git config --local user.name "GitHub Action"
git add .
git commit -m "Update release notes"
git push
- name: Publish draft release
env:
RELEASE_API_URL: ${{ steps.release_prep.outputs.RELEASE_URL }}
run: |
curl -X PATCH -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -H "Accept: application/vnd.github.v3+json" $RELEASE_API_URL -d '{"draft": false}'
3 changes: 1 addition & 2 deletions .github/workflows/run-tests-head.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ on:

jobs:
test-ch-head:
runs-on: ubuntu-latest
runs-on: [self-hosted, style-checker]
strategy:
fail-fast: true
max-parallel: 1
matrix:
go:
- "1.20"
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ on:

jobs:
single-node:
runs-on: ubuntu-latest
runs-on: [self-hosted, style-checker]
strategy:
fail-fast: true
max-parallel: 1
matrix:
go:
- "1.20"
Expand All @@ -43,12 +42,11 @@ jobs:
integration-tests-cloud:
if: ${{ false }} # disabled for now
runs-on: ubuntu-latest
runs-on: [self-hosted, style-checker]
defaults:
run:
shell: bash
strategy:
max-parallel: 1
fail-fast: true
matrix:
go:
Expand Down
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,36 @@
# v2.14.1, 2023-09-14 <!-- Release notes generated using configuration in .github/release.yml at main -->

## What's Changed
### Enhancements 🎉
* parseDSN: support connection pool settings (#1082) by @hanjm in https://github.com/ClickHouse/clickhouse-go/pull/1084

## New Contributors
* @hanjm made their first contribution in https://github.com/ClickHouse/clickhouse-go/pull/1084

**Full Changelog**: https://github.com/ClickHouse/clickhouse-go/compare/v2.14.0...v2.14.1

# v2.14.0, 2023-09-12 <!-- Release notes generated using configuration in .github/release.yml at main -->

## What's Changed
### Enhancements 🎉
* Add FreeBufOnConnRelease to clickhouse.Options by @cergxx in https://github.com/ClickHouse/clickhouse-go/pull/1091
* Improving object allocation for (positional) parameter binding by @mdonkers in https://github.com/ClickHouse/clickhouse-go/pull/1092
### Fixes 🐛
* Fix escaping double quote in SQL statement in prepare batch by @jkaflik in https://github.com/ClickHouse/clickhouse-go/pull/1083
### Other Changes 🛠
* Update Go & ClickHouse versions by @jkaflik in https://github.com/ClickHouse/clickhouse-go/pull/1079
* Return status code from any http error by @RoryCrispin in https://github.com/ClickHouse/clickhouse-go/pull/1090
* tests: fix dropped error by @alrs in https://github.com/ClickHouse/clickhouse-go/pull/1081
* chore: unnecessary use of fmt.Sprintf by @testwill in https://github.com/ClickHouse/clickhouse-go/pull/1080
* Run CI on self hosted runner by @jkaflik in https://github.com/ClickHouse/clickhouse-go/pull/1094

## New Contributors
* @cergxx made their first contribution in https://github.com/ClickHouse/clickhouse-go/pull/1091
* @alrs made their first contribution in https://github.com/ClickHouse/clickhouse-go/pull/1081
* @testwill made their first contribution in https://github.com/ClickHouse/clickhouse-go/pull/1080

**Full Changelog**: https://github.com/ClickHouse/clickhouse-go/compare/v2.13.4...v2.14

# v2.13.4, 2023-08-30 <!-- Release notes generated using configuration in .github/release.yml at main -->

## What's Changed
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ go get -u github.com/ClickHouse/clickhouse-go/v2
* [query parameters](examples/clickhouse_api/query_parameters.go) (deprecated in favour of native query parameters)
* [bind params](examples/clickhouse_api/bind.go) (deprecated in favour of native query parameters)
* [client info](examples/clickhouse_api/client_info.go)
*

### std `database/sql` interface

* [batch](examples/std/batch.go)
Expand Down
83 changes: 54 additions & 29 deletions bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,41 +110,64 @@ func checkAllNamedArguments(args ...any) (bool, error) {
return haveNamed, nil
}

var bindPositionCharRe = regexp.MustCompile(`[?]`)

func bindPositional(tz *time.Location, query string, args ...any) (_ string, err error) {
var (
unbind = make(map[int]struct{})
params = make([]string, len(args))
lastMatchIndex = -1 // Position of previous match for copying
argIndex = 0 // Index for the argument at current position
buf = make([]byte, 0, len(query))
unbindCount = 0 // Number of positional arguments that couldn't be matched
)
for i, v := range args {
if fn, ok := v.(std_driver.Valuer); ok {
if v, err = fn.Value(); err != nil {
return "", nil

for i := 0; i < len(query); i++ {
// It's fine looping through the query string as bytes, because the (fixed) characters we're looking for
// are in the ASCII range to won't take up more than one byte.
if query[i] == '?' {
if i > 0 && query[i-1] == '\\' {
// Copy all previous index to here characters
buf = append(buf, query[lastMatchIndex+1:i-1]...)
buf = append(buf, '?')
} else {
// Copy all previous index to here characters
buf = append(buf, query[lastMatchIndex+1:i]...)

// Append the argument value
if argIndex < len(args) {
v := args[argIndex]
if fn, ok := v.(std_driver.Valuer); ok {
if v, err = fn.Value(); err != nil {
return "", nil
}
}

value, err := format(tz, Seconds, v)
if err != nil {
return "", err
}

buf = append(buf, value...)
argIndex++
} else {
unbindCount++
}
}
}
params[i], err = format(tz, Seconds, v)
if err != nil {
return "", err

lastMatchIndex = i
}
}
i := 0
query = bindPositionalRe.ReplaceAllStringFunc(query, func(n string) string {
if i >= len(params) {
unbind[i] = struct{}{}
return ""
}
val := params[i]
i++
return bindPositionCharRe.ReplaceAllStringFunc(n, func(m string) string {
return val
})
})
for param := range unbind {
return "", fmt.Errorf("have no arg for param ? at position %d", param)

// If there were no replacements, quick return without copying the string
if lastMatchIndex < 0 {
return query, nil
}

// Append the remainder
buf = append(buf, query[lastMatchIndex+1:]...)

if unbindCount > 0 {
return "", fmt.Errorf("have no arg for param ? at last %d positions", unbindCount)
}
// replace \? escape sequence
return strings.ReplaceAll(query, "\\?", "?"), nil

return string(buf), nil
}

func bindNumeric(tz *time.Location, query string, args ...any) (_ string, err error) {
Expand Down Expand Up @@ -244,9 +267,11 @@ func formatTime(tz *time.Location, scale TimeUnit, value time.Time) (string, err
return fmt.Sprintf("toDateTime64('%s', %d, '%s')", value.Format(fmt.Sprintf("2006-01-02 15:04:05.%0*d", int(scale*3), 0)), int(scale*3), value.Location().String()), nil
}

var stringQuoteReplacer = strings.NewReplacer(`\`, `\\`, `'`, `\'`)

func format(tz *time.Location, scale TimeUnit, v any) (string, error) {
quote := func(v string) string {
return "'" + strings.NewReplacer(`\`, `\\`, `'`, `\'`).Replace(v) + "'"
return "'" + stringQuoteReplacer.Replace(v) + "'"
}
switch v := v.(type) {
case nil:
Expand Down
5 changes: 5 additions & 0 deletions clickhouse.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

_ "time/tzdata"

chproto "github.com/ClickHouse/ch-go/proto"
"github.com/ClickHouse/clickhouse-go/v2/contributors"
"github.com/ClickHouse/clickhouse-go/v2/lib/column"
"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
Expand Down Expand Up @@ -346,6 +347,10 @@ func (ch *clickhouse) release(conn *connect, err error) {
conn.close()
return
}
if ch.opt.FreeBufOnConnRelease {
conn.buffer = new(chproto.Buffer)
conn.compressor.Data = nil
}
select {
case ch.idle <- conn:
default:
Expand Down
19 changes: 19 additions & 0 deletions clickhouse_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ type Options struct {
MaxIdleConns int // default 5
ConnMaxLifetime time.Duration // default 1 hour
ConnOpenStrategy ConnOpenStrategy
FreeBufOnConnRelease bool // drop preserved memory buffer after each query
HttpHeaders map[string]string // set additional headers on HTTP requests
HttpUrlPath string // set additional URL path for HTTP requests
BlockBufferSize uint8 // default 2 - can be overwritten on query
Expand Down Expand Up @@ -265,6 +266,24 @@ func (o *Options) fromDSN(in string) error {
case "round_robin":
o.ConnOpenStrategy = ConnOpenRoundRobin
}
case "max_open_conns":
maxOpenConns, err := strconv.Atoi(params.Get(v))
if err != nil {
return errors.Wrap(err, "max_open_conns invalid value")
}
o.MaxOpenConns = maxOpenConns
case "max_idle_conns":
maxIdleConns, err := strconv.Atoi(params.Get(v))
if err != nil {
return errors.Wrap(err, "max_idle_conns invalid value")
}
o.MaxIdleConns = maxIdleConns
case "conn_max_lifetime":
connMaxLifetime, err := time.ParseDuration(params.Get(v))
if err != nil {
return errors.Wrap(err, "conn_max_lifetime invalid value")
}
o.ConnMaxLifetime = connMaxLifetime
case "username":
o.Auth.Username = params.Get(v)
case "password":
Expand Down
18 changes: 18 additions & 0 deletions clickhouse_options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package clickhouse
import (
"crypto/tls"
"testing"
"time"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -449,6 +450,23 @@ func TestParseDSN(t *testing.T) {
},
"",
},
{
"client connection pool settings",
"clickhouse://127.0.0.1/test_database?max_open_conns=-1&max_idle_conns=0&conn_max_lifetime=1h",
&Options{
Protocol: Native,
MaxOpenConns: -1,
MaxIdleConns: 0,
ConnMaxLifetime: time.Hour,
Addr: []string{"127.0.0.1"},
Settings: Settings{},
Auth: Auth{
Database: "test_database",
},
scheme: "clickhouse",
},
"",
},
}

for _, testCase := range testCases {
Expand Down
2 changes: 1 addition & 1 deletion clickhouse_rows.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ next:
r.err = err
return false
}
goto next
case block := <-r.stream:
if block == nil {
return false
Expand All @@ -63,6 +62,7 @@ next:
}
r.row, r.block = 0, block
}
goto next
}
r.row++
return r.row <= r.block.Rows()
Expand Down
Loading

0 comments on commit 1dce1c8

Please sign in to comment.