mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 01:22:04 +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>
|
template <typename T>
|
||||||
auto & Field::safeGet()
|
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,
|
throw Exception(ErrorCodes::BAD_GET,
|
||||||
"Bad get: has {}, requested {}", getTypeName(), requested);
|
"Bad get: has {}, requested {}", getTypeName(), target);
|
||||||
|
|
||||||
return get<T>();
|
return get<T>();
|
||||||
}
|
}
|
||||||
|
@ -210,12 +210,8 @@ bool ParserSetQuery::parseNameValuePair(SettingChange & change, IParser::Pos & p
|
|||||||
if (!s_eq.ignore(pos, expected))
|
if (!s_eq.ignore(pos, expected))
|
||||||
return false;
|
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='', ...)
|
/// 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);
|
tryGetIdentifierNameInto(name, change.name);
|
||||||
change.value = createFieldFromAST(function_ast);
|
change.value = createFieldFromAST(function_ast);
|
||||||
@ -276,11 +272,7 @@ bool ParserSetQuery::parseNameValuePairWithParameterOrDefault(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Setting
|
/// Setting
|
||||||
if (ParserKeyword(Keyword::TRUE_KEYWORD).ignore(pos, expected))
|
if (function_p.parse(pos, function_ast, expected) && function_ast->as<ASTFunction>()->name == "disk")
|
||||||
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")
|
|
||||||
{
|
{
|
||||||
change.name = name;
|
change.name = name;
|
||||||
change.value = createFieldFromAST(function_ast);
|
change.value = createFieldFromAST(function_ast);
|
||||||
|
@ -31,7 +31,7 @@ def test_distibuted_settings(start_cluster):
|
|||||||
DETACH TABLE dist_1;
|
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
|
# flush_on_detach=true, so data_1 should have 1 row
|
||||||
assert int(node.query("SELECT count() FROM data_1")) == 1
|
assert int(node.query("SELECT count() FROM data_1")) == 1
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
A2193552DCF8A9F99AC35F86BC4D2FFD
|
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