| 688 | |
| 689 | |
| 690 | void ClientBase::initOutputFormat(const Block & block, ASTPtr parsed_query) |
| 691 | try |
| 692 | { |
| 693 | if (!output_format) |
| 694 | { |
| 695 | /// Ignore all results when fuzzing as they can be huge. |
| 696 | if (query_fuzzer_runs) |
| 697 | { |
| 698 | output_format = std::make_shared<NullOutputFormat>(std::make_shared<const Block>(block)); |
| 699 | return; |
| 700 | } |
| 701 | |
| 702 | WriteBuffer * underlying_buf = nullptr; |
| 703 | if (!pager.empty() && !isEmbeeddedClient()) |
| 704 | { |
| 705 | if (SIG_ERR == signal(SIGPIPE, SIG_IGN)) |
| 706 | throw ErrnoException(ErrorCodes::CANNOT_SET_SIGNAL_HANDLER, "Cannot set signal handler for SIGPIPE"); |
| 707 | if (SIG_ERR == signal(SIGQUIT, SIG_IGN)) |
| 708 | throw ErrnoException(ErrorCodes::CANNOT_SET_SIGNAL_HANDLER, "Cannot set signal handler for SIGQUIT"); |
| 709 | |
| 710 | ShellCommand::Config config(pager); |
| 711 | config.pipe_stdin_only = true; |
| 712 | config.terminate_in_destructor_strategy.terminate_in_destructor = true; |
| 713 | config.terminate_in_destructor_strategy.termination_signal = SIGTERM; |
| 714 | pager_cmd = ShellCommand::execute(config); |
| 715 | underlying_buf = &pager_cmd->in; |
| 716 | } |
| 717 | else |
| 718 | { |
| 719 | underlying_buf = std_out.get(); |
| 720 | } |
| 721 | |
| 722 | /// Use the flush callback wrapper to prevent progress flickering |
| 723 | std_out_wrapper = std::make_unique<FlushCallbackWriteBuffer>( |
| 724 | underlying_buf, |
| 725 | [this]() |
| 726 | { |
| 727 | /// If results are written INTO OUTFILE, we can avoid clearing progress to avoid flicker. |
| 728 | if (need_render_progress && tty_buf && (!select_into_file || select_into_file_and_stdout)) |
| 729 | { |
| 730 | std::unique_lock lock(tty_mutex); |
| 731 | progress_indication.clearProgressOutput(*tty_buf, lock); |
| 732 | } |
| 733 | if (need_render_progress_table && tty_buf && (!select_into_file || select_into_file_and_stdout)) |
| 734 | { |
| 735 | std::unique_lock lock(tty_mutex); |
| 736 | progress_table.clearTableOutput(*tty_buf, lock); |
| 737 | } |
| 738 | } |
| 739 | ); |
| 740 | |
| 741 | WriteBuffer * out_buf = std_out_wrapper.get(); |
| 742 | |
| 743 | select_into_file = false; |
| 744 | select_into_file_and_stdout = false; |
| 745 | String current_format = default_output_format; |
| 746 | /// The query can specify output format or output file. |
| 747 | if (const auto * query_with_output = dynamic_cast<const ASTQueryWithOutput *>(parsed_query.get())) |
nothing calls this directly
no test coverage detected