Skip to content

Commit 649f177

Browse files
committed
fix wrong unescape special characters in table create query, fix #1151, affected aversions from 2.6.6 to 2.6.18
Signed-off-by: Slach <[email protected]>
1 parent b86a6f0 commit 649f177

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

ChangeLog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ BUG FIXES
44
- fix empty `path` and non-empty `object_disk_path` config parameters, allows unexpected deletion backup object disk data, fix [859](https://github.com/Altinity/clickhouse-backup/issues/859)
55
- reproduce behavior `<metadata_path>` parameter in clickhouse `<storage_configuration>` don't contain trailing slash, restore make hardlinks to wrong directory, look details in https://github.com/Altinity/clickhouse-backup/issues/859#issuecomment-2896880448, https://github.com/ClickHouse/ClickHouse/issues/80647
66
- fix backup for azblob disk behavior when `storage_account_url` contains container as first part in hostname
7+
- fix wrong unescape special characters in table create query, fix [1151](https://github.com/Altinity/clickhouse-backup/issues/1151), affected aversions from 2.6.6 to 2.6.18
78

89
# v2.6.18
910
IMPROVEMENTS

pkg/clickhouse/clickhouse.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,12 @@ func (ch *ClickHouse) GetTables(ctx context.Context, tablePattern string) ([]Tab
381381
return nil, err
382382
}
383383
for i := range tables {
384-
// https://github.com/Altinity/clickhouse-backup/issues/1091
385-
tables[i].CreateTableQuery = strings.ReplaceAll(tables[i].CreateTableQuery, `\\`, `\`)
384+
// https://github.com/Altinity/clickhouse-backup/issues/1091, https://github.com/Altinity/clickhouse-backup/issues/1151
385+
escapeReplacer := strings.NewReplacer(`\`, `\\`)
386+
escapeDb := escapeReplacer.Replace(tables[i].Database)
387+
escapeTable := escapeReplacer.Replace(tables[i].Name)
388+
tables[i].CreateTableQuery = strings.Replace(tables[i].CreateTableQuery, escapeDb, tables[i].Database, 1)
389+
tables[i].CreateTableQuery = strings.Replace(tables[i].CreateTableQuery, escapeTable, tables[i].Name, 1)
386390
}
387391
metadataPath, err := ch.getMetadataPath(ctx)
388392
if err != nil {

test/integration/integration_test.go

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"encoding/json"
99
"fmt"
10+
"github.com/Altinity/clickhouse-backup/v2/pkg/common"
1011
"github.com/Altinity/clickhouse-backup/v2/pkg/config"
1112
pool "github.com/jolestar/go-commons-pool/v2"
1213
"math/rand"
@@ -2385,7 +2386,47 @@ func TestCheckSystemPartsColumns(t *testing.T) {
23852386
env.Cleanup(t, r)
23862387
}
23872388

2388-
// // https://github.com/Altinity/clickhouse-backup/issues/871
2389+
// https://github.com/Altinity/clickhouse-backup/issues/1151
2390+
func TestSlashesInDatabaseAndTableNamesAndTableQuery(t *testing.T) {
2391+
env, r := NewTestEnvironment(t)
2392+
env.connectWithWait(t, r, 500*time.Millisecond, 1*time.Second, 1*time.Minute)
2393+
version, err := env.ch.GetVersion(t.Context())
2394+
r.NoError(err)
2395+
2396+
dbName := `db\db2/db3`
2397+
tableName := `z\z2/z3`
2398+
createSchemaSQL := "(`s`" + ` String DEFAULT replaceRegexpAll('test', '(\\\\=|\\\\\\\\)', '\\\\\\\\\\\\1')) ENGINE = MergeTree ORDER BY s`
2399+
createTableSQL := fmt.Sprintf("CREATE TABLE `%s`.`%s` "+createSchemaSQL, dbName, tableName)
2400+
env.queryWithNoError(r, fmt.Sprintf("CREATE DATABASE `%s`", dbName))
2401+
env.queryWithNoError(r, createTableSQL)
2402+
env.DockerExecNoError(r, "clickhouse-backup", "clickhouse-backup", "create", "--env", "CLICKHOUSE_HOST=clickhouse", "--tables", dbName+".*", t.Name())
2403+
2404+
backupTableFile := fmt.Sprintf("/var/lib/clickhouse/backup/%s/metadata/%s/%s.json", t.Name(), common.TablePathEncode(dbName), common.TablePathEncode(tableName))
2405+
backupContent, err := env.DockerExecOut("clickhouse-backup", "cat", backupTableFile)
2406+
r.NoError(err)
2407+
escapedCreateTableSQL := fmt.Sprintf("CREATE TABLE `%s`.`%s`", strings.ReplaceAll(dbName, `\`, `\\`), strings.ReplaceAll(tableName, `\`, `\\`))
2408+
escapedSchemaSQL := strings.ReplaceAll(createSchemaSQL, `\`, `\\`)
2409+
r.Contains(backupContent, escapedCreateTableSQL)
2410+
r.Contains(backupContent, escapedSchemaSQL)
2411+
2412+
r.NoError(env.ch.DropOrDetachTable(clickhouse.Table{Database: dbName, Name: tableName, CreateTableQuery: createTableSQL}, createTableSQL, "", false, version, "", false, ""))
2413+
r.NoError(env.dropDatabase(dbName, false))
2414+
env.DockerExecNoError(r, "clickhouse-backup", "clickhouse-backup", "restore", "--config", "/etc/clickhouse-backup/config-s3.yml", "--tables", dbName+".*", t.Name())
2415+
restoredSQL := ""
2416+
r.NoError(env.ch.SelectSingleRow(t.Context(), &restoredSQL, fmt.Sprintf("SHOW CREATE TABLE `%s`.`%s`", dbName, tableName)))
2417+
2418+
r.Contains(restoredSQL, escapedCreateTableSQL)
2419+
//SHOW CREATE SQL transform original query
2420+
restoredSQL = regexp.MustCompile(`[\n\s]+`).ReplaceAllString(restoredSQL, " ")
2421+
restoredSQL = regexp.MustCompile(`\(\s+`).ReplaceAllString(restoredSQL, "(")
2422+
restoredSQL = regexp.MustCompile(`\s+\)`).ReplaceAllString(restoredSQL, ")")
2423+
r.Contains(restoredSQL, createSchemaSQL)
2424+
2425+
r.NoError(env.dropDatabase(dbName, false))
2426+
env.Cleanup(t, r)
2427+
}
2428+
2429+
// https://github.com/Altinity/clickhouse-backup/issues/871
23892430
func TestKeepBackupRemoteAndDiffFromRemote(t *testing.T) {
23902431
if isTestShouldSkip("RUN_ADVANCED_TESTS") {
23912432
t.Skip("Skipping Advanced integration tests...")

0 commit comments

Comments
 (0)