@@ -1506,7 +1506,8 @@ namespace sqlite_orm {
1506
1506
constexpr bool hasExplicitFrom = tuple_has<is_from, conditions_tuple>::value;
1507
1507
if (!hasExplicitFrom) {
1508
1508
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
1510
1511
iterate_tuple (sel.conditions , joins_index_sequence{}, [&tableNames, &context](auto & join) {
1511
1512
using original_join_type = typename std::decay_t <decltype (join)>::type;
1512
1513
using cross_join_type = mapped_type_proxy_t <original_join_type>;
@@ -1828,30 +1829,33 @@ namespace sqlite_orm {
1828
1829
}
1829
1830
};
1830
1831
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;
1834
1838
1835
1839
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 {
1837
1841
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 ));
1840
1844
return ss.str ();
1841
1845
}
1842
1846
};
1843
1847
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 ;
1847
1851
1848
1852
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 {
1850
1854
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);
1855
1859
return ss.str ();
1856
1860
}
1857
1861
};
@@ -1861,69 +1865,11 @@ namespace sqlite_orm {
1861
1865
using statement_type = on_t <T>;
1862
1866
1863
1867
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 {
1865
1869
std::stringstream ss;
1866
1870
auto newContext = context;
1867
1871
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) << " " ;
1927
1873
return ss.str ();
1928
1874
}
1929
1875
};
0 commit comments