Skip to content

Commit e364960

Browse files
authored
Merge pull request #1153 from FireDaemon/test_join_serialization
Tests for constrained join clauses with regard to table collection
2 parents ffd2bd8 + 4adda95 commit e364960

File tree

5 files changed

+103
-226
lines changed

5 files changed

+103
-226
lines changed

dev/ast_iterator.h

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -497,13 +497,13 @@ namespace sqlite_orm {
497497
}
498498
};
499499

500-
template<class T, class O>
501-
struct ast_iterator<left_join_t<T, O>, void> {
502-
using node_type = left_join_t<T, O>;
500+
template<class Join>
501+
struct ast_iterator<Join, match_if<is_constrained_join, Join>> {
502+
using node_type = Join;
503503

504504
template<class L>
505-
void operator()(const node_type& j, L& lambda) const {
506-
iterate_ast(j.constraint, lambda);
505+
void operator()(const node_type& join, L& lambda) const {
506+
iterate_ast(join.constraint, lambda);
507507
}
508508
};
509509

@@ -512,8 +512,8 @@ namespace sqlite_orm {
512512
using node_type = on_t<T>;
513513

514514
template<class L>
515-
void operator()(const node_type& o, L& lambda) const {
516-
iterate_ast(o.arg, lambda);
515+
void operator()(const node_type& on, L& lambda) const {
516+
iterate_ast(on.arg, lambda);
517517
}
518518
};
519519

@@ -529,36 +529,6 @@ namespace sqlite_orm {
529529
}
530530
};
531531

532-
template<class T, class O>
533-
struct ast_iterator<join_t<T, O>, void> {
534-
using node_type = join_t<T, O>;
535-
536-
template<class L>
537-
void operator()(const node_type& j, L& lambda) const {
538-
iterate_ast(j.constraint, lambda);
539-
}
540-
};
541-
542-
template<class T, class O>
543-
struct ast_iterator<left_outer_join_t<T, O>, void> {
544-
using node_type = left_outer_join_t<T, O>;
545-
546-
template<class L>
547-
void operator()(const node_type& j, L& lambda) const {
548-
iterate_ast(j.constraint, lambda);
549-
}
550-
};
551-
552-
template<class T, class O>
553-
struct ast_iterator<inner_join_t<T, O>, void> {
554-
using node_type = inner_join_t<T, O>;
555-
556-
template<class L>
557-
void operator()(const node_type& j, L& lambda) const {
558-
iterate_ast(j.constraint, lambda);
559-
}
560-
};
561-
562532
template<class R, class T, class E, class... Args>
563533
struct ast_iterator<simple_case_t<R, T, E, Args...>, void> {
564534
using node_type = simple_case_t<R, T, E, Args...>;

dev/conditions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ namespace sqlite_orm {
813813
using is_from = polyfill::is_specialization_of<T, from_t>;
814814

815815
template<class T>
816-
using is_any_join = polyfill::is_detected<on_type_t, T>;
816+
using is_constrained_join = polyfill::is_detected<on_type_t, T>;
817817
}
818818

819819
/**

dev/statement_serializer.h

Lines changed: 21 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,7 +1506,8 @@ namespace sqlite_orm {
15061506
constexpr bool hasExplicitFrom = tuple_has<is_from, conditions_tuple>::value;
15071507
if(!hasExplicitFrom) {
15081508
auto tableNames = collect_table_names(sel, context);
1509-
using joins_index_sequence = filter_tuple_sequence_t<conditions_tuple, is_any_join>;
1509+
using joins_index_sequence = filter_tuple_sequence_t<conditions_tuple, is_constrained_join>;
1510+
// deduplicate table names of constrained join statements
15101511
iterate_tuple(sel.conditions, joins_index_sequence{}, [&tableNames, &context](auto& join) {
15111512
using original_join_type = typename std::decay_t<decltype(join)>::type;
15121513
using cross_join_type = mapped_type_proxy_t<original_join_type>;
@@ -1828,30 +1829,33 @@ namespace sqlite_orm {
18281829
}
18291830
};
18301831

1831-
template<class O>
1832-
struct statement_serializer<cross_join_t<O>, void> {
1833-
using statement_type = cross_join_t<O>;
1832+
template<class Join>
1833+
struct statement_serializer<
1834+
Join,
1835+
std::enable_if_t<polyfill::disjunction_v<polyfill::is_specialization_of<Join, cross_join_t>,
1836+
polyfill::is_specialization_of<Join, natural_join_t>>>> {
1837+
using statement_type = Join;
18341838

18351839
template<class Ctx>
1836-
std::string operator()(const statement_type& c, const Ctx& context) const {
1840+
std::string operator()(const statement_type& join, const Ctx& context) const {
18371841
std::stringstream ss;
1838-
ss << static_cast<std::string>(c) << " "
1839-
<< streaming_identifier(lookup_table_name<O>(context.db_objects));
1842+
ss << static_cast<std::string>(join) << " "
1843+
<< streaming_identifier(lookup_table_name<type_t<Join>>(context.db_objects));
18401844
return ss.str();
18411845
}
18421846
};
18431847

1844-
template<class T, class O>
1845-
struct statement_serializer<inner_join_t<T, O>, void> {
1846-
using statement_type = inner_join_t<T, O>;
1848+
template<class Join>
1849+
struct statement_serializer<Join, match_if<is_constrained_join, Join>> {
1850+
using statement_type = Join;
18471851

18481852
template<class Ctx>
1849-
std::string operator()(const statement_type& l, const Ctx& context) const {
1853+
std::string operator()(const statement_type& join, const Ctx& context) const {
18501854
std::stringstream ss;
1851-
ss << static_cast<std::string>(l) << " "
1852-
<< streaming_identifier(lookup_table_name<mapped_type_proxy_t<T>>(context.db_objects),
1853-
alias_extractor<T>::as_alias())
1854-
<< serialize(l.constraint, context);
1855+
ss << static_cast<std::string>(join) << " "
1856+
<< streaming_identifier(lookup_table_name<mapped_type_proxy_t<type_t<Join>>>(context.db_objects),
1857+
alias_extractor<type_t<Join>>::as_alias())
1858+
<< " " << serialize(join.constraint, context);
18551859
return ss.str();
18561860
}
18571861
};
@@ -1861,69 +1865,11 @@ namespace sqlite_orm {
18611865
using statement_type = on_t<T>;
18621866

18631867
template<class Ctx>
1864-
std::string operator()(const statement_type& t, const Ctx& context) const {
1868+
std::string operator()(const statement_type& on, const Ctx& context) const {
18651869
std::stringstream ss;
18661870
auto newContext = context;
18671871
newContext.skip_table_name = false;
1868-
ss << static_cast<std::string>(t) << " " << serialize(t.arg, newContext) << " ";
1869-
return ss.str();
1870-
}
1871-
};
1872-
1873-
template<class T, class O>
1874-
struct statement_serializer<join_t<T, O>, void> {
1875-
using statement_type = join_t<T, O>;
1876-
1877-
template<class Ctx>
1878-
std::string operator()(const statement_type& l, const Ctx& context) const {
1879-
std::stringstream ss;
1880-
ss << static_cast<std::string>(l) << " "
1881-
<< streaming_identifier(lookup_table_name<mapped_type_proxy_t<T>>(context.db_objects),
1882-
alias_extractor<T>::as_alias())
1883-
<< " " << serialize(l.constraint, context);
1884-
return ss.str();
1885-
}
1886-
};
1887-
1888-
template<class T, class O>
1889-
struct statement_serializer<left_join_t<T, O>, void> {
1890-
using statement_type = left_join_t<T, O>;
1891-
1892-
template<class Ctx>
1893-
std::string operator()(const statement_type& l, const Ctx& context) const {
1894-
std::stringstream ss;
1895-
ss << static_cast<std::string>(l) << " "
1896-
<< streaming_identifier(lookup_table_name<mapped_type_proxy_t<T>>(context.db_objects),
1897-
alias_extractor<T>::as_alias())
1898-
<< " " << serialize(l.constraint, context);
1899-
return ss.str();
1900-
}
1901-
};
1902-
1903-
template<class T, class O>
1904-
struct statement_serializer<left_outer_join_t<T, O>, void> {
1905-
using statement_type = left_outer_join_t<T, O>;
1906-
1907-
template<class Ctx>
1908-
std::string operator()(const statement_type& l, const Ctx& context) const {
1909-
std::stringstream ss;
1910-
ss << static_cast<std::string>(l) << " "
1911-
<< streaming_identifier(lookup_table_name<mapped_type_proxy_t<T>>(context.db_objects),
1912-
alias_extractor<T>::as_alias())
1913-
<< " " << serialize(l.constraint, context);
1914-
return ss.str();
1915-
}
1916-
};
1917-
1918-
template<class O>
1919-
struct statement_serializer<natural_join_t<O>, void> {
1920-
using statement_type = natural_join_t<O>;
1921-
1922-
template<class Ctx>
1923-
std::string operator()(const statement_type& c, const Ctx& context) const {
1924-
std::stringstream ss;
1925-
ss << static_cast<std::string>(c) << " "
1926-
<< streaming_identifier(lookup_table_name<O>(context.db_objects));
1872+
ss << static_cast<std::string>(on) << " " << serialize(on.arg, newContext) << " ";
19271873
return ss.str();
19281874
}
19291875
};

0 commit comments

Comments
 (0)