@@ -76,7 +76,7 @@ DuckDBPyRelation::DuckDBPyRelation(shared_ptr<DuckDBPyResult> result_p) : rel(nu
7676}
7777
7878unique_ptr<DuckDBPyRelation> DuckDBPyRelation::ProjectFromExpression (const string &expression) {
79- auto projected_relation = make_uniq<DuckDBPyRelation> (rel->Project (expression));
79+ auto projected_relation = DeriveRelation (rel->Project (expression));
8080 for (auto &dep : this ->rel ->external_dependencies ) {
8181 projected_relation->rel ->AddExternalDependency (dep);
8282 }
@@ -108,9 +108,9 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Project(const py::args &args, con
108108 vector<string> empty_aliases;
109109 if (groups.empty ()) {
110110 // No groups provided
111- return make_uniq<DuckDBPyRelation> (rel->Project (std::move (expressions), empty_aliases));
111+ return DeriveRelation (rel->Project (std::move (expressions), empty_aliases));
112112 }
113- return make_uniq<DuckDBPyRelation> (rel->Aggregate (std::move (expressions), groups));
113+ return DeriveRelation (rel->Aggregate (std::move (expressions), groups));
114114 }
115115}
116116
@@ -180,7 +180,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::EmptyResult(const shared_ptr<Clie
180180}
181181
182182unique_ptr<DuckDBPyRelation> DuckDBPyRelation::SetAlias (const string &expr) {
183- return make_uniq<DuckDBPyRelation> (rel->Alias (expr));
183+ return DeriveRelation (rel->Alias (expr));
184184}
185185
186186py::str DuckDBPyRelation::GetAlias () {
@@ -197,19 +197,19 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Filter(const py::object &expr) {
197197 throw InvalidInputException (" Please provide either a string or a DuckDBPyExpression object to 'filter'" );
198198 }
199199 auto expr_p = expression->GetExpression ().Copy ();
200- return make_uniq<DuckDBPyRelation> (rel->Filter (std::move (expr_p)));
200+ return DeriveRelation (rel->Filter (std::move (expr_p)));
201201}
202202
203203unique_ptr<DuckDBPyRelation> DuckDBPyRelation::FilterFromExpression (const string &expr) {
204- return make_uniq<DuckDBPyRelation> (rel->Filter (expr));
204+ return DeriveRelation (rel->Filter (expr));
205205}
206206
207207unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Limit (int64_t n, int64_t offset) {
208- return make_uniq<DuckDBPyRelation> (rel->Limit (n, offset));
208+ return DeriveRelation (rel->Limit (n, offset));
209209}
210210
211211unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Order (const string &expr) {
212- return make_uniq<DuckDBPyRelation> (rel->Order (expr));
212+ return DeriveRelation (rel->Order (expr));
213213}
214214
215215unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Sort (const py::args &args) {
@@ -228,7 +228,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Sort(const py::args &args) {
228228 if (order_nodes.empty ()) {
229229 throw InvalidInputException (" Please provide at least one expression to sort on" );
230230 }
231- return make_uniq<DuckDBPyRelation> (rel->Order (std::move (order_nodes)));
231+ return DeriveRelation (rel->Order (std::move (order_nodes)));
232232}
233233
234234vector<unique_ptr<ParsedExpression>> GetExpressions (ClientContext &context, const py::object &expr) {
@@ -259,9 +259,9 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Aggregate(const py::object &expr,
259259 AssertRelation ();
260260 auto expressions = GetExpressions (*rel->context ->GetContext (), expr);
261261 if (!groups.empty ()) {
262- return make_uniq<DuckDBPyRelation> (rel->Aggregate (std::move (expressions), groups));
262+ return DeriveRelation (rel->Aggregate (std::move (expressions), groups));
263263 }
264- return make_uniq<DuckDBPyRelation> (rel->Aggregate (std::move (expressions)));
264+ return DeriveRelation (rel->Aggregate (std::move (expressions)));
265265}
266266
267267void DuckDBPyRelation::AssertResult () const {
@@ -354,7 +354,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Describe() {
354354 DescribeAggregateInfo (" stddev" , true ), DescribeAggregateInfo (" min" ),
355355 DescribeAggregateInfo (" max" ), DescribeAggregateInfo (" median" , true )};
356356 auto expressions = CreateExpressionList (columns, aggregates);
357- return make_uniq<DuckDBPyRelation> (rel->Aggregate (expressions));
357+ return DeriveRelation (rel->Aggregate (expressions));
358358}
359359
360360string DuckDBPyRelation::ToSQL () {
@@ -456,7 +456,7 @@ DuckDBPyRelation::GenericWindowFunction(const string &function_name, const strin
456456 const string &projected_columns) {
457457 auto expr = GenerateExpressionList (function_name, aggr_columns, " " , function_parameters, ignore_nulls,
458458 projected_columns, window_spec);
459- return make_uniq<DuckDBPyRelation> (rel->Project (expr));
459+ return DeriveRelation (rel->Project (expr));
460460}
461461
462462unique_ptr<DuckDBPyRelation> DuckDBPyRelation::ApplyAggOrWin (const string &function_name, const string &agg_columns,
@@ -722,7 +722,7 @@ py::tuple DuckDBPyRelation::Shape() {
722722}
723723
724724unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Unique (const string &std_columns) {
725- return make_uniq<DuckDBPyRelation> (rel->Project (std_columns)->Distinct ());
725+ return DeriveRelation (rel->Project (std_columns)->Distinct ());
726726}
727727
728728/* General-purpose window functions */
@@ -796,7 +796,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::NthValue(const string &column, co
796796}
797797
798798unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Distinct () {
799- return make_uniq<DuckDBPyRelation> (rel->Distinct ());
799+ return DeriveRelation (rel->Distinct ());
800800}
801801
802802duckdb::pyarrow::RecordBatchReader DuckDBPyRelation::FetchRecordBatchReader (idx_t rows_per_batch) {
@@ -1064,6 +1064,22 @@ bool DuckDBPyRelation::ContainsColumnByName(const string &name) const {
10641064 [&](const string &item) { return StringUtil::CIEquals (name, item); }) != names.end ();
10651065}
10661066
1067+ void DuckDBPyRelation::SetConnectionOwner (py::object owner) {
1068+ connection_owner = std::move (owner);
1069+ }
1070+
1071+ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::DeriveRelation (shared_ptr<Relation> new_rel) {
1072+ auto result = make_uniq<DuckDBPyRelation>(std::move (new_rel));
1073+ result->connection_owner = connection_owner;
1074+ return result;
1075+ }
1076+
1077+ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::DeriveRelation (shared_ptr<DuckDBPyResult> result_p) {
1078+ auto result = make_uniq<DuckDBPyRelation>(std::move (result_p));
1079+ result->connection_owner = connection_owner;
1080+ return result;
1081+ }
1082+
10671083static bool ContainsStructFieldByName (LogicalType &type, const string &name) {
10681084 if (type.id () != LogicalTypeId::STRUCT) {
10691085 return false ;
@@ -1104,19 +1120,19 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::GetAttribute(const string &name)
11041120 expressions.push_back (std::move (make_uniq<ColumnRefExpression>(column_names)));
11051121 vector<string> aliases;
11061122 aliases.push_back (name);
1107- return make_uniq<DuckDBPyRelation> (rel->Project (std::move (expressions), aliases));
1123+ return DeriveRelation (rel->Project (std::move (expressions), aliases));
11081124}
11091125
11101126unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Union (DuckDBPyRelation *other) {
1111- return make_uniq<DuckDBPyRelation> (rel->Union (other->rel ));
1127+ return DeriveRelation (rel->Union (other->rel ));
11121128}
11131129
11141130unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Except (DuckDBPyRelation *other) {
1115- return make_uniq<DuckDBPyRelation> (rel->Except (other->rel ));
1131+ return DeriveRelation (rel->Except (other->rel ));
11161132}
11171133
11181134unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Intersect (DuckDBPyRelation *other) {
1119- return make_uniq<DuckDBPyRelation> (rel->Intersect (other->rel ));
1135+ return DeriveRelation (rel->Intersect (other->rel ));
11201136}
11211137
11221138namespace {
@@ -1177,7 +1193,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Join(DuckDBPyRelation *other, con
11771193 }
11781194 if (py::isinstance<py::str>(condition)) {
11791195 auto condition_string = std::string (py::cast<py::str>(condition));
1180- return make_uniq<DuckDBPyRelation> (rel->Join (other->rel , condition_string, join_type));
1196+ return DeriveRelation (rel->Join (other->rel , condition_string, join_type));
11811197 }
11821198 vector<string> using_list;
11831199 if (py::is_list_like (condition)) {
@@ -1193,7 +1209,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Join(DuckDBPyRelation *other, con
11931209 throw InvalidInputException (" Please provide at least one string in the condition to create a USING clause" );
11941210 }
11951211 auto join_relation = make_shared_ptr<JoinRelation>(rel, other->rel , std::move (using_list), join_type);
1196- return make_uniq<DuckDBPyRelation> (std::move (join_relation));
1212+ return DeriveRelation (std::move (join_relation));
11971213 }
11981214 shared_ptr<DuckDBPyExpression> condition_expr;
11991215 if (!py::try_cast (condition, condition_expr)) {
@@ -1202,11 +1218,11 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Join(DuckDBPyRelation *other, con
12021218 }
12031219 vector<unique_ptr<ParsedExpression>> conditions;
12041220 conditions.push_back (condition_expr->GetExpression ().Copy ());
1205- return make_uniq<DuckDBPyRelation> (rel->Join (other->rel , std::move (conditions), join_type));
1221+ return DeriveRelation (rel->Join (other->rel , std::move (conditions), join_type));
12061222}
12071223
12081224unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Cross (DuckDBPyRelation *other) {
1209- return make_uniq<DuckDBPyRelation> (rel->CrossProduct (other->rel ));
1225+ return DeriveRelation (rel->CrossProduct (other->rel ));
12101226}
12111227
12121228static Value NestedDictToStruct (const py::object &dictionary) {
@@ -1502,7 +1518,7 @@ void DuckDBPyRelation::ToCSV(const string &filename, const py::object &sep, cons
15021518// should this return a rel with the new view?
15031519unique_ptr<DuckDBPyRelation> DuckDBPyRelation::CreateView (const string &view_name, bool replace) {
15041520 rel->CreateView (view_name, replace);
1505- return make_uniq<DuckDBPyRelation> (rel);
1521+ return DeriveRelation (rel);
15061522}
15071523
15081524static bool IsDescribeStatement (SQLStatement &statement) {
@@ -1530,7 +1546,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Query(const string &view_name, co
15301546 auto select_statement = unique_ptr_cast<SQLStatement, SelectStatement>(std::move (parser.statements [0 ]));
15311547 auto query_relation = make_shared_ptr<QueryRelation>(rel->context ->GetContext (), std::move (select_statement),
15321548 sql_query, " query_relation" );
1533- return make_uniq<DuckDBPyRelation> (std::move (query_relation));
1549+ return DeriveRelation (std::move (query_relation));
15341550 } else if (IsDescribeStatement (statement)) {
15351551 auto query = PragmaShow (view_name);
15361552 return Query (view_name, query);
@@ -1630,7 +1646,7 @@ unique_ptr<DuckDBPyRelation> DuckDBPyRelation::Map(py::function fun, Optional<py
16301646 vector<Value> params;
16311647 params.emplace_back (Value::POINTER (CastPointerToValue (fun.ptr ())));
16321648 params.emplace_back (Value::POINTER (CastPointerToValue (schema.ptr ())));
1633- auto relation = make_uniq<DuckDBPyRelation> (rel->TableFunction (" python_map_function" , params));
1649+ auto relation = DeriveRelation (rel->TableFunction (" python_map_function" , params));
16341650 auto rel_dependency = make_uniq<ExternalDependency>();
16351651 rel_dependency->AddDependency (" map" , PythonDependencyItem::Create (std::move (fun)));
16361652 rel_dependency->AddDependency (" schema" , PythonDependencyItem::Create (std::move (schema)));
0 commit comments