Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Common Table Expressions #1124

Merged
merged 208 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
208 commits
Select commit Hold shift + click to select a range
dde241e
A first implementation of common table expressions
trueqbit Jan 7, 2022
f8abfdb
Prepared for multiple CTEs
trueqbit Jan 8, 2022
454a821
Multiple CTEs
trueqbit Jan 8, 2022
0a9624c
Included util.h in storage.h
trueqbit Jan 8, 2022
5c3d3aa
ad hoc storage implementation for expression
trueqbit Jan 8, 2022
0ef34ff
Improve readability
trueqbit Jan 9, 2022
31e204f
Curated storage implementation interface
trueqbit Jan 12, 2022
3546af3
Explicit column names for CTE
trueqbit Jan 13, 2022
8fb53cd
Cleanup code while programming CTEs
trueqbit Jan 14, 2022
21f976a
Allow compound statements for recursive CTEs
trueqbit Jan 14, 2022
df34bb5
Complex recursive CTEs
trueqbit Jan 14, 2022
3b8473f
Ability to order by nth column
trueqbit Jan 15, 2022
805b2c9
Provided dump function for expressions
trueqbit Jan 15, 2022
908dab4
Added cte.h to amalgamation script
trueqbit Jan 15, 2022
e4092bf
Added a few with-clause examples
trueqbit Jan 15, 2022
85d92e1
Ability to select all columns from aliased table
trueqbit Jan 16, 2022
eb7971e
Removed 'get table' accessor from storage implementation
trueqbit Jan 16, 2022
518677e
Validate number of columns of CTE
trueqbit Jan 16, 2022
09703ec
Implemented simple multi-argument min/max core functions
trueqbit Jan 16, 2022
5beffa1
Most CTE examples are available only with std::optional
trueqbit Jan 16, 2022
024f427
"Apfelmaennchen" (Mandelbrot set) example
trueqbit Jan 16, 2022
c5aa19f
#include <optional> in CTE examples file
trueqbit Jan 16, 2022
d8fd046
Abstracted table object mapping
trueqbit Jan 17, 2022
c6b461f
Renamed `label_type` typename alias to `cte_label_type`
trueqbit Jan 17, 2022
ff086f6
Renamed common_table_expression::expression -> subselect
trueqbit Jan 17, 2022
532c430
Ability to build storage columns by integral member pointer constant
trueqbit Jan 18, 2022
749ce47
Implemented getting column expression from aliased asterisk expression
trueqbit Jan 18, 2022
c772d09
Static unit tests for column expression types
trueqbit Jan 18, 2022
7582330
Added explicit as() call CTE builder
trueqbit Jan 18, 2022
1ec9350
Provided `polyfill::remove_cvref` for C++17
trueqbit Jan 18, 2022
8f8e991
Moved `column_expression_of_t` machinery to its own respective header…
trueqbit Jan 18, 2022
7d94059
Corrected column expression for reference wrapper
trueqbit Jan 18, 2022
5e46868
Added static unit tests for 'column pointer'
trueqbit Jan 18, 2022
dced338
Updated sqlite_orm.h
trueqbit Jan 18, 2022
fe5ba65
Simplified and described storage lookup methods
trueqbit Jan 19, 2022
917c34b
Addressed compiler errors found with clang (LLVM 12)
trueqbit Jan 20, 2022
45018e1
Addressed issues while compiling all examples and unit tests
trueqbit Jan 22, 2022
13807c7
Removed unused system_error variable in unit tests
trueqbit Jan 22, 2022
4030227
`tuplify` metafunction must do what it is supposed to do
trueqbit Jan 23, 2022
757c9a9
Ability to refer back to a CTE column via column alias
trueqbit Jan 26, 2022
357cf3f
Runner-up: Ability to refer back to a CTE column via column alias
trueqbit Jan 28, 2022
f600ca9
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Mar 13, 2022
5a33340
Restored parentheses around VALUES expression
trueqbit Mar 13, 2022
83d7fe4
make_error_code can now be called unqualified
trueqbit Mar 15, 2022
b28bfe1
Updated unit tests in regard to expected serialized statements
trueqbit Mar 15, 2022
8c92323
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Mar 15, 2022
8f74a98
Merged upstream/dev into CTEs
trueqbit Mar 28, 2022
1f9a132
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 2, 2022
16a100e
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 4, 2022
c3f72ed
Updated code after merge
trueqbit Apr 4, 2022
9581d8f
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 5, 2022
1b9e53c
Replaced `constexpr const` variable declarations
trueqbit Apr 7, 2022
015027f
Renamed `alias_exctractor::get()` -> `alias_exctractor::extract()`
trueqbit Apr 7, 2022
8fdce3a
Properly unquote collected CTE column names
trueqbit Apr 7, 2022
57e4bb3
Reused sqlite_orm's alias concept for CTE tables
trueqbit Apr 7, 2022
97c9bdf
Updated CTE examples, using new column pointer syntax abilities
trueqbit Apr 7, 2022
3490ca0
Updated sqlite_orm.h
trueqbit Apr 7, 2022
089ea5a
Simplifications, fully leveraging alias mechanism for CTEs
trueqbit Apr 11, 2022
78ae741
Fully implemented explicit CTE columns
trueqbit Apr 13, 2022
0a891da
Runner-up: Fully implemented explicit CTE columns
trueqbit Apr 14, 2022
93ecf55
Unit tests for explicit CTE column references
trueqbit Apr 14, 2022
a9e1390
Confined using numeric column aliases within a single CTE
trueqbit Apr 14, 2022
865611d
Same wording for "C++nm or later"
trueqbit Apr 14, 2022
059be69
Updated sqlite_orm.h
trueqbit Apr 14, 2022
2414ea7
Updated apfelmaennchen C++20 select statement
trueqbit Apr 14, 2022
7271bcb
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 17, 2022
5e62621
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 20, 2022
5cfa693
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 21, 2022
14400e9
Capture support for class types as non-type template parameters in macro
trueqbit Apr 21, 2022
f7de21e
Used 'support' macro for C++20 non-type template parameter features
trueqbit Apr 21, 2022
08cadb2
Added 'node tuple' and 'ast iterator' unit tests for CTEs
trueqbit Apr 21, 2022
42b138f
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 22, 2022
e76c2d1
Made CTE column references work with getters
trueqbit Apr 22, 2022
ddfc2db
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 23, 2022
32bf564
Fixed getting table_type's object
trueqbit Apr 24, 2022
c7e58ed
Added example selecting columns from a subquery, using an explicit CTE
trueqbit Apr 24, 2022
ab3b0a1
Use feature detection macros for polyfills
trueqbit Apr 24, 2022
f69701e
Context-sensitive alias extraction
trueqbit Apr 24, 2022
ca18031
Added unit tests for alias extraction
trueqbit Apr 25, 2022
f918940
Merge remote-tracking branch 'refs/remotes/upstream/dev'
trueqbit Jan 3, 2023
fa15bae
Corrected CTE column referencing backend code
trueqbit Jan 4, 2023
0291bbf
Removed ability to reference columns by index
trueqbit Jan 4, 2023
4449515
Simplified string identifier template
trueqbit Jan 4, 2023
3ca30b4
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Jan 5, 2023
ac94ea4
Cleanup CTE code
trueqbit Jan 5, 2023
2da31e0
CTE available from C++17 and later
trueqbit Jan 5, 2023
cd35ef4
Fixed compilation error on clang
trueqbit Jan 5, 2023
cc7e6be
Cleaned up remnants of pre-1.8 merge
trueqbit Jan 5, 2023
dfd0e0d
Optimized copying explicit CTE column string
trueqbit Jan 5, 2023
c70f111
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Jan 22, 2023
8ffdcbc
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Jan 26, 2023
98738a8
Made column aliases first-class citizens
trueqbit Jan 27, 2023
c6af050
Correct shadowed template parameter
trueqbit Jan 27, 2023
a2fddcb
Ability to daisy-chain the concatenation operator
trueqbit Jan 27, 2023
304fee3
EXISTS must use parentheses
trueqbit Jan 27, 2023
881115b
Aliasing of CTE aliases
trueqbit Jan 27, 2023
a6c6b46
Sudoku as another outlandish CTE query example
trueqbit Jan 27, 2023
4d7b911
Runner-up: Ability to daisy-chain the concatenation operator
trueqbit Jan 28, 2023
852e572
Trying to fix compiler errors with clang
trueqbit Jan 28, 2023
b756bd4
Merge branch 'dev' into CTEs
trueqbit Jan 28, 2023
f65156e
Corrected availability of `is_cte_alias_v`
trueqbit Jan 28, 2023
46cf220
Aliased columns mapped into a CTE
trueqbit Jan 30, 2023
00d159b
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Jan 30, 2023
8c4a198
Addressed a few CTE+clang related things
trueqbit Jan 30, 2023
026d37c
Removed code used in local test environment
trueqbit Jan 30, 2023
26b323a
Included <algorithm> in tuple_traits.h
trueqbit Jan 30, 2023
3d349d4
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Feb 1, 2023
8de0b38
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Feb 2, 2023
99ad4f3
Qualified remaining calls to `std::move()`
trueqbit Feb 2, 2023
3d2f3a3
Removed code used in local test environment
trueqbit Feb 2, 2023
2c69e87
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Feb 3, 2023
9404d5d
Made CTE select work with a `columns_t` expression having only 1 column
trueqbit Feb 7, 2023
c53d72b
Fixed collecting CTE column names from column aliases
trueqbit Feb 7, 2023
89c2882
Updated example using the newer `group_by().having()` expression
trueqbit Feb 7, 2023
22705d3
User retention calculation example using CTEs
trueqbit Feb 7, 2023
dcf07ea
Trying multi-processor compilation for appveyor builds
trueqbit Feb 7, 2023
8ff7f20
Fixed missing `column_expression_of_t`
trueqbit Feb 7, 2023
ecdd32a
Trying multi-processor compilation for appveyor builds except for gcc
trueqbit Feb 7, 2023
3beab49
Merge branch 'dev' into CTEs
trueqbit Feb 8, 2023
b33fe3c
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Feb 10, 2023
b8f9862
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Feb 14, 2023
74f8e64
'greatest n per group' using a self-join
trueqbit Feb 14, 2023
84cb56c
Simplified a few internal CTE-related things
trueqbit Feb 17, 2023
70dc5ac
Merge branch 'aliasing_1st' into CTEs
trueqbit Feb 18, 2023
94b1fc6
Updated sqlite_orm.h
trueqbit Feb 18, 2023
209c196
Fixed a few things detected with clang
trueqbit Feb 18, 2023
f3d9ff9
Must not guard `#include`s subject to amalgamation
trueqbit Feb 18, 2023
14d9125
Merge branch 'aliasing_1st' into CTEs
trueqbit Feb 25, 2023
5b1d723
Removed artificial constraint on single-character CTE aliases
trueqbit Feb 25, 2023
ef444ec
Removed '_col' suffix from columns in CTE examples
trueqbit Feb 25, 2023
dc7a118
Removed superfluous fold expression preprocessor guard
trueqbit Feb 25, 2023
89466cd
appveryor: Updated build worker image name for clang C++20
trueqbit Feb 25, 2023
b520578
Replaced SFINAE on `cte<>()` with concepts
trueqbit Feb 25, 2023
6bf1bdb
Renamed 'CTE label' and 'CTE alias' to 'CTE moniker'
trueqbit Feb 25, 2023
83783c9
Simplified storage lookup
trueqbit Feb 25, 2023
aefc77e
Fixed making CTE 'storage'
trueqbit Feb 25, 2023
b2c528e
Used `is_compound_operator` in more places
trueqbit Feb 26, 2023
112d712
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Feb 28, 2023
09d6d3a
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Mar 14, 2023
1014cc9
Improved performance of `index_sequence_value()`
trueqbit Mar 20, 2023
6cb05c5
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Mar 26, 2023
d74bee2
Updated EOL sequence in CTE header files to LF
trueqbit Mar 26, 2023
0c699f3
Removed comment in index_sequence_util.h
trueqbit Mar 26, 2023
c08a16a
Guarded availability of `operator->*` for CTE monikers
trueqbit Mar 26, 2023
11df357
Fix warning in json1 unit test
trueqbit Mar 27, 2023
d712608
Fixed C++17 compiler error in `index_sequence_value()`
trueqbit Mar 27, 2023
205f533
Turned `column<>` function object into function again
trueqbit Mar 27, 2023
0f2f78a
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 27, 2023
a833b4a
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Jul 24, 2023
8fda24c
Column pointers and overloading operators
trueqbit Oct 5, 2023
dbe1784
Overhauled operator overloading
trueqbit Oct 7, 2023
4bc87f6
Added schema subfolder
trueqbit Oct 8, 2023
4cb7237
Updated clang-format lint action to v0.16.2
trueqbit Oct 8, 2023
ed1d446
Small improvements to CTE examples
trueqbit Oct 8, 2023
ffcfc30
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Oct 9, 2023
bb95d10
Removed global numbered CTE moniker types
trueqbit Oct 9, 2023
2d3c8fc
Convenience function for constructing a CTE by directly using a moniker
trueqbit Oct 9, 2023
5e14f8c
Merge remote-tracking branch 'refs/remotes/upstream/dev'
trueqbit Oct 9, 2023
8bfbca0
Corrected test file ast_iterator_tests.cpp
trueqbit Oct 9, 2023
ff0f66a
Renamed cte.h -> cte_moniker.h
trueqbit Oct 10, 2023
5ffcc6a
Fixed unit test for "aliased CTE column alias"
trueqbit Oct 10, 2023
9190088
Fixed unit test for aliased CTE column
trueqbit Oct 10, 2023
ade3190
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Oct 13, 2023
c477ac9
Create a CTE using `as()`
trueqbit Oct 14, 2023
96043a1
Serialized `WITH` keyword differently
trueqbit Oct 14, 2023
ee5aba1
Provided optional `WITH RECURSIVE`
trueqbit Oct 14, 2023
5d2a8d8
Simplified a few node expressions involving comparisons with aliases
trueqbit Oct 14, 2023
843f667
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Oct 14, 2023
e8bfdb4
Unit tests for with select from CTE directly from storage object
trueqbit Oct 14, 2023
135733b
Guarded storage tests for CTEs
trueqbit Oct 14, 2023
c928cf4
First implementation of CTEs with materialization hints
trueqbit Oct 15, 2023
4fedb37
Improved CTE example fetching a hierarchy
trueqbit Oct 19, 2023
f1b2e36
Allow "compound" statements in with-clause
trueqbit Oct 19, 2023
f484fca
Count asterisk from CTE using C++20 aliases
trueqbit Oct 19, 2023
28d99bf
Corrected unit tests for aggregate functions
trueqbit Oct 20, 2023
f9eb74e
Clarified comment on `alias_extractor` a bit
trueqbit Oct 20, 2023
ab013e6
Relaxed forming a column reference to an aliased table column pointer
trueqbit Oct 22, 2023
d77fa59
Operators for column references to aliased table columns
trueqbit Oct 22, 2023
c370dca
Merge remote-tracking branch 'origin/alias_column_operators' into CTEs
trueqbit Oct 22, 2023
2bbf149
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Oct 22, 2023
60954f2
Merge branch 'multi-compound' into CTEs
trueqbit Oct 24, 2023
e3d9cc2
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Nov 9, 2023
b1c9dfc
A few more CTE unit tests
trueqbit Nov 10, 2023
baf801e
Properly guarded CTE alias column operator under C++20 aliases
trueqbit Nov 10, 2023
f4745e6
Guarded CTE column operator under C++20 aliases
trueqbit Nov 10, 2023
b7213ab
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Nov 10, 2023
f6e1c97
Corrected unit tests for table name collector
trueqbit Nov 11, 2023
6b0613d
Uniform syntax for column pointer expressions through table references
trueqbit Nov 12, 2023
57b5097
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Nov 12, 2023
348a803
Further unit tests for CTE expressions
trueqbit Nov 12, 2023
3a9665b
Table reference can be specified in call to `make_table()`
trueqbit Nov 12, 2023
4d68adf
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Nov 26, 2023
3c914e5
CTE with raw insert statements
trueqbit Nov 26, 2023
6b406c5
Merge remote-tracking branch 'origin/fixes/operators_adl' into CTEs
trueqbit Dec 19, 2023
fe696b6
Moved CTE string literal operators into inline namespace
trueqbit Dec 19, 2023
31c6d30
Merge remote-tracking branch 'origin/fixes/operators_adl' into CTEs
trueqbit Dec 21, 2023
508d0d7
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Dec 21, 2023
b2c77f2
Rephrased comment
trueqbit Dec 21, 2023
5ef6d4e
Merge remote-tracking branch 'origin/simplified_expression_object_typ…
trueqbit Dec 25, 2023
fcf85d6
Streamlined tuple traits and algorithms
trueqbit Dec 28, 2023
8e67751
Merge branch 'streamlined_tuple_algos' into CTEs
trueqbit Jan 5, 2024
60eb1a8
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Jan 5, 2024
32fef04
Applied changes requested in PR review
trueqbit Apr 4, 2024
4997b7d
Use of a string_view for serialization in several places
trueqbit Apr 4, 2024
21a1a63
Used standardized time types
trueqbit Apr 4, 2024
18b27ac
appveyor: Updated vcpkg environment to 2024.03.25
trueqbit Apr 4, 2024
4f4155a
Silenced warning 'expression result unused'
trueqbit Apr 4, 2024
312aef2
Merge remote-tracking branch 'upstream/dev' into CTEs
trueqbit Apr 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ for:
install:
- |-
cd C:\Tools\vcpkg
git fetch --tags && git checkout 2024.01.12
git fetch --tags && git checkout 2024.03.25
cd %APPVEYOR_BUILD_FOLDER%
C:\Tools\vcpkg\bootstrap-vcpkg.bat -disableMetrics
C:\Tools\vcpkg\vcpkg integrate install
Expand Down Expand Up @@ -140,7 +140,7 @@ for:
install:
- |-
pushd $HOME/vcpkg
git fetch --tags && git checkout 2024.01.12
git fetch --tags && git checkout 2024.03.25
popd
$HOME/vcpkg/bootstrap-vcpkg.sh -disableMetrics
$HOME/vcpkg/vcpkg integrate install --overlay-triplets=vcpkg/triplets
Expand Down Expand Up @@ -168,7 +168,7 @@ for:
# using custom vcpkg triplets for building and linking dynamic dependent libraries
install:
- |-
git clone --depth 1 --branch 2024.01.12 https://github.com/microsoft/vcpkg.git $HOME/vcpkg
git clone --depth 1 --branch 2024.03.25 https://github.com/microsoft/vcpkg.git $HOME/vcpkg
$HOME/vcpkg/bootstrap-vcpkg.sh -disableMetrics
$HOME/vcpkg/vcpkg integrate install --overlay-triplets=vcpkg/triplets
vcpkg install sqlite3[core,dbstat,math,json1,fts5,soundex] catch2 --overlay-triplets=vcpkg/triplets
Expand Down
138 changes: 131 additions & 7 deletions dev/alias.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
#include <utility> // std::make_index_sequence, std::move
#include <string> // std::string
#include <sstream> // std::stringstream
#ifdef SQLITE_ORM_WITH_CTE
#include <array>
#endif

