11#include " QueryHandlerImpl.hpp"
22
3+ #include < cstddef>
34#include < exception>
45#include < memory>
56#include < optional>
@@ -54,6 +55,7 @@ using clp_s::search::ast::literal_type_bitmask_t;
5455/* *
5556 * Creates column descriptors and column-to-original-key map from the given projections.
5657 * @param projections
58+ * @param allow_duplicate_projected_columns Whether to allow duplicate projected columns.
5759 * @return A result containing a pair or an error code indicating the failure:
5860 * - The pair:
5961 * - A vector of projected columns.
@@ -65,7 +67,8 @@ using clp_s::search::ast::literal_type_bitmask_t;
6567 * descriptor for the projected key.
6668 */
6769[[nodiscard]] auto create_projected_columns_and_projection_map (
68- std::vector<std::pair<std::string, literal_type_bitmask_t >> const & projections
70+ std::vector<std::pair<std::string, literal_type_bitmask_t >> const & projections,
71+ bool allow_duplicate_projected_columns
6972)
7073 -> ystdlib::error_handling::Result<std::pair<
7174 std::vector<std::shared_ptr<ColumnDescriptor>>,
@@ -74,7 +77,7 @@ using clp_s::search::ast::literal_type_bitmask_t;
7477/* *
7578 * Creates initial partial resolutions for the given query and projections.
7679 * @param query
77- * @param projected_column_to_original_key
80+ * @param projected_column_to_original_key_and_index
7881 * @return A result containing a pair or an error code indicating the failure:
7982 * - The pair:
8083 * - The partial resolution for auto-generated keys.
@@ -86,7 +89,7 @@ using clp_s::search::ast::literal_type_bitmask_t;
8689 */
8790[[nodiscard]] auto create_initial_partial_resolutions (
8891 std::shared_ptr<Expression> const & query,
89- QueryHandlerImpl::ProjectionMap const & projected_column_to_original_key
92+ QueryHandlerImpl::ProjectionMap const & projected_column_to_original_key_and_index
9093)
9194 -> ystdlib::error_handling::Result<std::pair<
9295 QueryHandlerImpl::PartialResolutionMap,
@@ -182,20 +185,24 @@ auto preprocess_query(std::shared_ptr<Expression> query)
182185}
183186
184187auto create_projected_columns_and_projection_map (
185- std::vector<std::pair<std::string, literal_type_bitmask_t >> const & projections
188+ std::vector<std::pair<std::string, literal_type_bitmask_t >> const & projections,
189+ bool allow_duplicate_projected_columns
186190)
187191 -> ystdlib::error_handling::Result<std::pair<
188192 std::vector<std::shared_ptr<ColumnDescriptor>>,
189193 QueryHandlerImpl::ProjectionMap>> {
190194 std::unordered_set<std::string_view> unique_projected_columns;
191195 std::vector<std::shared_ptr<ColumnDescriptor>> projected_columns;
192- QueryHandlerImpl::ProjectionMap projected_column_to_original_key ;
196+ QueryHandlerImpl::ProjectionMap projected_column_to_original_key_and_index ;
193197
194- for (auto const & [key, types] : projections) {
195- if (unique_projected_columns.contains (key)) {
196- return ErrorCode{ErrorCodeEnum::DuplicateProjectedColumn};
198+ for (size_t index{0 }; index < projections.size (); ++index) {
199+ auto const & [key, types] = projections[index];
200+ if (false == allow_duplicate_projected_columns) {
201+ if (unique_projected_columns.contains (key)) {
202+ return ErrorCode{ErrorCodeEnum::DuplicateProjectedColumn};
203+ }
204+ unique_projected_columns.emplace (key);
197205 }
198- unique_projected_columns.emplace (key);
199206
200207 std::vector<std::string> descriptor_tokens;
201208 std::string descriptor_namespace;
@@ -220,26 +227,29 @@ auto create_projected_columns_and_projection_map(
220227 {
221228 return ErrorCode{ErrorCodeEnum::ProjectionColumnDescriptorCreationFailure};
222229 }
223- projected_column_to_original_key.emplace (column_descriptor.get (), key);
230+ projected_column_to_original_key_and_index.emplace (
231+ column_descriptor.get (),
232+ std::make_pair (key, index)
233+ );
224234 projected_columns.emplace_back (std::move (column_descriptor));
225235 } catch (std::exception const & e) {
226236 return ErrorCode{ErrorCodeEnum::ProjectionColumnDescriptorCreationFailure};
227237 }
228238 }
229239
230- return {std::move (projected_columns), std::move (projected_column_to_original_key )};
240+ return {std::move (projected_columns), std::move (projected_column_to_original_key_and_index )};
231241}
232242
233243auto create_initial_partial_resolutions (
234244 std::shared_ptr<Expression> const & query,
235- QueryHandlerImpl::ProjectionMap const & projected_column_to_original_key
245+ QueryHandlerImpl::ProjectionMap const & projected_column_to_original_key_and_index
236246)
237247 -> ystdlib::error_handling::Result<std::pair<
238248 QueryHandlerImpl::PartialResolutionMap,
239249 QueryHandlerImpl::PartialResolutionMap>> {
240250 QueryHandlerImpl::PartialResolutionMap auto_gen_namespace_partial_resolutions;
241251 QueryHandlerImpl::PartialResolutionMap user_gen_namespace_partial_resolutions;
242- for (auto const & [col, key ] : projected_column_to_original_key ) {
252+ for (auto const & [col, _ ] : projected_column_to_original_key_and_index ) {
243253 auto const optional_is_auto_gen{is_auto_generated (col->get_namespace ())};
244254 if (false == optional_is_auto_gen.has_value ()) {
245255 // Ignore unrecognized namespace
@@ -408,22 +418,27 @@ auto evaluate_wildcard_filter(
408418auto QueryHandlerImpl::create (
409419 std::shared_ptr<Expression> query,
410420 std::vector<std::pair<std::string, literal_type_bitmask_t >> const & projections,
411- bool case_sensitive_match
421+ bool case_sensitive_match,
422+ bool allow_duplicate_projected_columns
412423) -> ystdlib::error_handling::Result<QueryHandlerImpl> {
413424 query = YSTDLIB_ERROR_HANDLING_TRYX (preprocess_query (query));
414- auto [projected_columns, projected_column_to_original_key]
415- = YSTDLIB_ERROR_HANDLING_TRYX (create_projected_columns_and_projection_map (projections));
425+ auto [projected_columns, projected_column_to_original_key_and_index]
426+ = YSTDLIB_ERROR_HANDLING_TRYX (create_projected_columns_and_projection_map (
427+ projections,
428+ allow_duplicate_projected_columns
429+ ));
416430 auto [auto_gen_namespace_partial_resolutions, user_gen_namespace_partial_resolutions]
417- = YSTDLIB_ERROR_HANDLING_TRYX (
418- create_initial_partial_resolutions (query, projected_column_to_original_key)
419- );
431+ = YSTDLIB_ERROR_HANDLING_TRYX (create_initial_partial_resolutions (
432+ query,
433+ projected_column_to_original_key_and_index
434+ ));
420435
421436 return QueryHandlerImpl{
422437 std::move (query),
423438 std::move (auto_gen_namespace_partial_resolutions),
424439 std::move (user_gen_namespace_partial_resolutions),
425440 std::move (projected_columns),
426- std::move (projected_column_to_original_key ),
441+ std::move (projected_column_to_original_key_and_index ),
427442 case_sensitive_match
428443 };
429444}
0 commit comments