diff --git a/src/include/planner/operator/schema.h b/src/include/planner/operator/schema.h index 22769a455..28d5c892e 100644 --- a/src/include/planner/operator/schema.h +++ b/src/include/planner/operator/schema.h @@ -38,8 +38,10 @@ class FactorizationGroup { double getMultiplier() const { return cardinalityMultiplier; } void insertExpression(const std::shared_ptr& expression) { - DASSERT(!expressionNameToPos.contains(expression->getUniqueName())); - expressionNameToPos.insert({expression->getUniqueName(), expressions.size()}); + // A projection keeps out-of-scope expressions in their groups, so one with the same unique + // name may already be here, e.g. an ORDER BY key a WITH dropped. The new expression gets + // its own position: the old one's is still written by the operator that produced it. + expressionNameToPos.insert_or_assign(expression->getUniqueName(), expressions.size()); expressions.push_back(expression); } binder::expression_vector getExpressions() const { return expressions; } diff --git a/test/test_files/order_by/order_by_key_repeated.test b/test/test_files/order_by/order_by_key_repeated.test new file mode 100644 index 000000000..25f4ec720 --- /dev/null +++ b/test/test_files/order_by/order_by_key_repeated.test @@ -0,0 +1,21 @@ +-DATASET CSV empty + +-- + +-CASE ProjectionRepeatsDiscardedOrderByKey +-LOOP i 1 2000 +-STATEMENT UNWIND [10, 20, NULL, 5] AS x WITH x ORDER BY x + x SKIP 0 RETURN x + x AS y +-CHECK_ORDER +---- 4 +10 +20 +40 + +-STATEMENT UNWIND [10, 20, NULL, 5] AS x WITH x ORDER BY x * x SKIP 0 RETURN x * x AS y +-CHECK_ORDER +---- 4 +25 +100 +400 + +-ENDLOOP