#include "functional/cxx_type_traits_polyfill.h"
#include "functional/cstring_literal.h"
#include "type_traits.h"
#include "alias_traits.h"
#include "table_type_of.h"
#include "tags.h"
#include "column_pointer.h"

namespace sqlite_orm {

Expand Down Expand Up @@ -78,8 +82,8 @@ namespace sqlite_orm {
/*
* Encapsulates extracting the alias identifier of an alias.
*
* `extract()` always returns the alias identifier.
* `as_alias()` is used in contexts where a table is aliased, and the alias identifier is returned.
* `extract()` always returns the alias identifier or CTE moniker.
* `as_alias()` is used in contexts where a recordset is aliased, and the alias identifier is returned.
* `as_qualifier()` is used in contexts where a table is aliased, and the alias identifier is returned.
*/
template<class A>
Expand All @@ -96,6 +100,14 @@ namespace sqlite_orm {
return alias_extractor::extract();
}

#ifdef SQLITE_ORM_WITH_CTE
// for CTE monikers -> empty
template<class T = A, satisfies<std::is_same, polyfill::detected_t<type_t, T>, A> = true>
static std::string as_alias() {
return {};
}
#endif

// for regular table aliases -> alias identifier
template<class T = A, satisfies<is_table_alias, T> = true>
static std::string as_qualifier(const basic_table&) {
Expand Down Expand Up @@ -131,6 +143,8 @@ namespace sqlite_orm {
using type = T;

alias_holder() = default;
// CTE feature needs it to implicitly convert a column alias to an alias_holder; see `cte()` factory function
alias_holder(const T&) noexcept {}
};

template<class T>
Expand All @@ -144,8 +158,31 @@ namespace sqlite_orm {
[[nodiscard]] consteval recordset_alias<T, A, X...> for_() const {
return {};
}

template<auto t>
[[nodiscard]] consteval auto for_() const {
using T = std::remove_const_t<decltype(t)>;
return recordset_alias<T, A, X...>{};
}
};
#endif

#ifdef SQLITE_ORM_WITH_CTE
template<size_t n, char... C>
SQLITE_ORM_CONSTEVAL auto n_to_colalias() {
constexpr column_alias<'1' + n % 10, C...> colalias{};
if constexpr(n > 10) {
return n_to_colalias<n / 10, '1' + n % 10, C...>();
} else {
return colalias;
}
}

template<class T>
inline constexpr bool is_builtin_numeric_column_alias_v = false;
template<char... C>
inline constexpr bool is_builtin_numeric_column_alias_v<column_alias<C...>> = ((C >= '0' && C <= '9') && ...);
#endif
}

/**
Expand All @@ -155,7 +192,12 @@ namespace sqlite_orm {
* using als = alias_u<User>;
* select(alias_column<als>(column<User>(&User::id)))
*/
template<class A, class C, std::enable_if_t<internal::is_table_alias<A>::value, bool> = true>
template<class A,
class C,
std::enable_if_t<
polyfill::conjunction<internal::is_table_alias<A>,
polyfill::negation<internal::is_cte_moniker<internal::type_t<A>>>>::value,
bool> = true>
constexpr auto alias_column(C field) {
using namespace ::sqlite_orm::internal;
using aliased_type = type_t<A>;
Expand All @@ -173,7 +215,13 @@ namespace sqlite_orm {
* using als = alias_u<User>;
* select(alias_column<als>(&User::id))
*/
template<class A, class F, class O, std::enable_if_t<internal::is_table_alias<A>::value, bool> = true>
template<class A,
class F,
class O,
std::enable_if_t<
polyfill::conjunction<internal::is_table_alias<A>,
polyfill::negation<internal::is_cte_moniker<internal::type_t<A>>>>::value,
bool> = true>
constexpr auto alias_column(F O::*field) {
using namespace ::sqlite_orm::internal;
using aliased_type = type_t<A>;
Expand All @@ -195,6 +243,7 @@ namespace sqlite_orm {
* select(alias_column<als>(&User::id))
*/
template<orm_table_alias auto als, class C>
requires(!orm_cte_moniker<internal::auto_type_t<als>>)
constexpr auto alias_column(C field) {
using namespace ::sqlite_orm::internal;
using A = decltype(als);
Expand Down Expand Up @@ -225,11 +274,60 @@ namespace sqlite_orm {
* select(als->*&User::id)
*/
template<orm_table_alias A, class F>
requires(!orm_cte_moniker<internal::type_t<A>>)
constexpr auto operator->*(const A& /*tableAlias*/, F field) {
return alias_column<A>(std::move(field));
}
#endif

#ifdef SQLITE_ORM_WITH_CTE
/**
* Create a column reference to an aliased CTE column.
*/
template<class A,
class C,
std::enable_if_t<
polyfill::conjunction_v<internal::is_table_alias<A>, internal::is_cte_moniker<internal::type_t<A>>>,
bool> = true>
constexpr auto alias_column(C c) {
using namespace internal;
using cte_moniker_t = type_t<A>;

if constexpr(is_column_pointer_v<C>) {
static_assert(std::is_same<table_type_of_t<C>, cte_moniker_t>::value,
"Column pointer must match aliased CTE");
return alias_column_t<A, C>{c};
} else {
auto cp = column<cte_moniker_t>(c);
return alias_column_t<A, decltype(cp)>{std::move(cp)};
}
}

#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
/**
* Create a column reference to an aliased CTE column.
*
* @note (internal) Intentionally place in the sqlite_orm namespace for ADL (Argument Dependent Lookup)
* because recordset aliases are derived from `sqlite_orm::alias_tag`
*/
template<orm_table_alias A, class C>
requires(orm_cte_moniker<internal::type_t<A>>)
constexpr auto operator->*(const A& /*tableAlias*/, C c) {
return alias_column<A>(std::move(c));
}

/**
* Create a column reference to an aliased CTE column.
*/
template<orm_table_alias auto als, class C>
requires(orm_cte_moniker<internal::auto_type_t<als>>)
constexpr auto alias_column(C c) {
using A = std::remove_const_t<decltype(als)>;
return alias_column<A>(std::move(c));
}
#endif
#endif

/**
* Alias a column expression.
*/
Expand All @@ -247,17 +345,29 @@ namespace sqlite_orm {
return internal::as_t<decltype(als), E>{std::move(expression)};
}

/**
/**
* Alias a column expression.
*/
template<orm_column_alias A, class E>
internal::as_t<A, E> operator>>=(E expression, const A&) {
return {std::move(expression)};
}
#else
/**
* Alias a column expression.
*/
template<class A, class E, internal::satisfies<internal::is_column_alias, A> = true>
internal::as_t<A, E> operator>>=(E expression, const A&) {
return {std::move(expression)};
}
#endif

template<class A, internal::satisfies<internal::is_column_alias, A> = true>
internal::alias_holder<A> get() {
/**
* Wrap a column alias in an alias holder.
*/
template<class T>
internal::alias_holder<T> get() {
static_assert(internal::is_column_alias_v<T>, "");
return {};
}

Expand Down Expand Up @@ -362,4 +472,18 @@ namespace sqlite_orm {
}
}
#endif

#ifdef SQLITE_ORM_WITH_CTE
/**
* column_alias<'1'[, ...]> from a numeric literal.
* E.g. 1_colalias, 2_colalias
*/
template<char... Chars>
[[nodiscard]] SQLITE_ORM_CONSTEVAL auto operator"" _colalias() {
// numeric identifiers are used for automatically assigning implicit aliases to unaliased column expressions,
// which start at "1".
static_assert(std::array{Chars...}[0] > '0');
return internal::column_alias<Chars...>{};
}
#endif
}
29 changes: 26 additions & 3 deletions dev/alias_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ namespace sqlite_orm {
/** @short Alias of a concrete table, see `orm_table_alias`.
*/
template<class A>
SQLITE_ORM_INLINE_VAR constexpr bool is_table_alias_v = polyfill::conjunction_v<
SQLITE_ORM_INLINE_VAR constexpr bool is_table_alias_v = polyfill::conjunction<
is_recordset_alias<A>,
polyfill::negation<std::is_same<polyfill::detected_t<type_t, A>, std::remove_const_t<A>>>>;
polyfill::negation<std::is_same<polyfill::detected_t<type_t, A>, std::remove_const_t<A>>>>::value;

template<class A>
struct is_table_alias : polyfill::bool_constant<is_table_alias_v<A>> {};
Expand All @@ -68,6 +68,20 @@ namespace sqlite_orm {
template<auto recordset>
using decay_table_reference_t = typename decay_table_reference<decltype(recordset)>::type;
#endif

/** @short Moniker of a CTE, see `orm_cte_moniker`.
*/
template<class A>
SQLITE_ORM_INLINE_VAR constexpr bool is_cte_moniker_v =
#ifdef SQLITE_ORM_WITH_CTE
polyfill::conjunction_v<is_recordset_alias<A>,
std::is_same<polyfill::detected_t<type_t, A>, std::remove_const_t<A>>>;
#else
false;
#endif

template<class A>
using is_cte_moniker = polyfill::bool_constant<is_cte_moniker_v<A>>;
}

#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
Expand Down Expand Up @@ -109,6 +123,15 @@ namespace sqlite_orm {
template<class R>
concept orm_table_reference = polyfill::is_specialization_of_v<std::remove_const_t<R>, internal::table_reference>;

/** @short Moniker of a CTE.
*
* A CTE moniker has the following traits:
* - is derived from `alias_tag`.
* - has a `type` typename, which refers to itself.
*/
template<class A>
concept orm_cte_moniker = (orm_recordset_alias<A> && std::same_as<typename A::type, std::remove_const_t<A>>);

/** @short Specifies that a type refers to a mapped table (possibly aliased).
*/
template<class T>
Expand All @@ -122,6 +145,6 @@ namespace sqlite_orm {
/** @short Specifies that a type is a mapped recordset (table reference).
*/
template<class T>
concept orm_mapped_recordset = (orm_table_reference<T>);
concept orm_mapped_recordset = (orm_table_reference<T> || orm_cte_moniker<T>);
#endif
}
23 changes: 23 additions & 0 deletions dev/ast_iterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,29 @@ namespace sqlite_orm {
}
};

#ifdef SQLITE_ORM_WITH_CTE
template<class CTE>
struct ast_iterator<CTE, match_specialization_of<CTE, common_table_expression>> {
using node_type = CTE;

template<class L>
void operator()(const node_type& c, L& lambda) const {
iterate_ast(c.subselect, lambda);
}
};

template<class With>
struct ast_iterator<With, match_specialization_of<With, with_t>> {
using node_type = With;

template<class L>
void operator()(const node_type& c, L& lambda) const {
iterate_ast(c.cte, lambda);
iterate_ast(c.expression, lambda);
}
};
#endif

template<class T>
struct ast_iterator<T, match_if<is_compound_operator, T>> {
using node_type = T;
Expand Down
Loading