1919#include < clickhouse/base/socket.h> // for ipv4-ipv6 platform-specific stuff
2020
2121#include < cinttypes>
22+ #include < cstdint>
23+ #include < ctime>
2224#include < iomanip>
2325#include < sstream>
26+ #include < stdexcept>
2427#include < type_traits>
28+ #include " clickhouse/types/types.h"
29+ #include " absl/numeric/int128.h"
30+
2531
2632
2733namespace {
@@ -42,7 +48,7 @@ struct DateTimeValue {
4248};
4349
4450std::ostream& operator <<(std::ostream & ostr, const DateTimeValue & time) {
45- const auto t = std::localtime (&time.value );
51+ const auto t = std::gmtime (&time.value );
4652 char buffer[] = " 2015-05-18 07:40:12\0\0 " ;
4753 std::strftime (buffer, sizeof (buffer), " %Y-%m-%d %H:%M:%S" , t);
4854
@@ -173,6 +179,7 @@ std::ostream & printColumnValue(const ColumnRef& c, const size_t row, std::ostre
173179 || doPrintValue<ColumnEnum8>(c, row, ostr)
174180 || doPrintValue<ColumnEnum16>(c, row, ostr)
175181 || doPrintValue<ColumnDate, DateTimeValue>(c, row, ostr)
182+ || doPrintValue<ColumnDate32, DateTimeValue>(c, row, ostr)
176183 || doPrintValue<ColumnDateTime, DateTimeValue>(c, row, ostr)
177184 || doPrintValue<ColumnDateTime64, DateTimeValue>(c, row, ostr)
178185 || doPrintValue<ColumnDecimal>(c, row, ostr)
@@ -332,6 +339,141 @@ std::ostream & operator<<(std::ostream & ostr, const Progress & progress) {
332339 << " written_bytes : " << progress.written_bytes ;
333340}
334341
342+ std::ostream& operator <<(std::ostream& ostr, const ItemView& item_view) {
343+ ostr << " ItemView {" << clickhouse::Type::TypeName (item_view.type ) << " : " ;
344+
345+ switch (item_view.type ) {
346+ case Type::Void:
347+ ostr << " --void--" ;
348+ break ;
349+ case Type::Int8:
350+ ostr << static_cast <int >(item_view.get <int8_t >());
351+ break ;
352+ case Type::Int16:
353+ ostr << static_cast <int >(item_view.get <int16_t >());
354+ break ;
355+ case Type::Int32:
356+ ostr << static_cast <int >(item_view.get <int32_t >());
357+ break ;
358+ case Type::Int64:
359+ ostr << item_view.get <int64_t >();
360+ break ;
361+ case Type::UInt8:
362+ ostr << static_cast <unsigned int >(item_view.get <uint8_t >());
363+ break ;
364+ case Type::UInt16:
365+ ostr << static_cast <unsigned int >(item_view.get <uint16_t >());
366+ break ;
367+ case Type::UInt32:
368+ ostr << static_cast <unsigned int >(item_view.get <uint32_t >());
369+ break ;
370+ case Type::UInt64:
371+ ostr << item_view.get <uint64_t >();
372+ break ;
373+ case Type::Float32:
374+ ostr << static_cast <float >(item_view.get <float >());
375+ break ;
376+ case Type::Float64:
377+ ostr << static_cast <double >(item_view.get <double >());
378+ break ;
379+ case Type::String:
380+ case Type::FixedString:
381+ ostr << " \" " << item_view.data << " \" (" << item_view.data .size () << " bytes)" ;
382+ break ;
383+ case Type::Date:
384+ ostr << DateTimeValue (item_view.get <uint16_t >() * 86400 );
385+ break ;
386+ case Type::Date32:
387+ ostr << DateTimeValue (item_view.get <int32_t >() * 86400 );
388+ break ;
389+ case Type::DateTime:
390+ ostr << DateTimeValue (item_view.get <uint32_t >());
391+ break ;
392+ case Type::DateTime64: {
393+ if (item_view.data .size () == 4 ) {
394+ ostr << DateTimeValue (item_view.get <int32_t >());
395+ }
396+ else if (item_view.data .size () == 8 ) {
397+ ostr << DateTimeValue (item_view.get <int64_t >());
398+ }
399+ else if (item_view.data .size () == 16 ) {
400+ ostr << DateTimeValue (item_view.get <Int128>());
401+ }
402+ else {
403+ throw std::runtime_error (" Invalid data size of ItemView of type DateTime64" );
404+ }
405+ break ;
406+ }
407+ case Type::Enum8:
408+ ostr << static_cast <unsigned int >(item_view.get <uint8_t >());
409+ break ;
410+ case Type::Enum16:
411+ ostr << static_cast <unsigned int >(item_view.get <uint16_t >());
412+ break ;
413+ case Type::UUID: {
414+ const auto & uuid_vals = reinterpret_cast <const uint64_t *>(item_view.data .data ());
415+ ostr << ToString (clickhouse::UUID{uuid_vals[0 ], uuid_vals[1 ]});
416+ break ;
417+ }
418+ case Type::IPv4: {
419+ in_addr addr;
420+ addr.s_addr = ntohl (item_view.get <uint32_t >());
421+ ostr << addr;
422+ break ;
423+ }
424+ case Type::IPv6:
425+ ostr << *reinterpret_cast <const in6_addr*>(item_view.AsBinaryData ().data ());
426+ break ;
427+ case Type::Int128:
428+ ostr << item_view.get <Int128>();
429+ break ;
430+ case Type::UInt128:
431+ ostr << item_view.get <UInt128>();
432+ break ;
433+ case Type::Decimal: {
434+ if (item_view.data .size () == 4 ) {
435+ ostr << item_view.get <int32_t >();
436+ }
437+ else if (item_view.data .size () == 8 ) {
438+ ostr << item_view.get <int64_t >();
439+ }
440+ else if (item_view.data .size () == 16 ) {
441+ ostr << item_view.get <Int128>();
442+ }
443+ else {
444+ throw std::runtime_error (" Invalid data size of ItemView of type DateTime64" );
445+ }
446+ }
447+ break ;
448+ case Type::Decimal32:
449+ ostr << DateTimeValue (item_view.get <int32_t >());
450+ break ;
451+ case Type::Decimal64:
452+ ostr << DateTimeValue (item_view.get <int64_t >());
453+ break ;
454+ case Type::Decimal128:
455+ ostr << DateTimeValue (item_view.get <Int128>());
456+ break ;
457+ // Unsupported types. i.e. there shouldn't be `ItemView`s of those types in practice.
458+ // either because GetItem() is not implemented for corresponding column type
459+ // OR this type code is never used, for `ItemView`s (but type code of wrapped column is).
460+ case Type::LowCardinality:
461+ case Type::Array:
462+ case Type::Nullable:
463+ case Type::Tuple:
464+ case Type::Map:
465+ case Type::Point:
466+ case Type::Ring:
467+ case Type::Polygon:
468+ case Type::MultiPolygon: {
469+ throw std::runtime_error (" Invalid data size of ItemView of type " + std::string (Type::TypeName (item_view.type )));
470+ }
471+ };
472+
473+ return ostr << " }" ;
474+ }
475+
476+
335477}
336478
337479uint64_t versionNumber (const ServerInfo & server_info) {
0 commit comments