| 909 | } |
| 910 | |
| 911 | RelationPlan |
| 912 | QueryPlannerVisitor::planReadFromStorage(IAST & table_ast, ScopePtr table_scope, ASTSelectQuery & origin_query, SqlHints & hints, bool is_table_function) |
| 913 | { |
| 914 | const auto & storage_analysis = analysis.getStorageAnalysis(table_ast); |
| 915 | const auto & storage = storage_analysis.storage; |
| 916 | const auto & alias = table_ast.tryGetAlias(); |
| 917 | |
| 918 | auto primary_column_size = table_scope->size(); |
| 919 | const auto & used_columns = analysis.getReadColumns(table_ast); |
| 920 | const auto & used_sub_columns = analysis.getReadSubColumns(table_ast); |
| 921 | NamesWithAliases columns_with_aliases; |
| 922 | // note primary column and sub columns may overlap, we use a map to keep allocated columns |
| 923 | // e.g. SELECT m{'foo'}, __m__foo from t; |
| 924 | NameToNameMap columns_to_aliases; |
| 925 | FieldSymbolInfos field_symbols; |
| 926 | |
| 927 | field_symbols.reserve(primary_column_size); |
| 928 | columns_with_aliases.reserve(primary_column_size); // may be larger |
| 929 | |
| 930 | assert(used_sub_columns.size() <= primary_column_size); |
| 931 | |
| 932 | for (size_t i = 0; i < primary_column_size; ++i) |
| 933 | { |
| 934 | const auto & primary_column_name = table_scope->at(i).getOriginColumnName(); |
| 935 | String primary_column_symbol; |
| 936 | FieldSymbolInfo::SubColumnToSymbol sub_column_symbols; |
| 937 | |
| 938 | // allocate primary columns, not allocate if it is not used |
| 939 | if (used_columns.count(i) || (i < used_sub_columns.size() && !used_sub_columns[i].empty())) |
| 940 | { |
| 941 | if (!columns_to_aliases.count(primary_column_name)) |
| 942 | { |
| 943 | primary_column_symbol = context->getSymbolAllocator()->newSymbol(primary_column_name); |
| 944 | columns_with_aliases.emplace_back(primary_column_name, primary_column_symbol); |
| 945 | columns_to_aliases.emplace(primary_column_name, primary_column_symbol); |
| 946 | } |
| 947 | else |
| 948 | { |
| 949 | primary_column_symbol = columns_to_aliases.at(primary_column_name); |
| 950 | } |
| 951 | } |
| 952 | |
| 953 | // allocate sub columns |
| 954 | if (i < used_sub_columns.size()) |
| 955 | { |
| 956 | for (const auto & sub_column_id : used_sub_columns[i]) |
| 957 | { |
| 958 | auto sub_column_name = sub_column_id.getSubColumnName(primary_column_name); |
| 959 | if (!columns_to_aliases.count(sub_column_name)) |
| 960 | { |
| 961 | auto sub_column_symbol = context->getSymbolAllocator()->newSymbol(sub_column_name); |
| 962 | columns_with_aliases.emplace_back(sub_column_name, sub_column_symbol); |
| 963 | columns_to_aliases.emplace(sub_column_name, sub_column_symbol); |
| 964 | sub_column_symbols.emplace(sub_column_id, sub_column_symbol); |
| 965 | } |
| 966 | else |
| 967 | { |
| 968 | sub_column_symbols.emplace(sub_column_id, columns_to_aliases.at(sub_column_name)); |
nothing calls this directly
no test coverage detected