MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / getSubcolumnData

Method getSubcolumnData

src/DataTypes/IDataType.cpp:154–231  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

152}
153
154std::unique_ptr<IDataType::SubstreamData> IDataType::getSubcolumnData(
155 std::string_view subcolumn_name,
156 const SubstreamData & data,
157 size_t initial_array_level,
158 bool throw_if_null)
159{
160 std::unique_ptr<IDataType::SubstreamData> res;
161 /// Track whether res was set by an exact name match, so that exact matches
162 /// always take priority over prefix (dynamic subcolumn) matches.
163 /// This matters when e.g. JSON has typed paths "a" (Array(JSON)) and "a.b" (Int64):
164 /// without this, the prefix match on "a" would fire first (sorted order) and
165 /// the exact match on "a.b" would be skipped because res is already set.
166 bool res_from_exact_match = false;
167
168 ISerialization::StreamCallback callback_with_data = [&](const auto & subpath)
169 {
170 for (size_t i = 0; i < subpath.size(); ++i)
171 {
172 size_t prefix_len = i + 1;
173 if (!subpath[i].visited && ISerialization::hasSubcolumnForPath(subpath, prefix_len))
174 {
175 auto name = ISerialization::getSubcolumnNameForStream(subpath, prefix_len, false, initial_array_level);
176 /// Create data from path only if it's requested subcolumn.
177 /// Use the first exact match to be consistent with ColumnsDescription::addSubcolumns
178 /// which also keeps the first subcolumn when there are name collisions
179 /// (e.g. "null" can match both Nullable's null-map and a Tuple element named "null").
180 /// Exact matches always take priority over prefix matches regardless of iteration order.
181 if (name == subcolumn_name && !res_from_exact_match)
182 {
183 res = std::make_unique<SubstreamData>(ISerialization::createFromPath(subpath, prefix_len));
184 res_from_exact_match = true;
185 }
186 /// Check if this subcolumn is a prefix of requested subcolumn and it can create dynamic subcolumns.
187 /// Only use prefix matches when no exact match has been found.
188 else if (!res_from_exact_match && subcolumn_name.starts_with(name + ".") && subpath[i].data.type && subpath[i].data.type->hasDynamicSubcolumnsData())
189 {
190 auto dynamic_subcolumn_name = subcolumn_name.substr(name.size() + 1);
191 auto dynamic_subcolumn_data = subpath[i].data.type->getDynamicSubcolumnData(
192 dynamic_subcolumn_name,
193 subpath[i].data,
194 initial_array_level + ISerialization::getArrayLevel(subpath, prefix_len),
195 false);
196 if (dynamic_subcolumn_data)
197 {
198 /// Create requested subcolumn using dynamic subcolumn data.
199 auto tmp_subpath = subpath;
200 if (tmp_subpath[i].creator)
201 {
202 dynamic_subcolumn_data->type = tmp_subpath[i].creator->create(dynamic_subcolumn_data->type);
203 dynamic_subcolumn_data->column = tmp_subpath[i].creator->create(dynamic_subcolumn_data->column);
204 dynamic_subcolumn_data->serialization = tmp_subpath[i].creator->create(dynamic_subcolumn_data->serialization, dynamic_subcolumn_data->type);
205 }
206
207 tmp_subpath[i].data = *dynamic_subcolumn_data;
208 res = std::make_unique<SubstreamData>(ISerialization::createFromPath(tmp_subpath, prefix_len));
209 }
210 }
211 }

Callers

nothing calls this directly

Calls 7

ExceptionClass · 0.50
sizeMethod · 0.45
createMethod · 0.45
enumerateStreamsMethod · 0.45
getNameMethod · 0.45

Tested by

no test coverage detected