mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Backport #62206 to 24.3: Fix parsing booleans in settings
This commit is contained in:
parent
c6b1ccf544
commit
7bdb70723a
@ -893,11 +893,13 @@ NearestFieldType<std::decay_t<T>> & Field::get()
|
||||
template <typename T>
|
||||
auto & Field::safeGet()
|
||||
{
|
||||
const Types::Which requested = TypeToEnum<NearestFieldType<std::decay_t<T>>>::value;
|
||||
const Types::Which target = TypeToEnum<NearestFieldType<std::decay_t<T>>>::value;
|
||||
|
||||
if (which != requested)
|
||||
/// We allow converting int64 <-> uint64, int64 <-> bool, uint64 <-> bool in safeGet().
|
||||
if (target != which
|
||||
&& (!isInt64OrUInt64orBoolFieldType(target) || !isInt64OrUInt64orBoolFieldType(which)))
|
||||
throw Exception(ErrorCodes::BAD_GET,
|
||||
"Bad get: has {}, requested {}", getTypeName(), requested);
|
||||
"Bad get: has {}, requested {}", getTypeName(), target);
|
||||
|
||||
return get<T>();
|
||||
}
|
||||
|
@ -210,12 +210,8 @@ bool ParserSetQuery::parseNameValuePair(SettingChange & change, IParser::Pos & p
|
||||
if (!s_eq.ignore(pos, expected))
|
||||
return false;
|
||||
|
||||
if (ParserKeyword(Keyword::TRUE_KEYWORD).ignore(pos, expected))
|
||||
value = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(1)));
|
||||
else if (ParserKeyword(Keyword::FALSE_KEYWORD).ignore(pos, expected))
|
||||
value = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(0)));
|
||||
/// for SETTINGS disk=disk(type='s3', path='', ...)
|
||||
else if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name == "disk")
|
||||
if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name == "disk")
|
||||
{
|
||||
tryGetIdentifierNameInto(name, change.name);
|
||||
change.value = createFieldFromAST(function_ast);
|
||||
@ -276,11 +272,7 @@ bool ParserSetQuery::parseNameValuePairWithParameterOrDefault(
|
||||
}
|
||||
|
||||
/// Setting
|
||||
if (ParserKeyword(Keyword::TRUE_KEYWORD).ignore(pos, expected))
|
||||
node = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(1)));
|
||||
else if (ParserKeyword(Keyword::FALSE_KEYWORD).ignore(pos, expected))
|
||||
node = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(0)));
|
||||
else if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name == "disk")
|
||||
if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name == "disk")
|
||||
{
|
||||
change.name = name;
|
||||
change.value = createFieldFromAST(function_ast);
|
||||
|
@ -31,7 +31,7 @@ def test_distibuted_settings(start_cluster):
|
||||
DETACH TABLE dist_1;
|
||||
"""
|
||||
)
|
||||
assert "flush_on_detach = 1" in node.query("SHOW CREATE dist_1")
|
||||
assert "flush_on_detach = true" in node.query("SHOW CREATE dist_1")
|
||||
# flush_on_detach=true, so data_1 should have 1 row
|
||||
assert int(node.query("SELECT count() FROM data_1")) == 1
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
A2193552DCF8A9F99AC35F86BC4D2FFD
|
||||
SELECT hex(encrypt(\'aes-128-ecb\', \'[HIDDEN]\')) SETTINGS use_query_cache = 1
|
||||
SELECT hex(encrypt(\'aes-128-ecb\', \'[HIDDEN]\')) SETTINGS use_query_cache = true
|
||||
|
@ -0,0 +1,35 @@
|
||||
-- Custom settings from system.settings
|
||||
custom_f1 Bool_0 Custom
|
||||
custom_f2 Bool_0 Custom
|
||||
custom_f3 Bool_0 Custom
|
||||
custom_n0 UInt64_0 Custom
|
||||
custom_n1 UInt64_1 Custom
|
||||
custom_t1 Bool_1 Custom
|
||||
custom_t2 Bool_1 Custom
|
||||
custom_t3 Bool_1 Custom
|
||||
-- Custom settings via getSetting()
|
||||
custom_f1 false Bool
|
||||
custom_f2 false Bool
|
||||
custom_f3 false Bool
|
||||
custom_n0 0 UInt8
|
||||
custom_n1 1 UInt8
|
||||
custom_t1 true Bool
|
||||
custom_t2 true Bool
|
||||
custom_t3 true Bool
|
||||
-- Built-in settings
|
||||
async_insert 0 Bool
|
||||
async_insert false Bool
|
||||
async_insert 0 Bool
|
||||
async_insert false Bool
|
||||
async_insert 0 Bool
|
||||
async_insert false Bool
|
||||
async_insert 0 Bool
|
||||
async_insert false Bool
|
||||
async_insert 1 Bool
|
||||
async_insert true Bool
|
||||
async_insert 1 Bool
|
||||
async_insert true Bool
|
||||
async_insert 1 Bool
|
||||
async_insert true Bool
|
||||
async_insert 1 Bool
|
||||
async_insert true Bool
|
@ -0,0 +1,65 @@
|
||||
-- Custom settings must remember their types - whether it's a boolean or an integer.
|
||||
|
||||
-- Different ways to set a boolean.
|
||||
SET custom_f1 = false;
|
||||
SET custom_f2 = False;
|
||||
SET custom_f3 = FALSE;
|
||||
|
||||
SET custom_n0 = 0;
|
||||
SET custom_n1 = 1;
|
||||
|
||||
SET custom_t1 = true;
|
||||
SET custom_t2 = True;
|
||||
SET custom_t3 = TRUE;
|
||||
|
||||
SELECT '-- Custom settings from system.settings';
|
||||
|
||||
SELECT name, value, type FROM system.settings WHERE startsWith(name, 'custom_') ORDER BY name;
|
||||
|
||||
SELECT '-- Custom settings via getSetting()';
|
||||
|
||||
SELECT 'custom_f1' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
SELECT 'custom_f2' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
SELECT 'custom_f3' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SELECT 'custom_n0' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
SELECT 'custom_n1' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SELECT 'custom_t1' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
SELECT 'custom_t2' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
SELECT 'custom_t3' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
-- Built-in settings have hardcoded types.
|
||||
SELECT '-- Built-in settings';
|
||||
|
||||
SET async_insert = false;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SET async_insert = False;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SET async_insert = FALSE;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SET async_insert = 0;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SET async_insert = 1;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SET async_insert = true;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SET async_insert = True;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
||||
|
||||
SET async_insert = TRUE;
|
||||
SELECT name, value, type FROM system.settings WHERE name = 'async_insert';
|
||||
SELECT 'async_insert' AS name, getSetting(name) AS value, toTypeName(value);
|
@ -0,0 +1,5 @@
|
||||
BACKUP_CREATED
|
||||
RESTORED
|
||||
2
|
||||
80
|
||||
-12345
|
56
tests/queries/0_stateless/03032_async_backup_restore.sh
Executable file
56
tests/queries/0_stateless/03032_async_backup_restore.sh
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CUR_DIR"/../shell_config.sh
|
||||
|
||||
${CLICKHOUSE_CLIENT} -nm --query "
|
||||
DROP TABLE IF EXISTS tbl;
|
||||
DROP TABLE IF EXISTS tbl2;
|
||||
CREATE TABLE tbl (a Int32) ENGINE = MergeTree() ORDER BY tuple();
|
||||
INSERT INTO tbl VALUES (2), (80), (-12345);
|
||||
"
|
||||
|
||||
function start_async()
|
||||
{
|
||||
local command="$1"
|
||||
local first_column="s/^\([^\t]*\)\t.*/\1/"
|
||||
echo $(${CLICKHOUSE_CLIENT} --query "$command" | sed "${first_column}")
|
||||
}
|
||||
|
||||
function wait_status()
|
||||
{
|
||||
local operation_id="$1"
|
||||
local expected_status="$2"
|
||||
local timeout=60
|
||||
local start=$EPOCHSECONDS
|
||||
while true; do
|
||||
local current_status=$(${CLICKHOUSE_CLIENT} --query "SELECT status FROM system.backups WHERE id='${operation_id}'")
|
||||
if [ "${current_status}" == "${expected_status}" ]; then
|
||||
echo "${current_status}"
|
||||
break
|
||||
fi
|
||||
if ((EPOCHSECONDS-start > timeout )); then
|
||||
echo "Timeout while waiting for operation ${operation_id} to come to status ${expected_status}. The current status is ${current_status}."
|
||||
exit 1
|
||||
fi
|
||||
sleep 0.1
|
||||
done
|
||||
}
|
||||
|
||||
# Making a backup.
|
||||
backup_name="Disk('backups', '${CLICKHOUSE_TEST_UNIQUE_NAME}')"
|
||||
backup_operation_id=$(start_async "BACKUP TABLE tbl TO ${backup_name} ASYNC")
|
||||
wait_status ${backup_operation_id} "BACKUP_CREATED"
|
||||
|
||||
# Restoring from that backup.
|
||||
restore_operation_id=$(start_async "RESTORE TABLE tbl AS tbl2 FROM ${backup_name} ASYNC")
|
||||
wait_status ${restore_operation_id} "RESTORED"
|
||||
|
||||
# Check the result of that restoration.
|
||||
${CLICKHOUSE_CLIENT} --query "SELECT * FROM tbl2"
|
||||
|
||||
${CLICKHOUSE_CLIENT} -nm --query "
|
||||
DROP TABLE tbl;
|
||||
DROP TABLE tbl2;
|
||||
"
|
Loading…
Reference in New Issue
Block a user