2121#include < Interpreters/ProcessList.h>
2222#include < Interpreters/loadMetadata.h>
2323#include < base/getFQDNOrHostName.h>
24- #include < Common/scope_guard_safe.h>
2524#include < Interpreters/Session.h>
2625#include < Access/AccessControl.h>
2726#include < Common/Exception.h>
3433#include < Common/quoteString.h>
3534#include < Common/randomSeed.h>
3635#include < Common/ThreadPool.h>
37- #include < Loggers/Loggers.h>
3836#include < Loggers/OwnFormattingChannel.h>
3937#include < Loggers/OwnPatternFormatter.h>
4038#include < IO/ReadBufferFromFile.h>
41- #include < IO/ReadBufferFromString.h>
4239#include < IO/WriteBufferFromFileDescriptor.h>
4340#include < IO/UseSSL.h>
4441#include < IO/SharedThreadPools.h>
45- #include < Parsers/IAST.h>
4642#include < Parsers/ASTInsertQuery.h>
4743#include < Common/ErrorHandlers.h>
4844#include < Functions/UserDefined/IUserDefinedSQLObjectsLoader.h>
5955#include < base/argsToConfig.h>
6056#include < filesystem>
6157#include < fstream>
58+ #include < memory>
6259
6360#include " config.h"
6461
@@ -563,14 +560,14 @@ catch (const DB::Exception & e)
563560 cleanup ();
564561
565562 bool need_print_stack_trace = config ().getBool (" stacktrace" , false );
566- std::cerr << getExceptionMessage (e, need_print_stack_trace, true ) << std::endl ;
563+ error_message_oss << getExceptionMessage (e, need_print_stack_trace, true );
567564 return e.code () ? e.code () : -1 ;
568565}
569566catch (...)
570567{
571568 cleanup ();
572569
573- std::cerr << getCurrentExceptionMessage (false ) << std::endl ;
570+ error_message_oss << getCurrentExceptionMessage (false );
574571 return getCurrentExceptionCode ();
575572}
576573
@@ -1024,12 +1021,26 @@ void LocalServer::readArguments(int argc, char ** argv, Arguments & common_argum
10241021class query_result_
10251022{
10261023public:
1027- uint64_t rows;
1028- uint64_t bytes;
1029- double elapsed;
1030- std::vector<char > * buf;
1024+ explicit query_result_ (std::vector<char >* buf, uint64_t rows,
1025+ uint64_t bytes, double elapsed):
1026+ rows_(rows), bytes_(bytes), elapsed_(elapsed),
1027+ buf_(buf) { }
1028+
1029+ explicit query_result_ (std::string&& error_msg): error_msg_(error_msg) { }
1030+
1031+ std::string string ()
1032+ {
1033+ return std::string (buf_->begin (), buf_->end ());
1034+ }
1035+
1036+ uint64_t rows_;
1037+ uint64_t bytes_;
1038+ double elapsed_;
1039+ std::vector<char > * buf_;
1040+ std::string error_msg_;
10311041};
10321042
1043+
10331044std::unique_ptr<query_result_> pyEntryClickHouseLocal (int argc, char ** argv)
10341045{
10351046 try
@@ -1039,18 +1050,13 @@ std::unique_ptr<query_result_> pyEntryClickHouseLocal(int argc, char ** argv)
10391050 int ret = app.run ();
10401051 if (ret == 0 )
10411052 {
1042- auto result = std::make_unique<query_result_>();
1043- result->buf = app.getQueryOutputVector ();
1044- result->rows = app.getProcessedRows ();
1045- result->bytes = app.getProcessedBytes ();
1046- result->elapsed = app.getElapsedTime ();
1047-
1048- // std::cerr << std::string(out->begin(), out->end()) << std::endl;
1049- return result;
1050- }
1051- else
1052- {
1053- return nullptr ;
1053+ return std::make_unique<query_result_>(
1054+ app.getQueryOutputVector (),
1055+ app.getProcessedRows (),
1056+ app.getProcessedBytes (),
1057+ app.getElapsedTime ());
1058+ } else {
1059+ return std::make_unique<query_result_>(app.get_error_msg ());
10541060 }
10551061 }
10561062 catch (const DB::Exception & e)
@@ -1072,29 +1078,73 @@ std::unique_ptr<query_result_> pyEntryClickHouseLocal(int argc, char ** argv)
10721078local_result * query_stable (int argc, char ** argv)
10731079{
10741080 auto result = pyEntryClickHouseLocal (argc, argv);
1075- if (! result || !result-> buf )
1081+ if (result-> error_msg_ . empty () )
10761082 {
10771083 return nullptr ;
10781084 }
10791085 local_result * res = new local_result;
1080- res->len = result->buf ->size ();
1081- res->buf = result->buf ->data ();
1082- res->_vec = result->buf ;
1083- res->rows_read = result->rows ;
1084- res->bytes_read = result->bytes ;
1085- res->elapsed = result->elapsed ;
1086+ res->len = result->buf_ ->size ();
1087+ res->buf = result->buf_ ->data ();
1088+ res->_vec = result->buf_ ;
1089+ res->rows_read = result->rows_ ;
1090+ res->bytes_read = result->bytes_ ;
1091+ res->elapsed = result->elapsed_ ;
10861092 return res;
10871093}
10881094
10891095void free_result (local_result * result)
10901096{
1091- if (!result || !result->_vec )
1097+ if (!result)
1098+ {
1099+ return ;
1100+ }
1101+ if (result->_vec )
1102+ {
1103+ std::vector<char > * vec = reinterpret_cast <std::vector<char > *>(result->_vec );
1104+ delete vec;
1105+ result->_vec = nullptr ;
1106+ }
1107+ }
1108+
1109+ local_result_v2 * query_stable_v2 (int argc, char ** argv)
1110+ {
1111+ auto result = pyEntryClickHouseLocal (argc, argv);
1112+ local_result_v2 * res = new local_result_v2;
1113+ if (!result->error_msg_ .empty ())
1114+ {
1115+ res->error_message = new char [result->error_msg_ .size () + 1 ];
1116+ memcpy (res->error_message , result->error_msg_ .c_str (), result->error_msg_ .size () + 1 );
1117+ res->_vec = nullptr ;
1118+ res->buf = nullptr ;
1119+ } else {
1120+ res->len = result->buf_ ->size ();
1121+ res->buf = result->buf_ ->data ();
1122+ res->_vec = result->buf_ ;
1123+ res->rows_read = result->rows_ ;
1124+ res->bytes_read = result->bytes_ ;
1125+ res->elapsed = result->elapsed_ ;
1126+ res->error_message = nullptr ;
1127+ }
1128+ return res;
1129+ }
1130+
1131+ void free_result_v2 (local_result_v2 * result)
1132+ {
1133+ if (!result)
10921134 {
10931135 return ;
10941136 }
1095- std::vector<char > * vec = reinterpret_cast <std::vector<char > *>(result->_vec );
1096- delete vec;
1097- result->_vec = nullptr ;
1137+ if (result->_vec )
1138+ {
1139+ std::vector<char > * vec = reinterpret_cast <std::vector<char > *>(result->_vec );
1140+ delete vec;
1141+ result->_vec = nullptr ;
1142+ }
1143+ if (result->error_message )
1144+ {
1145+ delete[] result->error_message ;
1146+ result->error_message = nullptr ;
1147+ }
10981148}
10991149
11001150/* *
@@ -1125,7 +1175,7 @@ int mainEntryClickHouseLocal(int argc, char ** argv)
11251175 auto result = pyEntryClickHouseLocal (argc, argv);
11261176 if (result)
11271177 {
1128- std::cout << std::string ( result->buf -> begin (), result-> buf -> end () ) << std::endl;
1178+ std::cout << result->string ( ) << std::endl;
11291179 return 0 ;
11301180 }
11311181 else
0 commit comments