MCPcopy Create free account
hub / github.com/ByConity/ByConity / executeImpl

Method executeImpl

src/Functions/map.cpp:978–1030  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

976 inline String getColumnStringValue(const ColumnWithTypeAndName & argument) const { return argument.column->getDataAt(0).toString(); }
977
978 ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
979 {
980 String db_name = getColumnStringValue(arguments[0]);
981 String table_name = getColumnStringValue(arguments[1]);
982 String column_name = getColumnStringValue(arguments[2]);
983 if (db_name.empty() || table_name.empty() || column_name.empty())
984 throw Exception("Bad arguments: database/table/column should not be empty", ErrorCodes::BAD_ARGUMENTS);
985
986 String pattern;
987 if (arguments.size() >= 4)
988 {
989 pattern = getColumnStringValue(arguments[3]);
990 }
991
992 /// Check byte map type
993 auto table_id = context->resolveStorageID({db_name, table_name});
994 auto table = DatabaseCatalog::instance().getTable(table_id, context);
995 auto metadata_snapshot = table->getInMemoryMetadataPtr();
996 if (!metadata_snapshot || !metadata_snapshot->columns.hasPhysical(column_name))
997 throw Exception(ErrorCodes::BAD_ARGUMENTS, "Table {}.{} doesn't contain column {}", db_name, table_name, column_name);
998 auto type = metadata_snapshot->columns.getPhysical(column_name).type;
999 if (!type->isMap() || type->isKVMap())
1000 throw Exception(
1001 ErrorCodes::BAD_ARGUMENTS, "Function getMapKeys must apply to ByteMap but given {}", type->isKVMap() ? "KV map" : type->getName());
1002
1003 /**
1004 SELECT groupUniqArrayArray(ks) AS keys FROM (
1005 SELECT arrayMap(t -> t.2, arrayFilter(t -> t.1 = 'some_map', _map_column_keys)) AS ks
1006 FROM some_db.some_table WHERE match(_partition_id, '.*2020.*10.*10.*')
1007 ) SETTINGS early_limit_for_map_virtual_columns = 1, max_threads = 1
1008 */
1009 String inner_query = "SELECT arrayMap(t -> t.2, arrayFilter(t -> t.1 = '" + column_name + "', _map_column_keys)) AS ks" //
1010 + " FROM `" + db_name + "`.`" + table_name + "`" //
1011 + (pattern.empty() ? "" : " WHERE match(_partition_id, '" + pattern + "')");
1012 String query = "SELECT groupUniqArrayArray(ks) AS keys FROM ( " + inner_query
1013 + " ) SETTINGS early_limit_for_map_virtual_columns = 1, max_threads = 1";
1014
1015 auto query_context = createContextForSubQuery(context);
1016 auto res = executeSubQueryWithOneRow(query, query_context, true);
1017 if (res)
1018 {
1019 // TODO(shiyuze): maybe add a new function to get result in different rows, just like arrayJoin(getMapKeys(xxx))
1020
1021 /// Total map key number in result may exceed max_array_size_as_field (for example,
1022 /// each pratition or bucket has different key sets), so we need to avoid calling
1023 /// ColumnArray::[] or ColumnArray::get() to get array as a Field here.
1024 return ColumnConst::create(res.getByName("keys").column, input_rows_count)->convertToFullColumnIfConst();
1025 }
1026 else
1027 {
1028 return result_type->createColumnConst(input_rows_count, Array{})->convertToFullColumnIfConst();
1029 }
1030 }
1031
1032 /// override executeImplDryRun to prevent calling getMapKeys multi times under
1033 /// same txn id, which may cause worker create table multi times

Callers

nothing calls this directly

Calls 15

createContextForSubQueryFunction · 0.85
resolveStorageIDMethod · 0.80
hasPhysicalMethod · 0.80
getPhysicalMethod · 0.80
getByNameMethod · 0.80
createColumnConstMethod · 0.80
createFunction · 0.70
ExceptionClass · 0.50
emptyMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected