| 3844 | } |
| 3845 | |
| 3846 | void ClientBase::runInteractive() |
| 3847 | { |
| 3848 | if (getClientConfiguration().has("query_id")) |
| 3849 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "query_id could be specified only in non-interactive mode"); |
| 3850 | if (getClientConfiguration().getBool("print-time-to-stderr", false)) |
| 3851 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "time option could be specified only in non-interactive mode"); |
| 3852 | |
| 3853 | initQueryIdFormats(); |
| 3854 | |
| 3855 | #if USE_CLIENT_AI |
| 3856 | /// AI SQL generation is disabled for the embedded client (SSH and WebSocket protocols) |
| 3857 | /// because it accesses the environment (API keys) which could be a security concern. |
| 3858 | if (!isEmbeeddedClient()) |
| 3859 | initAIProvider(); |
| 3860 | #endif |
| 3861 | |
| 3862 | /// Initialize DateLUT here to avoid counting time spent here as query execution time. |
| 3863 | const auto local_tz = DateLUT::instance().getTimeZone(); |
| 3864 | |
| 3865 | suggest.emplace(); |
| 3866 | if (load_suggestions) |
| 3867 | { |
| 3868 | /// Load suggestion data from the server. |
| 3869 | if (client_context->getApplicationType() == Context::ApplicationType::CLIENT) |
| 3870 | suggest->load<Connection>(client_context, connection_parameters, getClientConfiguration().getInt("suggestion_limit"), wait_for_suggestions_to_load); |
| 3871 | else if (client_context->getApplicationType() == Context::ApplicationType::LOCAL || client_context->getApplicationType() == Context::ApplicationType::SERVER) |
| 3872 | suggest->load<LocalConnection>(client_context, connection_parameters, getClientConfiguration().getInt("suggestion_limit"), wait_for_suggestions_to_load); |
| 3873 | } |
| 3874 | |
| 3875 | if (home_path.empty()) |
| 3876 | { |
| 3877 | const char * home_path_cstr = getenv("HOME"); // NOLINT(concurrency-mt-unsafe) |
| 3878 | if (home_path_cstr) |
| 3879 | home_path = home_path_cstr; |
| 3880 | } |
| 3881 | |
| 3882 | history_max_entries = getClientConfiguration().getUInt("history_max_entries", 1000000); |
| 3883 | |
| 3884 | LineReader::Patterns query_extenders = {"\\"}; |
| 3885 | LineReader::Patterns query_delimiters = {";", "\\G", "\\G;"}; |
| 3886 | char word_break_characters[] = " \t\v\f\a\b\r\n`~!@#$%^&*()-=+[{]}\\|;:'\",<.>/?"; |
| 3887 | |
| 3888 | std::unique_ptr<LineReader> lr; |
| 3889 | |
| 3890 | |
| 3891 | #if USE_REPLXX |
| 3892 | replxx::Replxx::highlighter_callback_with_pos_t highlight_callback{}; |
| 3893 | |
| 3894 | if (getClientConfiguration().getBool("highlight", true)) |
| 3895 | { |
| 3896 | highlight_callback = [this](const String & query, std::vector<replxx::Replxx::Color> & colors, int pos) |
| 3897 | { |
| 3898 | highlight(query, colors, *client_context, pos, rainbow_parentheses); |
| 3899 | }; |
| 3900 | } |
| 3901 | |
| 3902 | /// Don't allow embedded client to read from and write to any file on the server's filesystem. |
| 3903 | String actual_history_file_path; |
nothing calls this directly
no test coverage detected