mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Fixed parsing and interpreting of tuples [#CLICKHOUSE-2].
This commit is contained in:
parent
22f69f5c5f
commit
903dc680bb
@ -122,7 +122,10 @@ void DataTypeTuple::deserializeText(IColumn & column, ReadBuffer & istr) const
|
|||||||
{
|
{
|
||||||
skipWhitespaceIfAny(istr);
|
skipWhitespaceIfAny(istr);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
|
{
|
||||||
assertChar(',', istr);
|
assertChar(',', istr);
|
||||||
|
skipWhitespaceIfAny(istr);
|
||||||
|
}
|
||||||
elems[i]->deserializeTextQuoted(extractElementColumn(column, i), istr);
|
elems[i]->deserializeTextQuoted(extractElementColumn(column, i), istr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -174,7 +177,10 @@ void DataTypeTuple::deserializeTextJSON(IColumn & column, ReadBuffer & istr) con
|
|||||||
{
|
{
|
||||||
skipWhitespaceIfAny(istr);
|
skipWhitespaceIfAny(istr);
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
|
{
|
||||||
assertChar(',', istr);
|
assertChar(',', istr);
|
||||||
|
skipWhitespaceIfAny(istr);
|
||||||
|
}
|
||||||
elems[i]->deserializeTextJSON(extractElementColumn(column, i), istr);
|
elems[i]->deserializeTextJSON(extractElementColumn(column, i), istr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <IO/ReadHelpers.h>
|
#include <IO/ReadHelpers.h>
|
||||||
|
|
||||||
#include <DataTypes/DataTypeArray.h>
|
#include <DataTypes/DataTypeArray.h>
|
||||||
|
#include <DataTypes/DataTypeTuple.h>
|
||||||
#include <DataTypes/DataTypesNumber.h>
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
#include <DataTypes/DataTypeString.h>
|
#include <DataTypes/DataTypeString.h>
|
||||||
#include <DataTypes/DataTypeFixedString.h>
|
#include <DataTypes/DataTypeFixedString.h>
|
||||||
@ -107,16 +108,16 @@ Field convertFieldToTypeImpl(const Field & src, const IDataType & type)
|
|||||||
{
|
{
|
||||||
if (type.isNumeric())
|
if (type.isNumeric())
|
||||||
{
|
{
|
||||||
if (typeid_cast<const DataTypeUInt8 *>(&type)) return convertNumericType<UInt8>(src, type);
|
if (typeid_cast<const DataTypeUInt8 *>(&type)) return convertNumericType<UInt8>(src, type);
|
||||||
if (typeid_cast<const DataTypeUInt16 *>(&type)) return convertNumericType<UInt16>(src, type);
|
if (typeid_cast<const DataTypeUInt16 *>(&type)) return convertNumericType<UInt16>(src, type);
|
||||||
if (typeid_cast<const DataTypeUInt32 *>(&type)) return convertNumericType<UInt32>(src, type);
|
if (typeid_cast<const DataTypeUInt32 *>(&type)) return convertNumericType<UInt32>(src, type);
|
||||||
if (typeid_cast<const DataTypeUInt64 *>(&type)) return convertNumericType<UInt64>(src, type);
|
if (typeid_cast<const DataTypeUInt64 *>(&type)) return convertNumericType<UInt64>(src, type);
|
||||||
if (typeid_cast<const DataTypeInt8 *>(&type)) return convertNumericType<Int8>(src, type);
|
if (typeid_cast<const DataTypeInt8 *>(&type)) return convertNumericType<Int8>(src, type);
|
||||||
if (typeid_cast<const DataTypeInt16 *>(&type)) return convertNumericType<Int16>(src, type);
|
if (typeid_cast<const DataTypeInt16 *>(&type)) return convertNumericType<Int16>(src, type);
|
||||||
if (typeid_cast<const DataTypeInt32 *>(&type)) return convertNumericType<Int32>(src, type);
|
if (typeid_cast<const DataTypeInt32 *>(&type)) return convertNumericType<Int32>(src, type);
|
||||||
if (typeid_cast<const DataTypeInt64 *>(&type)) return convertNumericType<Int64>(src, type);
|
if (typeid_cast<const DataTypeInt64 *>(&type)) return convertNumericType<Int64>(src, type);
|
||||||
if (typeid_cast<const DataTypeFloat32 *>(&type)) return convertNumericType<Float32>(src, type);
|
if (typeid_cast<const DataTypeFloat32 *>(&type)) return convertNumericType<Float32>(src, type);
|
||||||
if (typeid_cast<const DataTypeFloat64 *>(&type)) return convertNumericType<Float64>(src, type);
|
if (typeid_cast<const DataTypeFloat64 *>(&type)) return convertNumericType<Float64>(src, type);
|
||||||
|
|
||||||
const bool is_date = typeid_cast<const DataTypeDate *>(&type);
|
const bool is_date = typeid_cast<const DataTypeDate *>(&type);
|
||||||
bool is_datetime = false;
|
bool is_datetime = false;
|
||||||
@ -155,41 +156,51 @@ Field convertFieldToTypeImpl(const Field & src, const IDataType & type)
|
|||||||
return dynamic_cast<const IDataTypeEnum &>(type).castToValue(src);
|
return dynamic_cast<const IDataTypeEnum &>(type).castToValue(src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
throw Exception("Type mismatch in IN or VALUES section. Expected: " + type.getName() + ". Got: "
|
else if (typeid_cast<const DataTypeString *>(&type)
|
||||||
+ Field::Types::toString(src.getType()), ErrorCodes::TYPE_MISMATCH);
|
|| typeid_cast<const DataTypeFixedString *>(&type))
|
||||||
|
{
|
||||||
|
if (src.getType() == Field::Types::String)
|
||||||
|
return src;
|
||||||
}
|
}
|
||||||
else if (const DataTypeArray * type_array = typeid_cast<const DataTypeArray *>(&type))
|
else if (const DataTypeArray * type_array = typeid_cast<const DataTypeArray *>(&type))
|
||||||
{
|
{
|
||||||
if (src.getType() != Field::Types::Array)
|
if (src.getType() == Field::Types::Array)
|
||||||
throw Exception("Type mismatch in IN or VALUES section. Expected: " + type.getName() + ". Got: "
|
{
|
||||||
+ Field::Types::toString(src.getType()), ErrorCodes::TYPE_MISMATCH);
|
const IDataType & nested_type = *DataTypeTraits::removeNullable(type_array->getNestedType());
|
||||||
|
|
||||||
const IDataType & nested_type = *DataTypeTraits::removeNullable(type_array->getNestedType());
|
const Array & src_arr = src.get<Array>();
|
||||||
|
size_t src_arr_size = src_arr.size();
|
||||||
|
|
||||||
const Array & src_arr = src.get<Array>();
|
Array res(src_arr_size);
|
||||||
size_t src_arr_size = src_arr.size();
|
for (size_t i = 0; i < src_arr_size; ++i)
|
||||||
|
res[i] = convertFieldToType(src_arr[i], nested_type);
|
||||||
|
|
||||||
Array res(src_arr_size);
|
return res;
|
||||||
for (size_t i = 0; i < src_arr_size; ++i)
|
}
|
||||||
res[i] = convertFieldToType(src_arr[i], nested_type);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
else
|
else if (const DataTypeTuple * type_tuple = typeid_cast<const DataTypeTuple *>(&type))
|
||||||
{
|
{
|
||||||
if (src.getType() == Field::Types::UInt64
|
if (src.getType() == Field::Types::Tuple)
|
||||||
|| src.getType() == Field::Types::Int64
|
{
|
||||||
|| src.getType() == Field::Types::Float64
|
const TupleBackend & src_tuple = src.get<Tuple>();
|
||||||
|| src.getType() == Field::Types::Array
|
size_t src_tuple_size = src_tuple.size();
|
||||||
|| (src.getType() == Field::Types::String
|
size_t dst_tuple_size = type_tuple->getElements().size();
|
||||||
&& !typeid_cast<const DataTypeString *>(&type)
|
|
||||||
&& !typeid_cast<const DataTypeFixedString *>(&type)))
|
if (dst_tuple_size != src_tuple_size)
|
||||||
throw Exception("Type mismatch in IN or VALUES section. Expected: " + type.getName() + ". Got: "
|
throw Exception("Bad size of tuple in IN or VALUES section. Expected size: "
|
||||||
+ Field::Types::toString(src.getType()), ErrorCodes::TYPE_MISMATCH);
|
+ toString(dst_tuple_size) + ", actual size: " + toString(src_tuple_size), ErrorCodes::TYPE_MISMATCH);
|
||||||
|
|
||||||
|
TupleBackend res(dst_tuple_size);
|
||||||
|
for (size_t i = 0; i < dst_tuple_size; ++i)
|
||||||
|
res[i] = convertFieldToType(src_tuple[i], *type_tuple->getElements()[i]);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return src;
|
throw Exception("Type mismatch in IN or VALUES section. Expected: " + type.getName() + ". Got: "
|
||||||
|
+ Field::Types::toString(src.getType()), ErrorCodes::TYPE_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
('2000-01-01',15,51)
|
||||||
|
('2000-01-01',123,456)
|
@ -0,0 +1,9 @@
|
|||||||
|
DROP TABLE IF EXISTS test.tuple;
|
||||||
|
CREATE TABLE test.tuple (t Tuple(Date, UInt32, UInt64)) ENGINE = Memory;
|
||||||
|
INSERT INTO test.tuple VALUES ((concat('2000', '-01-01'), /* Hello */ 12+3, 45+6));
|
||||||
|
|
||||||
|
SET input_format_values_interpret_expressions = 0;
|
||||||
|
INSERT INTO test.tuple VALUES (('2000-01-01', 123, 456));
|
||||||
|
|
||||||
|
SELECT * FROM test.tuple;
|
||||||
|
DROP TABLE test.tuple;
|
Loading…
Reference in New Issue
Block a user