fix several cases, while reading subcolumns

This commit is contained in:
Anton Popov 2021-01-21 15:34:11 +03:00
parent fe6b964b32
commit ac3de63a71
6 changed files with 75 additions and 9 deletions

View File

@ -546,7 +546,7 @@ ColumnPtr DataTypeNullable::getSubcolumn(const String & subcolumn_name, const IC
{
const auto & column_nullable = assert_cast<const ColumnNullable &>(column);
if (subcolumn_name == "null")
return column_nullable.getNullMapColumnPtr()->assumeMutable();
return column_nullable.getNullMapColumnPtr();
return nested_data_type->getSubcolumn(subcolumn_name, column_nullable.getNestedColumn());
}

View File

@ -331,8 +331,7 @@ NamesAndTypesList ColumnsDescription::getAll() const
bool ColumnsDescription::has(const String & column_name) const
{
return columns.get<1>().find(column_name) != columns.get<1>().end()
|| subcolumns.find(column_name) != subcolumns.end();
return columns.get<1>().find(column_name) != columns.get<1>().end();
}
bool ColumnsDescription::hasNested(const String & column_name) const
@ -341,6 +340,16 @@ bool ColumnsDescription::hasNested(const String & column_name) const
return range.first != range.second && range.first->name.length() > column_name.length();
}
bool ColumnsDescription::hasSubcolumn(const String & column_name) const
{
return subcolumns.find(column_name) != subcolumns.end();
}
bool ColumnsDescription::hasInStorageOrSubcolumn(const String & column_name) const
{
return has(column_name) || hasSubcolumn(column_name);
}
const ColumnDescription & ColumnsDescription::get(const String & column_name) const
{
auto it = columns.get<1>().find(column_name);

View File

@ -85,6 +85,8 @@ public:
bool has(const String & column_name) const;
bool hasNested(const String & column_name) const;
bool hasSubcolumn(const String & column_name) const;
bool hasInStorageOrSubcolumn(const String & column_name) const;
const ColumnDescription & get(const String & column_name) const;
template <typename F>

View File

@ -879,6 +879,8 @@ void IMergeTreeDataPart::loadColumns(bool require)
{
String path = getFullRelativePath() + "columns.txt";
auto metadata_snapshot = storage.getInMemoryMetadataPtr();
NamesAndTypesList loaded_columns;
if (!volume->getDisk()->exists(path))
{
/// We can get list of columns only from columns.txt in compact parts.
@ -888,25 +890,23 @@ void IMergeTreeDataPart::loadColumns(bool require)
/// If there is no file with a list of columns, write it down.
for (const NameAndTypePair & column : metadata_snapshot->getColumns().getAllPhysical())
if (volume->getDisk()->exists(getFullRelativePath() + getFileNameForColumn(column) + ".bin"))
columns.push_back(column);
loaded_columns.push_back(column);
if (columns.empty())
throw Exception("No columns in part " + name, ErrorCodes::NO_FILE_IN_DATA_PART);
{
auto buf = volume->getDisk()->writeFile(path + ".tmp", 4096);
columns.writeText(*buf);
loaded_columns.writeText(*buf);
}
volume->getDisk()->moveFile(path + ".tmp", path);
}
else
{
columns.readText(*volume->getDisk()->readFile(path));
loaded_columns.readText(*volume->getDisk()->readFile(path));
}
size_t pos = 0;
for (const auto & column : columns)
column_name_to_position.emplace(column.name, pos++);
setColumns(loaded_columns);
}
bool IMergeTreeDataPart::shallParticipateInMerges(const StoragePolicyPtr & storage_policy) const

View File

@ -0,0 +1,16 @@
Nullable
2
2
2
2
Map
2
2
2
2
2
2
1 2
2 2
3 3
1

View File

@ -0,0 +1,39 @@
DROP TABLE IF EXISTS null_subcolumns;
SELECT 'Nullable';
CREATE TABLE null_subcolumns (id UInt32, n Nullable(String)) ENGINE = MergeTree ORDER BY id;
INSERT INTO null_subcolumns VALUES (1, 'foo') (2, NULL) (3, NULL) (4, 'abc');
SELECT count() FROM null_subcolumns WHERE n.null;
SELECT count() FROM null_subcolumns PREWHERE n.null;
-- Check, that subcolumns will be available after restart.
DETACH TABLE null_subcolumns;
ATTACH TABLE null_subcolumns;
SELECT count() FROM null_subcolumns WHERE n.null;
SELECT count() FROM null_subcolumns PREWHERE n.null;
DROP TABLE null_subcolumns;
DROP TABLE IF EXISTS map_subcolumns;
SELECT 'Map';
SET allow_experimental_map_type = 1;
CREATE TABLE map_subcolumns (id UInt32, m Map(String, UInt32)) ENGINE = MergeTree ORDER BY id;
INSERT INTO map_subcolumns VALUES (1, map('a', 1, 'b', 2)) (2, map('a', 3, 'c', 4)), (3, map('b', 5, 'c', 6, 'd', 7));
SELECT count() FROM map_subcolumns WHERE has(m.keys, 'a');
SELECT count() FROM map_subcolumns PREWHERE has(m.keys, 'b');
SELECT count() FROM map_subcolumns WHERE arrayMax(m.values) > 3;
SELECT count() FROM map_subcolumns PREWHERE arrayMax(m.values) > 3;
DETACH TABLE map_subcolumns;
ATTACH TABLE map_subcolumns;
SELECT count() FROM map_subcolumns WHERE has(m.keys, 'a');
SELECT count() FROM map_subcolumns PREWHERE has(m.keys, 'b');
SELECT id, m.size0 FROM map_subcolumns;
SELECT count() FROM map_subcolumns WHERE m.size0 > 2;