MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / parseAndCheckOptions

Method parseAndCheckOptions

src/Client/ClientApplicationBaseParser.cpp:28–90  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

26}
27
28void ClientApplicationBase::parseAndCheckOptions(OptionsDescription & options_description, po::variables_map & options, Arguments & arguments)
29{
30 /// Parse main commandline options.
31 auto parser = po::command_line_parser(arguments)
32 .options(options_description.main_description.value())
33 .extra_parser(OptionsAliasParser(options_description.main_description.value()))
34 .allow_unregistered();
35 po::parsed_options parsed = parser.run();
36
37 /// Check unrecognized options without positional options.
38 auto unrecognized_options = po::collect_unrecognized(parsed.options, po::collect_unrecognized_mode::exclude_positional);
39 if (!unrecognized_options.empty())
40 {
41 auto hints = this->getHints(unrecognized_options[0]);
42 if (!hints.empty())
43 throw Exception(ErrorCodes::UNRECOGNIZED_ARGUMENTS, "Unrecognized option '{}'. Maybe you meant {}",
44 unrecognized_options[0], toString(hints));
45
46 throw Exception(ErrorCodes::UNRECOGNIZED_ARGUMENTS, "Unrecognized option '{}'", unrecognized_options[0]);
47 }
48
49 /// Check positional options.
50 for (const auto & op : parsed.options)
51 {
52 /// Skip all options after empty `--`. These are processed separately into the Application configuration.
53 if (op.string_key.empty() && op.original_tokens[0].starts_with("--"))
54 break;
55
56 if (!op.unregistered && op.string_key.empty() && !op.original_tokens[0].starts_with("--")
57 && !op.original_tokens[0].empty() && !op.value.empty())
58 {
59 /// Two special cases for better usability:
60 /// - if the option contains a whitespace, it might be a query: clickhouse "SELECT 1"
61 /// - if the option is a filesystem file, then it's likely a queries file (clickhouse repro.sql)
62 /// These are relevant for interactive usage - user-friendly, but questionable in general.
63 /// In case of ambiguity or for scripts, prefer using proper options.
64
65 const auto & token = op.original_tokens[0];
66 po::variable_value value(boost::any(op.value), false);
67
68 const char * option = nullptr;
69 std::error_code ec;
70 if (token.contains(' '))
71 option = "query";
72 else if (std::filesystem::is_regular_file(std::filesystem::path{token}, ec))
73 option = "queries-file";
74 else if (token.contains('/') || token.contains('.'))
75 /// The argument looks like a file path (contains `/` or `.`) but doesn't exist on disk.
76 /// Give a clear "no such file" error rather than the generic "positional option is not supported"
77 /// which is confusing when the user meant to pass a file, e.g.:
78 /// $ clickhouse local /tmp/aaa.rep
79 /// Positional option `/tmp/aaa.rep` is not supported.
80 throw Exception(ErrorCodes::BAD_ARGUMENTS, "No such file: {}", token);
81 else
82 throw Exception(ErrorCodes::BAD_ARGUMENTS, "Positional option `{}` is not supported.", token);
83
84 if (!options.emplace(option, value).second)
85 throw Exception(ErrorCodes::BAD_ARGUMENTS, "Positional option `{}` is not supported.", token);

Callers

nothing calls this directly

Calls 12

OptionsAliasParserClass · 0.85
anyFunction · 0.85
storeFunction · 0.85
ExceptionClass · 0.70
toStringFunction · 0.50
optionsMethod · 0.45
valueMethod · 0.45
runMethod · 0.45
emptyMethod · 0.45
getHintsMethod · 0.45
containsMethod · 0.45
emplaceMethod · 0.45

Tested by

no test coverage detected