|
| 1 | +package clickhouse |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "net/url" |
| 6 | + "strconv" |
| 7 | + |
| 8 | + "github.com/kshvakov/clickhouse/lib/binary" |
| 9 | +) |
| 10 | + |
| 11 | +type querySettingType int |
| 12 | + |
| 13 | +// all possible query setting's data type |
| 14 | +const ( |
| 15 | + uintQS querySettingType = iota + 1 |
| 16 | + intQS |
| 17 | + boolQS |
| 18 | + timeQS |
| 19 | +) |
| 20 | + |
| 21 | +// description of single query setting |
| 22 | +type querySettingInfo struct { |
| 23 | + name string |
| 24 | + qsType querySettingType |
| 25 | +} |
| 26 | + |
| 27 | +// all possible query settings |
| 28 | +var querySettingList = []querySettingInfo{ |
| 29 | + {"min_compress_block_size", uintQS}, |
| 30 | + {"max_compress_block_size", uintQS}, |
| 31 | + {"max_block_size", uintQS}, |
| 32 | + {"max_insert_block_size", uintQS}, |
| 33 | + {"min_insert_block_size_rows", uintQS}, |
| 34 | + {"min_insert_block_size_bytes", uintQS}, |
| 35 | + {"max_read_buffer_size", uintQS}, |
| 36 | + {"max_distributed_connections", uintQS}, |
| 37 | + {"max_query_size", uintQS}, |
| 38 | + {"interactive_delay", uintQS}, |
| 39 | + {"poll_interval", uintQS}, |
| 40 | + {"distributed_connections_pool_size", uintQS}, |
| 41 | + {"connections_with_failover_max_tries", uintQS}, |
| 42 | + {"background_pool_size", uintQS}, |
| 43 | + {"background_schedule_pool_size", uintQS}, |
| 44 | + {"replication_alter_partitions_sync", uintQS}, |
| 45 | + {"replication_alter_columns_timeout", uintQS}, |
| 46 | + {"min_count_to_compile", uintQS}, |
| 47 | + {"min_count_to_compile_expression", uintQS}, |
| 48 | + {"group_by_two_level_threshold", uintQS}, |
| 49 | + {"group_by_two_level_threshold_bytes", uintQS}, |
| 50 | + {"aggregation_memory_efficient_merge_threads", uintQS}, |
| 51 | + {"max_parallel_replicas", uintQS}, |
| 52 | + {"parallel_replicas_count", uintQS}, |
| 53 | + {"parallel_replica_offset", uintQS}, |
| 54 | + {"merge_tree_min_rows_for_concurrent_read", uintQS}, |
| 55 | + {"merge_tree_min_bytes_for_concurrent_read", uintQS}, |
| 56 | + {"merge_tree_min_rows_for_seek", uintQS}, |
| 57 | + {"merge_tree_min_bytes_for_seek", uintQS}, |
| 58 | + {"merge_tree_coarse_index_granularity", uintQS}, |
| 59 | + {"merge_tree_max_rows_to_use_cache", uintQS}, |
| 60 | + {"merge_tree_max_bytes_to_use_cache", uintQS}, |
| 61 | + {"mysql_max_rows_to_insert", uintQS}, |
| 62 | + {"optimize_min_equality_disjunction_chain_length", uintQS}, |
| 63 | + {"min_bytes_to_use_direct_io", uintQS}, |
| 64 | + {"mark_cache_min_lifetime", uintQS}, |
| 65 | + {"priority", uintQS}, |
| 66 | + {"log_queries_cut_to_length", uintQS}, |
| 67 | + {"max_concurrent_queries_for_user", uintQS}, |
| 68 | + {"insert_quorum", uintQS}, |
| 69 | + {"select_sequential_consistency", uintQS}, |
| 70 | + {"table_function_remote_max_addresses", uintQS}, |
| 71 | + {"read_backoff_max_throughput", uintQS}, |
| 72 | + {"read_backoff_min_events", uintQS}, |
| 73 | + {"output_format_pretty_max_rows", uintQS}, |
| 74 | + {"output_format_pretty_max_column_pad_width", uintQS}, |
| 75 | + {"output_format_parquet_row_group_size", uintQS}, |
| 76 | + {"http_headers_progress_interval_ms", uintQS}, |
| 77 | + {"input_format_allow_errors_num", uintQS}, |
| 78 | + {"preferred_block_size_bytes", uintQS}, |
| 79 | + {"max_replica_delay_for_distributed_queries", uintQS}, |
| 80 | + {"preferred_max_column_in_block_size_bytes", uintQS}, |
| 81 | + {"insert_distributed_timeout", uintQS}, |
| 82 | + {"odbc_max_field_size", uintQS}, |
| 83 | + {"max_rows_to_read", uintQS}, |
| 84 | + {"max_bytes_to_read", uintQS}, |
| 85 | + {"max_rows_to_group_by", uintQS}, |
| 86 | + {"max_bytes_before_external_group_by", uintQS}, |
| 87 | + {"max_rows_to_sort", uintQS}, |
| 88 | + {"max_bytes_to_sort", uintQS}, |
| 89 | + {"max_bytes_before_external_sort", uintQS}, |
| 90 | + {"max_bytes_before_remerge_sort", uintQS}, |
| 91 | + {"max_result_rows", uintQS}, |
| 92 | + {"max_result_bytes", uintQS}, |
| 93 | + {"min_execution_speed", uintQS}, |
| 94 | + {"max_execution_speed", uintQS}, |
| 95 | + {"min_execution_speed_bytes", uintQS}, |
| 96 | + {"max_execution_speed_bytes", uintQS}, |
| 97 | + {"max_columns_to_read", uintQS}, |
| 98 | + {"max_temporary_columns", uintQS}, |
| 99 | + {"max_temporary_non_const_columns", uintQS}, |
| 100 | + {"max_subquery_depth", uintQS}, |
| 101 | + {"max_pipeline_depth", uintQS}, |
| 102 | + {"max_ast_depth", uintQS}, |
| 103 | + {"max_ast_elements", uintQS}, |
| 104 | + {"max_expanded_ast_elements", uintQS}, |
| 105 | + {"readonly", uintQS}, |
| 106 | + {"max_rows_in_set", uintQS}, |
| 107 | + {"max_bytes_in_set", uintQS}, |
| 108 | + {"max_rows_in_join", uintQS}, |
| 109 | + {"max_bytes_in_join", uintQS}, |
| 110 | + {"max_rows_to_transfer", uintQS}, |
| 111 | + {"max_bytes_to_transfer", uintQS}, |
| 112 | + {"max_rows_in_distinct", uintQS}, |
| 113 | + {"max_bytes_in_distinct", uintQS}, |
| 114 | + {"max_memory_usage", uintQS}, |
| 115 | + {"max_memory_usage_for_user", uintQS}, |
| 116 | + {"max_memory_usage_for_all_queries", uintQS}, |
| 117 | + {"max_network_bandwidth", uintQS}, |
| 118 | + {"max_network_bytes", uintQS}, |
| 119 | + {"max_network_bandwidth_for_user", uintQS}, |
| 120 | + {"max_network_bandwidth_for_all_users", uintQS}, |
| 121 | + {"low_cardinality_max_dictionary_size", uintQS}, |
| 122 | + {"max_fetch_partition_retries_count", uintQS}, |
| 123 | + {"http_max_multipart_form_data_size", uintQS}, |
| 124 | + {"max_partitions_per_insert_block", uintQS}, |
| 125 | + |
| 126 | + {"network_zstd_compression_level", intQS}, |
| 127 | + {"http_zlib_compression_level", intQS}, |
| 128 | + {"distributed_ddl_task_timeout", intQS}, |
| 129 | + |
| 130 | + {"extremes", boolQS}, |
| 131 | + {"use_uncompressed_cache", boolQS}, |
| 132 | + {"replace_running_query", boolQS}, |
| 133 | + {"distributed_directory_monitor_batch_inserts", boolQS}, |
| 134 | + {"optimize_move_to_prewhere", boolQS}, |
| 135 | + {"compile", boolQS}, |
| 136 | + {"allow_suspicious_low_cardinality_types", boolQS}, |
| 137 | + {"compile_expressions", boolQS}, |
| 138 | + {"distributed_aggregation_memory_efficient", boolQS}, |
| 139 | + {"skip_unavailable_shards", boolQS}, |
| 140 | + {"distributed_group_by_no_merge", boolQS}, |
| 141 | + {"optimize_skip_unused_shards", boolQS}, |
| 142 | + {"merge_tree_uniform_read_distribution", boolQS}, |
| 143 | + {"force_index_by_date", boolQS}, |
| 144 | + {"force_primary_key", boolQS}, |
| 145 | + {"log_queries", boolQS}, |
| 146 | + {"insert_deduplicate", boolQS}, |
| 147 | + {"enable_http_compression", boolQS}, |
| 148 | + {"http_native_compression_disable_checksumming_on_decompress", boolQS}, |
| 149 | + {"output_format_write_statistics", boolQS}, |
| 150 | + {"add_http_cors_header", boolQS}, |
| 151 | + {"input_format_skip_unknown_fields", boolQS}, |
| 152 | + {"input_format_with_names_use_header", boolQS}, |
| 153 | + {"input_format_import_nested_json", boolQS}, |
| 154 | + {"input_format_defaults_for_omitted_fields", boolQS}, |
| 155 | + {"input_format_values_interpret_expressions", boolQS}, |
| 156 | + {"output_format_json_quote_64bit_integers", boolQS}, |
| 157 | + {"output_format_json_quote_denormals", boolQS}, |
| 158 | + {"output_format_json_escape_forward_slashes", boolQS}, |
| 159 | + {"output_format_pretty_color", boolQS}, |
| 160 | + {"use_client_time_zone", boolQS}, |
| 161 | + {"send_progress_in_http_headers", boolQS}, |
| 162 | + {"fsync_metadata", boolQS}, |
| 163 | + {"join_use_nulls", boolQS}, |
| 164 | + {"fallback_to_stale_replicas_for_distributed_queries", boolQS}, |
| 165 | + {"insert_distributed_sync", boolQS}, |
| 166 | + {"insert_allow_materialized_columns", boolQS}, |
| 167 | + {"optimize_throw_if_noop", boolQS}, |
| 168 | + {"use_index_for_in_with_subqueries", boolQS}, |
| 169 | + {"empty_result_for_aggregation_by_empty_set", boolQS}, |
| 170 | + {"allow_distributed_ddl", boolQS}, |
| 171 | + {"join_any_take_last_row", boolQS}, |
| 172 | + {"format_csv_allow_single_quotes", boolQS}, |
| 173 | + {"format_csv_allow_double_quotes", boolQS}, |
| 174 | + {"log_profile_events", boolQS}, |
| 175 | + {"log_query_settings", boolQS}, |
| 176 | + {"log_query_threads", boolQS}, |
| 177 | + {"enable_optimize_predicate_expression", boolQS}, |
| 178 | + {"low_cardinality_use_single_dictionary_for_part", boolQS}, |
| 179 | + {"decimal_check_overflow", boolQS}, |
| 180 | + {"prefer_localhost_replica", boolQS}, |
| 181 | + {"asterisk_left_columns_only", boolQS}, |
| 182 | + {"calculate_text_stack_trace", boolQS}, |
| 183 | + {"allow_ddl", boolQS}, |
| 184 | + {"parallel_view_processing", boolQS}, |
| 185 | + {"enable_debug_queries", boolQS}, |
| 186 | + {"enable_unaligned_array_join", boolQS}, |
| 187 | + {"low_cardinality_allow_in_native_format", boolQS}, |
| 188 | + {"allow_experimental_multiple_joins_emulation", boolQS}, |
| 189 | + {"allow_experimental_cross_to_join_conversion", boolQS}, |
| 190 | + {"cancel_http_readonly_queries_on_client_close", boolQS}, |
| 191 | + {"external_table_functions_use_nulls", boolQS}, |
| 192 | + {"allow_experimental_data_skipping_indices", boolQS}, |
| 193 | + {"allow_hyperscan", boolQS}, |
| 194 | + {"allow_simdjson", boolQS}, |
| 195 | + |
| 196 | + {"connect_timeout", timeQS}, |
| 197 | + {"connect_timeout_with_failover_ms", timeQS}, |
| 198 | + {"receive_timeout", timeQS}, |
| 199 | + {"send_timeout", timeQS}, |
| 200 | + {"tcp_keep_alive_timeout", timeQS}, |
| 201 | + {"queue_max_wait_ms", timeQS}, |
| 202 | + {"distributed_directory_monitor_sleep_time_ms", timeQS}, |
| 203 | + {"insert_quorum_timeout", timeQS}, |
| 204 | + {"read_backoff_min_latency_ms", timeQS}, |
| 205 | + {"read_backoff_min_interval_between_events_ms", timeQS}, |
| 206 | + {"stream_flush_interval_ms", timeQS}, |
| 207 | + {"stream_poll_timeout_ms", timeQS}, |
| 208 | + {"http_connection_timeout", timeQS}, |
| 209 | + {"http_send_timeout", timeQS}, |
| 210 | + {"http_receive_timeout", timeQS}, |
| 211 | + {"max_execution_time", timeQS}, |
| 212 | + {"timeout_before_checking_execution_speed", timeQS}, |
| 213 | +} |
| 214 | + |
| 215 | +type querySettingValueEncoder func(enc *binary.Encoder) error |
| 216 | + |
| 217 | +type querySettings struct { |
| 218 | + settings map[string]querySettingValueEncoder |
| 219 | + settingsStr string // used for debug output |
| 220 | +} |
| 221 | + |
| 222 | +func makeQuerySettings(query url.Values) (*querySettings, error) { |
| 223 | + qs := &querySettings{ |
| 224 | + settings: make(map[string]querySettingValueEncoder), |
| 225 | + settingsStr: "", |
| 226 | + } |
| 227 | + |
| 228 | + for _, info := range querySettingList { |
| 229 | + valueStr := query.Get(info.name) |
| 230 | + if valueStr == "" { |
| 231 | + continue |
| 232 | + } |
| 233 | + |
| 234 | + switch info.qsType { |
| 235 | + case uintQS, intQS, timeQS: |
| 236 | + value, err := strconv.ParseUint(valueStr, 10, 64) |
| 237 | + if err != nil { |
| 238 | + return nil, err |
| 239 | + } |
| 240 | + qs.settings[info.name] = func(enc *binary.Encoder) error { return enc.Uvarint(value) } |
| 241 | + |
| 242 | + case boolQS: |
| 243 | + valueBool, err := strconv.ParseBool(valueStr) |
| 244 | + if err != nil { |
| 245 | + return nil, err |
| 246 | + } |
| 247 | + value := uint64(0) |
| 248 | + if valueBool { |
| 249 | + value = 1 |
| 250 | + } |
| 251 | + qs.settings[info.name] = func(enc *binary.Encoder) error { return enc.Uvarint(value) } |
| 252 | + |
| 253 | + default: |
| 254 | + err := fmt.Errorf("query setting %s has unsupported data type", info.name) |
| 255 | + return nil, err |
| 256 | + } |
| 257 | + |
| 258 | + if qs.settingsStr != "" { |
| 259 | + qs.settingsStr += "&" |
| 260 | + } |
| 261 | + qs.settingsStr += info.name + "=" + valueStr |
| 262 | + } |
| 263 | + |
| 264 | + return qs, nil |
| 265 | +} |
| 266 | + |
| 267 | +func (qs *querySettings) IsEmpty() bool { |
| 268 | + return len(qs.settings) == 0 |
| 269 | +} |
| 270 | + |
| 271 | +func (qs *querySettings) Serialize(enc *binary.Encoder) error { |
| 272 | + for name, fn := range qs.settings { |
| 273 | + if err := enc.String(name); err != nil { |
| 274 | + return err |
| 275 | + } |
| 276 | + if err := fn(enc); err != nil { |
| 277 | + return err |
| 278 | + } |
| 279 | + } |
| 280 | + |
| 281 | + return nil |
| 282 | +} |
0 commit comments