Showing preview only (250K chars total). Download the full file or copy to clipboard to get everything.
Repository: mkitzan/constexpr-sql
Branch: master
Commit: ba98a31224ce
Files: 59
Total size: 234.1 KB
Directory structure:
gitextract_sm4g9zum/
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── example.cpp
├── generator.py
├── include/
│ ├── cexpr/
│ │ └── string.hpp
│ ├── ra/
│ │ ├── cross.hpp
│ │ ├── join.hpp
│ │ ├── natural.hpp
│ │ ├── operation.hpp
│ │ ├── projection.hpp
│ │ ├── relation.hpp
│ │ ├── rename.hpp
│ │ └── selection.hpp
│ └── sql/
│ ├── column.hpp
│ ├── index.hpp
│ ├── predicate.hpp
│ ├── query.hpp
│ ├── row.hpp
│ ├── schema.hpp
│ └── tokens.hpp
├── single-header/
│ └── sql.hpp
└── tests/
├── data/
│ ├── authored.tsv
│ ├── books.tsv
│ ├── collected.tsv
│ └── stories.tsv
├── data.hpp
├── perf/
│ ├── data/
│ │ ├── lib-query0
│ │ ├── lib-query1
│ │ ├── lib-query2
│ │ ├── lib-query3
│ │ ├── lib-query4
│ │ ├── lib-query5
│ │ ├── query0
│ │ ├── query1
│ │ ├── query2
│ │ ├── query3
│ │ ├── query4
│ │ └── query5
│ ├── queries/
│ │ ├── lib-query0.cpp
│ │ ├── lib-query1.cpp
│ │ ├── lib-query2.cpp
│ │ ├── lib-query3.cpp
│ │ ├── lib-query4.cpp
│ │ ├── lib-query5.cpp
│ │ ├── query0.cpp
│ │ ├── query1.cpp
│ │ ├── query2.cpp
│ │ ├── query3.cpp
│ │ ├── query4.cpp
│ │ └── query5.cpp
│ ├── runner.sh
│ └── scripts/
│ └── runner.py
├── runner.sh
└── scripts/
├── compose.py
├── generate.py
├── runner.py
└── select.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
================================================
FILE: .gitignore
================================================
tests/*.txt
tests/test.cpp
tests/test
tests/queries/*
.vscode/*
example
.DS_STORE
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2020 Michael Kitzan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Constexpr SQL
A light weight single header alternative to DBMS
This library was developed during my honors project at the [University of Victoria](https://www.uvic.ca/engineering/computerscience/index.php) under the supervision of [Bill Bird](https://github.com/billbird). The original development occurred in this [Metaprogramming Optimization](https://github.com/mkitzan/metaprogramming-optimization) repository, but was moved into a new, dedicated, home repository. The project was inspired and influenced by [Hana Dusíková](https://github.com/hanickadot)'s great [Compile Time Regular Expressions](https://github.com/hanickadot/compile-time-regular-expressions) library (CTRE).
Maintenance may slow in the near future due to my employer's open source software policy. I will be looking into getting approval to continue maintaining this project.
## Library Features and Compiler Support
Supported features:
- SQL query syntax for data processing
- `SELECT` data querying
- `AS` column renaming
- `CROSS JOIN` (note: all column names of each relation must be unique)
- `NATURAL JOIN` (note: natural join will attempt to join on the first column of each relation)
- `WHERE` clause predicates on numeric and `std::string` types
- Wildcard selection with `*`
- Nested queries
- Uppercase and lowercase SQL keywords
- Modern `!=` and legacy `<>` not-equal operator
- Standard SQL operator precedence in `WHERE` clause
- Schemas support all default constructable types
- Indexes for schemas (used for sorting the data)
- Range loop and structured binding declaration support
- [Loading data](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/schema.hpp#L180) from files (no header row)
- [Storing data](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/schema.hpp#L210) from `sql::schema` and `sql::query` objects to files
- Element querying from `sql::row` objects with [`sql::get<"column-name">`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/row.hpp#L81)
Unsupported features (future work):
- `INNER JOIN`, `OUTER JOIN`, `LEFT JOIN`, and `RIGHT JOIN`
- `GROUP BY`, `HAVING`, and `ORDER BY` (using indexes can simulate some of these features)
- `IN` operation within `WHERE` clause
- Template argument error detection
As of April 2020, Constexpr SQL is only supported by **`GCC 9.0+`**. The compiler support is constrained because of the widespread use of the new `C++20` feature ["Class Types in Non-Type Template Parameters"](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0732r2.pdf) (proposal `P0732R2`) which is only implemented by `GCC 9.0+`. Library users specify SQL queries and column labels with string literals which are converted into `constexpr` objects all of which relies on functionality from `P0732R2`.
## Example
The following example shows usage of all class templates a user is expected to define to use the library.
```c++
#include <iostream>
#include <string>
#include "sql.hpp"
using books =
sql::schema<
"books", sql::index<"title">,
sql::column<"title", std::string>,
sql::column<"genre", std::string>,
sql::column<"year", unsigned>,
sql::column<"pages", unsigned>
>;
using authored =
sql::schema<
"authored", sql::index<>,
sql::column<"title", std::string>,
sql::column<"name", std::string>
>;
using query =
sql::query<
"SELECT title AS book, name AS author, year, pages "
"FROM books NATURAL JOIN (SELECT * FROM authored WHERE name = \"Harlan Ellison\") "
"WHERE year = 1967 OR year >= 1972 AND genre = \"science fiction\"",
books, authored
>;
int main()
{
authored a{ sql::load<authored>("tests/data/authored.tsv", '\t') };
books b{ sql::load<books>("tests/data/books.tsv", '\t') };
for (query q{ b, a }; auto const& [book, author, year, pages] : q)
{
std::cout << book << '\t' << author << '\t' << year << '\t' << pages << '\n';
}
return 0;
}
```
[`sql::schema`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/schema.hpp) defines a relation used in a query. [`sql::index`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/index.hpp) defines how an `sql::schema` sorts its data (unsorted if unspecified). [`sql::column`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/column.hpp) types are used to define the rows in an `sql::schema`. [`sql::query`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/query.hpp) wraps a query statement and the `sql::schema` types the query will operate on. [`sql::load`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/schema.hpp#L180) can be used to load data from a file into an `sql::schema`.
The example is from [`example.cpp`](https://github.com/mkitzan/constexpr-sql/blob/master/example.cpp) in the root of the repository, and can be compiled and executed with the following command:
```shell
g++ -std=c++2a -pedantic -Wall -Wextra -Werror -O3 -Isingle-header/ -o example example.cpp && ./example
```
It is strongly recommended to compile with optimizations enabled, otherwise expect template bloat. Use of multiple objects of the same `sql::query` type is considered **undefined behavior** (due to issues involving static members). Instantiating `sql::query` objects should be performed within a guarded scope, like in the example. However, there are no use restrictions to `sql::schema` types. `sql::schema` types may be used multiple times within a single query or in many queries at once. There are more examples and information in [`presentation.pdf`](https://github.com/mkitzan/constexpr-sql/blob/master/presentation.pdf) at the root of the repository.
## Correctness and Performance Testing
The library has a significant testing system which is composed of two script pipelines. All tests use the data from another project of mine called [`Terminus`](https://github.com/mkitzan/terminus) which is a library database shell. The correctness testing pipeline generates nearly 1.5 million test queries, then Constexpr SQL's output is compared against the output of `SQLite3` performing the same queries. The performance testing pipeline executes six different SQL queries implemented using Constexpr SQL and hand coded SQL. The queries are executed over 65 thousand times (256 for `CROSS JOIN` due to computational complexity), and the execution timing is captured using the Linux `time` tool.
The [`runner.sh`](https://github.com/mkitzan/constexpr-sql/blob/master/tests/runner.sh) script in the `tests` directory will execute correctness testing, and the [`runner.sh`](https://github.com/mkitzan/constexpr-sql/tree/master/tests/perf/runner.sh) script in `tests/perf` will execute performance testing.
## Important Class Templates and Implementation Details
The following sections provide a high-level description about how the library is implemented. Hopefully, the sections will provide useful code and document references to others looking to write similar libraries.
### Class Template: `sql::schema`
The `sql::schema` class template represents relational schemas and, when instantiated, SQL tables. The class template is parameterized on three template parameters: `Name`, `Index`, and `Col` template parameter pack. `Name` defines the SQL table name which is matched against table names in a query's `FROM` statement. The `Index` template argument is used to support `GROUP BY` statements by using [**SFINAE**](https://en.cppreference.com/w/cpp/language/sfinae) to select the [underlying column data container](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/schema.hpp#L25) (`std::vector` or `std::multiset`). The `Index` template argument, when fully specified, provides the [comparator functor](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/index.hpp#L15) used by the `std::multiset` container. The `Cols` template parameter pack is expanded into the `sql::row` type for the schema. `sql::schema` objects support [**structured binding declarations**](https://en.cppreference.com/w/cpp/language/structured_binding) which is facilitated partly through the `sql::schema` API and partly through [`std` namespace injections from `sql::row`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/row.hpp#L131) helping to satisfy the [argument dependant lookup](https://en.cppreference.com/w/cpp/language/adl) of the [`get<i>` function](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/row.hpp#L97).
Reference the example [earlier](https://github.com/mkitzan/constexpr-sql#example) for proper usage of `sql::schema`. Notice in the example the string literal as a template argument. String literals are lvalue reference types which are passed as `const` pointers. Normally, pointers can not be used as template arguments. With the new C++20 feature mentioned [earlier](https://github.com/mkitzan/constexpr-sql#library-features-and-compiler-support), a [`cexpr::string`](https://github.com/mkitzan/constexpr-sql/blob/master/include/cexpr/string.hpp) constructor template can be [deduced](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction) to turn the string literal into a `constexpr` object. The deduction is enabled through [`cexpr::string`'s class template argument deduction guide](https://github.com/mkitzan/constexpr-sql/blob/master/include/cexpr/string.hpp#L144) which provides a mapping of constructor arguments to template parameters.
### Class Template: `sql::query`
The [`sql::query`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/query.hpp) class template is the user interface to the SQL query parser. The class is templated on a `cexpr::string` object (the SQL query) and a template parameter pack of `sql::schema` types. At compile time, the SQL query string is parsed into the relational algebra expression tree representing the query's computation. The constructor to a fully specified `sql::query` class takes a variadic pack of `sql::schema` objects which it uses to seed the relational algebra expression tree with iterators to data. The `sql::query` object can then be used in a range loop with structured binding declarations like in the example.
The relational algebra expression tree uses static members to hold data, so only one object of a single fully specified `sql::query` class can exist at once in the program. To ensure this the object should be constructed within a guarded scope like in the example. It's worth noting that even though this class template's source file is the largest among the code base, nearly all of it is only live during compilation to parse the SQL query. In fact, the [runtime interface](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/query.hpp#L666) is deliberately insubstantial, merely providing an wrapper to support range loops and structured binding declarations.
In compliance with range loop syntax, `sql::query` has an associated iterator class [`sql::query_iterator`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/query.hpp#L189). `sql::query_iterator` wraps the type representing the relational algebra expression and handles all of the idiosyncrasies of its usage in favor of the familiar [`forward iterator`](https://en.cppreference.com/w/cpp/named_req/ForwardIterator) interface. When an [`sql::query_iterator` is dereferenced](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/query.hpp#L211), it returns a constant reference to an `sql::row` object representing the current row of output from the query stream.
### Class Template: `sql::row`
The [`sql::row`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/row.hpp) class template is a template recursive linked-list (similar to [`std::tuple`](https://en.cppreference.com/w/cpp/utility/tuple)). A template recursive linked-list is a template metaprogramming pattern which expresses a type analogous to a traditional linked-list. `sql::row` implements this pattern with two template parameters `Col` and `Next`. `Col` represents the [`sql::column`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/column.hpp) which the node in list holds a data element from. `Next` represents the type of the next node in the list, which is either another `sql::row` type or [`sql::void_row`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/row.hpp#L12). Because the next node is expressed as a type the template linked-list does not incur the overhead of holding a next pointer nor the run time cost of dereferencing a pointer to iterate (also makes better use of the cache). A quirk to this pattern is that the node data type need not be homogenous across the list, instead the list may be composed of heterogenous data types. Also, template linked-list access is computed at compile time, so the run time cost is constant.
The example does not demonstrate the [`sql::get<cexpr::string>`](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/row.hpp#L81) helper function. This helper function allows the user to query a specific element from an `sql::row` object by column name. Additionally, `sql::row` has [**ML**-like](https://github.com/mkitzan/constexpr-sql/blob/master/include/sql/row.hpp#L81) functions for getting the `head` and `tail` of the object.
### Relational Algebra Expression Nodes
At the moment, [`ra::projection`](https://github.com/mkitzan/constexpr-sql/blob/master/include/ra/projection.hpp), [`ra::rename`](https://github.com/mkitzan/constexpr-sql/blob/master/include/ra/rename.hpp), [`ra::cross`](https://github.com/mkitzan/constexpr-sql/blob/master/include/ra/cross.hpp), [`ra::natural`](https://github.com/mkitzan/constexpr-sql/blob/master/include/ra/natural.hpp), [`ra::selection`](https://github.com/mkitzan/constexpr-sql/blob/master/include/ra/selection.hpp), and [`ra::relation`](https://github.com/mkitzan/constexpr-sql/blob/master/include/ra/relation.hpp) are the only relational algebra nodes implemented. `ra::projection` and `ra::rename` are unary operators which take a single `sql::row` from their `Input` relational algebra operator and fold their operation over the row before propagating the transformed row to their `Output`. The `fold` is implemented as a template recursive function. `ra::cross` outputs the cross product of two relations. `ra::natural` implements a natural join between two relations using a hash table buffer of the right relation for performance. `ra::selection` uses a predicate function constructed from a `WHERE` clause to filter rows in a query. `ra::relation` is the only terminal node in the expression tree which is used for retrieving the next input in the stream. These operators are composable types and are used to serialize the relational algebra expression tree. Individual objects of each type are not instantiated to compose the expression tree. Instead to ensure the expression tree is a zero overhead abstraction, the types implement a `static` member function `next` used to request data from its input type. The actual `constexpr` template recursive recursive descent SQL parser will serialize these individual nodes together into the appropriate expression tree.
### Constexpr Parsing
As a proof of concept for `constexpr` parsing, two math expression parsers were implemented in old repository: [`cexpr::prefix`](https://github.com/mkitzan/metaprogramming-optimization/blob/master/include/cexpr/prefix.hpp) and [`cexpr::infix`](https://github.com/mkitzan/metaprogramming-optimization/blob/master/include/cexpr/infix.hpp). `cexpr::prefix` demonstrates the fundamental method of `constexpr` parsing an expression tree into a class template. `cexpr::infix` extends this to perform `constepxr` recursive descent parsing. `cexpr::infix` and the SQL query parser are a whole order of magnitude more complex, because there's recursive function template instantiations to many different function templates. The explanation of `constexpr` parsing is illustrated through `cexpr::prefix` for simplicity.
The expression tree created while parsing is a template recursive tree which shares similar properties to the template linked-list (discussed [earlier](https://github.com/mkitzan/constexpr-sql#class-template-sqlrow)). A notable benefit to this data structure is that because the tree is composed of types rather than data values, the tree can be used to express computation models (expression trees) rather than just a tree based container.
Fundamentally, the parsing is accomplished by calling a template recursive `static constexpr` parsing function member parameterized on the token position which the parser's "cursor" is standing on ([`Pos`](https://github.com/mkitzan/metaprogramming-optimization/blob/master/include/cexpr/prefix.hpp#L39) template parameter). At each "cursor" position, the function uses the token to decide the how to proceed. If the token indicates the start of an operation, the parser recurses the immediate left subexpression ("cursor" + 1). On return, the left subexpression will report the depth in the token stream it recursed at which point the right subexpression will pick up at this position. This control flow is expressed in [this line](https://github.com/mkitzan/metaprogramming-optimization/blob/master/include/cexpr/prefix.hpp#L47) of [`cexpr::prefix::parse`](https://github.com/mkitzan/metaprogramming-optimization/blob/master/include/cexpr/prefix.hpp#L40). Once both left and right subexpressions are parsed, the new node's type is formed ([`decltype`](https://en.cppreference.com/w/cpp/language/decltype) left and right subexpressions) which is then propagated to the caller. Otherwise, if the token indicates a terminal, then an appropriate terminal node is constructed. It is necessary that the "cursor" position is unique across template instantiations, otherwise template memoization will lead to "infinite" recursion.
The few ancillary class templates used to support this parsing and the math node `struct` templates can be found in the [`templ` namespace](https://github.com/mkitzan/metaprogramming-optimization/tree/master/include/templ) of the old repository. There is also a [driver program](https://github.com/mkitzan/metaprogramming-optimization/blob/master/resources/parser/equation.cpp) using the parsers in the old repository. In the Constexpr SQL parser, all of the entities in the `templ` namespace were replaced for more template metaprogramming idiomatic structures.
================================================
FILE: example.cpp
================================================
#include <iostream>
#include <string>
#include "sql.hpp"
using books =
sql::schema<
"books", sql::index<"title">,
sql::column<"title", std::string>,
sql::column<"genre", std::string>,
sql::column<"year", unsigned>,
sql::column<"pages", unsigned>
>;
using authored =
sql::schema<
"authored", sql::index<>,
sql::column<"title", std::string>,
sql::column<"name", std::string>
>;
using query =
sql::query<
"SELECT title AS book, name AS author, year, pages "
"FROM books NATURAL JOIN (SELECT * FROM authored WHERE name = \"Harlan Ellison\") "
"WHERE year = 1967 OR year >= 1972 AND genre = \"science fiction\"",
books, authored
>;
int main()
{
authored a{ sql::load<authored>("tests/data/authored.tsv", '\t') };
books b{ sql::load<books>("tests/data/books.tsv", '\t') };
for (query q{ b, a }; auto const& [book, author, year, pages] : q)
{
std::cout << book << '\t' << author << '\t' << year << '\t' << pages << '\n';
}
return 0;
}
================================================
FILE: generator.py
================================================
import os
def include(header, incs, root, included):
file = open("include/" + root, "r")
for line in file:
if line == "#pragma once\n" or line == "\n":
pass
elif line[:10] == "#include \"":
if not line in included:
included += [line]
include(header, incs, line[10:-2], included)
elif line[:10] == "#include <":
incs += [line]
else:
header.write(line)
break
for line in file:
header.write(line)
header.write("\n")
return included, incs
def main():
header = open("temp", "w")
included, incs = include(header, [], "sql/schema.hpp", [])
included, incs = include(header, incs, "sql/query.hpp", included)
header.close()
header = open("single-header/sql.hpp", "w")
header.write("#pragma once\n\n")
for line in sorted(set(incs)):
header.write(line)
header.write("\n")
for line in open("temp"):
header.write(line)
os.remove("temp")
if __name__ == "__main__":
main()
================================================
FILE: include/cexpr/string.hpp
================================================
#pragma once
#include <cstddef>
#include <string>
#include <string_view>
namespace cexpr
{
template <typename Char, std::size_t N>
class string
{
public:
using char_type = Char;
constexpr string() noexcept : size_{ 0 }, string_{ 0 }
{}
constexpr string(const Char(&s)[N]) noexcept : string{}
{
for(; s[size_]; ++size_)
{
string_[size_] = s[size_];
}
}
constexpr string(cexpr::string<Char, N> const& s) noexcept : string{}
{
for (; s[size_]; ++size_)
{
string_[size_] = s[size_];
}
}
constexpr string(std::basic_string_view<Char> const& s) noexcept : string{}
{
if (s.length() < N)
{
for (; size_ < s.length(); ++size_)
{
string_[size_] = s[size_];
}
}
}
constexpr void fill(const Char* begin, const Char* end) noexcept
{
fill_from(begin, end, begin());
}
constexpr void fill_from(const Char* begin, const Char* end, Char* start) noexcept
{
if (end - begin < N)
{
for (auto curr{ start }; begin != end; ++begin, ++curr)
{
*curr = *begin;
}
}
}
inline constexpr std::size_t capacity() const noexcept
{
return N - 1;
}
inline constexpr std::size_t size() const noexcept
{
return size_;
}
inline constexpr Char* begin() noexcept
{
return string_;
}
inline constexpr const Char* cbegin() const noexcept
{
return string_;
}
inline constexpr Char* end() noexcept
{
return &string_[size_];
}
inline constexpr const Char* cend() const noexcept
{
return &string_[size_];
}
inline constexpr Char& operator[](std::size_t i)
{
return string_[i];
}
inline constexpr Char const& operator[](std::size_t i) const
{
return string_[i];
}
template <typename OtherChar, std::size_t OtherN>
constexpr bool operator==(string<OtherChar, OtherN> const& other) const noexcept
{
if constexpr (N != OtherN)
{
return false;
}
std::size_t i{};
for (; i < N && string_[i] == other[i]; ++i);
return i == N;
}
template <typename OtherChar, std::size_t OtherN>
constexpr bool operator==(const OtherChar(&other)[OtherN]) const noexcept
{
if constexpr (N != OtherN)
{
return false;
}
std::size_t i{};
for (; i < N && string_[i] == other[i]; ++i);
return i == N;
}
template <typename OtherChar>
inline bool operator==(std::basic_string<OtherChar> const& other) const noexcept
{
return other == string_;
}
template <typename OtherChar>
inline bool operator!=(std::basic_string<OtherChar> const& other) const noexcept
{
return !(other == string_);
}
private:
std::size_t size_;
Char string_[N];
};
template <typename Char, std::size_t N>
string(const Char[N]) -> string<Char, N>;
template <typename Char, std::size_t N>
inline bool operator==(std::basic_string<Char> const& str, string<Char, N> const& cstr) noexcept
{
return cstr == str;
}
template <typename Char, std::size_t N>
inline bool operator!=(std::basic_string<Char> const& str, string<Char, N> const& cstr) noexcept
{
return cstr != str;
}
} // namespace cexpr
================================================
FILE: include/ra/cross.hpp
================================================
#pragma once
#include "ra/join.hpp"
#include "ra/relation.hpp"
namespace ra
{
template <typename LeftInput, typename RightInput>
class cross : public ra::join<LeftInput, RightInput>
{
using join_type = ra::join<LeftInput, RightInput>;
public:
using output_type = join_type::output_type;
static auto&& next()
{
try
{
copy(join_type::output_row, RightInput::next());
}
catch(ra::data_end const& e)
{
copy(join_type::output_row, LeftInput::next());
RightInput::reset();
copy(join_type::output_row, RightInput::next());
}
return std::move(join_type::output_row);
}
};
} // namespace ra
================================================
FILE: include/ra/join.hpp
================================================
#pragma once
#include <type_traits>
#include "ra/operation.hpp"
#include "sql/row.hpp"
namespace ra
{
namespace
{
template <typename Left, typename Right>
constexpr auto recr_merge()
{
if constexpr (std::is_same_v<Left, sql::void_row>)
{
return Right{};
}
else
{
using next = decltype(recr_merge<typename Left::next, Right>());
return sql::row<typename Left::column, next>{};
}
}
template <typename Left, typename Right>
inline constexpr auto merge()
{
if constexpr (Left::column::name == Right::column::name)
{
return recr_merge<Left, typename Right::next>();
}
else
{
return recr_merge<Left, Right>();
}
}
template <typename Dest, typename Row>
constexpr void recr_copy(Dest& dest, Row const& src)
{
if constexpr (std::is_same_v<Row, sql::void_row>)
{
return;
}
else
{
dest.head() = src.head();
recr_copy(dest.tail(), src.tail());
}
}
template <typename Dest, typename Row>
inline constexpr void copy(Dest& dest, Row const& src)
{
if constexpr (Dest::column::name == Row::column::name)
{
recr_copy(dest, src);
}
else
{
copy(dest.tail(), src);
}
}
} // namespace
template <typename LeftInput, typename RightInput>
class join : public ra::binary<LeftInput, RightInput>
{
using binary_type = ra::binary<LeftInput, RightInput>;
using left_type = typename binary_type::left_type;
using right_type = typename binary_type::right_type;
public:
using output_type = decltype(merge<left_type, right_type>());
template <typename... Inputs>
static inline void seed(Inputs const&... rs)
{
binary_type::seed(rs...);
copy(output_row, LeftInput::next());
}
static inline void reset()
{
binary_type::reset();
copy(output_row, LeftInput::next());
}
static output_type output_row;
};
template <typename LeftInput, typename RightInput>
typename join<LeftInput, RightInput>::output_type join<LeftInput, RightInput>::output_row{};
} // namespace ra
================================================
FILE: include/ra/natural.hpp
================================================
#pragma once
#include <type_traits>
#include <vector>
#include <unordered_map>
#include "ra/join.hpp"
#include "ra/relation.hpp"
namespace ra
{
template <typename LeftInput, typename RightInput>
class natural : public ra::join<LeftInput, RightInput>
{
using join_type = ra::join<LeftInput, RightInput>;
using key_type = std::remove_cvref_t<decltype(LeftInput::next().head())>;
using value_type = std::vector<std::remove_cvref_t<decltype(RightInput::next().tail())>>;
using map_type = std::unordered_map<key_type, value_type>;
public:
using output_type = join_type::output_type;
template <typename... Inputs>
static void seed(Inputs const&... rs)
{
join_type::seed(rs...);
if (row_cache.empty())
{
try
{
for (;;)
{
auto const& row{ RightInput::next() };
row_cache[row.head()].push_back(row.tail());
}
}
catch(ra::data_end const& e)
{
RightInput::reset();
}
}
auto const& active{ row_cache[join_type::output_row.head()] };
curr = active.cbegin();
end = active.cend();
}
static auto&& next()
{
while (curr == end)
{
copy(join_type::output_row, LeftInput::next());
auto const& active{ row_cache[join_type::output_row.head()] };
curr = active.cbegin();
end = active.cend();
}
copy(join_type::output_row, *curr++);
return std::move(join_type::output_row);
}
private:
static map_type row_cache;
static value_type::const_iterator curr;
static value_type::const_iterator end;
};
template <typename LeftInput, typename RightInput>
typename natural<LeftInput, RightInput>::map_type natural<LeftInput, RightInput>::row_cache{};
template <typename LeftInput, typename RightInput>
typename natural<LeftInput, RightInput>::value_type::const_iterator natural<LeftInput, RightInput>::curr;
template <typename LeftInput, typename RightInput>
typename natural<LeftInput, RightInput>::value_type::const_iterator natural<LeftInput, RightInput>::end;
} // namespace ra
================================================
FILE: include/ra/operation.hpp
================================================
#pragma once
#include <type_traits>
namespace ra
{
template <typename Input>
class unary
{
public:
using input_type = std::remove_cvref_t<decltype(Input::next())>;
template <typename... Inputs>
static inline void seed(Inputs const&... rs)
{
Input::seed(rs...);
}
static inline void reset()
{
Input::reset();
}
};
template <typename LeftInput, typename RightInput>
class binary
{
public:
using left_type = std::remove_cvref_t<decltype(LeftInput::next())>;
using right_type = std::remove_cvref_t<decltype(RightInput::next())>;
template <typename... Inputs>
static inline void seed(Inputs const&... rs)
{
LeftInput::seed(rs...);
RightInput::seed(rs...);
}
static inline void reset()
{
LeftInput::reset();
RightInput::reset();
}
};
} // namespace ra
================================================
FILE: include/ra/projection.hpp
================================================
#pragma once
#include "ra/operation.hpp"
#include "sql/row.hpp"
namespace ra
{
template <typename Output, typename Input>
class projection : public ra::unary<Input>
{
using input_type = typename ra::unary<Input>::input_type;
public:
using output_type = Output;
static auto&& next()
{
fold<output_type>(output_row, Input::next());
return std::move(output_row);
}
private:
template <typename Dest>
static inline constexpr void fold(Dest& dest, input_type const& src)
{
if constexpr (Dest::depth == 0)
{
return;
}
else
{
dest.head() = sql::get<Dest::column::name>(src);
fold<typename Dest::next>(dest.tail(), src);
}
}
static output_type output_row;
};
template <typename Output, typename Input>
typename projection<Output, Input>::output_type projection<Output, Input>::output_row{};
} // namespace ra
================================================
FILE: include/ra/relation.hpp
================================================
#pragma once
#include <exception>
#include <type_traits>
namespace ra
{
struct data_end : std::exception
{};
// Id template parameter allows unique ra::relation types to be instantiated from
// a single sql::schema type (for queries referencing a schema multiple times).
template <typename Schema, std::size_t Id>
class relation
{
public:
using output_type = Schema::row_type&;
static auto& next()
{
if (curr != end)
{
return *curr++;
}
else
{
throw ra::data_end{};
}
}
template <typename Input, typename... Inputs>
static void seed(Input const& r, Inputs const&... rs) noexcept
{
if constexpr (std::is_same_v<Input, Schema>)
{
curr = r.begin();
begin = r.begin();
end = r.end();
}
else
{
seed(rs...);
}
}
static inline void reset() noexcept
{
curr = begin;
}
private:
static Schema::const_iterator curr;
static Schema::const_iterator begin;
static Schema::const_iterator end;
};
template <typename Schema, std::size_t Id>
Schema::const_iterator relation<Schema, Id>::curr{};
template <typename Schema, std::size_t Id>
Schema::const_iterator relation<Schema, Id>::begin{};
template <typename Schema, std::size_t Id>
Schema::const_iterator relation<Schema, Id>::end{};
} // namespace ra
================================================
FILE: include/ra/rename.hpp
================================================
#pragma once
#include "ra/operation.hpp"
#include "sql/row.hpp"
namespace ra
{
template <typename Output, typename Input>
class rename : public ra::unary<Input>
{
using input_type = typename ra::unary<Input>::input_type;
public:
using output_type = Output;
static auto&& next()
{
fold<output_type, input_type>(output_row, Input::next());
return std::move(output_row);
}
private:
template <typename Dest, typename Src>
static inline constexpr void fold(Dest& dest, Src const& src)
{
if constexpr (Dest::depth == 0)
{
return;
}
else
{
dest.head() = src.head();
fold<typename Dest::next, typename Src::next>(dest.tail(), src.tail());
}
}
static output_type output_row;
};
template <typename Output, typename Input>
typename rename<Output, Input>::output_type rename<Output, Input>::output_row{};
} // namespace ra
================================================
FILE: include/ra/selection.hpp
================================================
#pragma once
#include "ra/operation.hpp"
namespace ra
{
template <typename Predicate, typename Input>
class selection : public ra::unary<Input>
{
using input_type = typename ra::unary<Input>::input_type;
public:
using output_type = input_type;
static auto&& next()
{
output_row = Input::next();
while(!Predicate::eval(output_row))
{
output_row = Input::next();
}
return std::move(output_row);
}
private:
static output_type output_row;
};
template <typename Output, typename Input>
typename selection<Output, Input>::output_type selection<Output, Input>::output_row{};
} // namespace ra
================================================
FILE: include/sql/column.hpp
================================================
#pragma once
#include "cexpr/string.hpp"
namespace sql
{
template <cexpr::string Name, typename Type>
struct column
{
static constexpr auto name{ Name };
using type = Type;
};
} // namespace sql
================================================
FILE: include/sql/index.hpp
================================================
#pragma once
#include <type_traits>
#include "cexpr/string.hpp"
#include "sql/row.hpp"
namespace sql
{
template <cexpr::string... Columns>
struct index
{
template <typename Row>
struct comparator
{
bool operator()(Row const& left, Row const& right) const noexcept
{
return compare<Columns...>(left, right);
}
private:
template <cexpr::string Col, cexpr::string... Cols>
bool compare(Row const& left, Row const& right) const noexcept
{
auto const& l{ sql::get<Col>(left) };
auto const& r{ sql::get<Col>(right) };
if constexpr (sizeof...(Cols) != 0)
{
if (l == r)
{
return compare<Cols...>(left, right);
}
}
return l < r;
}
};
};
} // namespace sql
================================================
FILE: include/sql/predicate.hpp
================================================
#pragma once
#include <cstddef>
#include "cexpr/string.hpp"
namespace sql
{
namespace
{
// shim to allow all value types like double or float to be used as non-type template parameters.
template <typename Type>
struct value
{
constexpr value(Type v) : val{ v }
{}
Type val;
};
} // namespace
template <cexpr::string Op, typename Row, typename Left, typename Right=void>
struct operation
{
static constexpr bool eval(Row const& row) noexcept
{
if constexpr (Op == "=")
{
return Left::eval(row) == Right::eval(row);
}
else if constexpr (Op == ">")
{
return Left::eval(row) > Right::eval(row);
}
else if constexpr(Op == "<")
{
return Left::eval(row) < Right::eval(row);
}
else if constexpr(Op == ">=")
{
return Left::eval(row) >= Right::eval(row);
}
else if constexpr(Op == "<=")
{
return Left::eval(row) <= Right::eval(row);
}
else if constexpr(Op == "!=" || Op == "<>")
{
return Left::eval(row) != Right::eval(row);
}
else if constexpr(Op == "AND")
{
return Left::eval(row) && Right::eval(row);
}
else if constexpr(Op == "OR")
{
return Left::eval(row) || Right::eval(row);
}
else if constexpr(Op == "NOT")
{
return !Left::eval(row);
}
}
};
template <cexpr::string Column, typename Row>
struct variable
{
static constexpr auto eval(Row const& row) noexcept
{
return sql::get<Column>(row);
}
};
template <auto Const, typename Row>
struct constant
{
static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
{
return Const.val;
}
};
} // namespace sql
================================================
FILE: include/sql/query.hpp
================================================
#pragma once
#include <array>
#include <string>
#include <string_view>
#include <type_traits>
#include "cexpr/string.hpp"
#include "ra/cross.hpp"
#include "ra/join.hpp"
#include "ra/natural.hpp"
#include "ra/projection.hpp"
#include "ra/relation.hpp"
#include "ra/rename.hpp"
#include "ra/selection.hpp"
#include "sql/column.hpp"
#include "sql/tokens.hpp"
#include "sql/predicate.hpp"
#include "sql/row.hpp"
namespace sql
{
// anonymous namespace to hold helper data structures and functions
namespace
{
template <std::size_t Pos, typename Node>
struct context
{
using node = Node;
static constexpr std::size_t pos = Pos;
};
template <typename Type, std::size_t Name, std::size_t Next>
struct colinfo
{
using type = Type;
static constexpr std::size_t name = Name;
static constexpr std::size_t next = Next;
};
template <cexpr::string Name, typename Row>
constexpr bool exists() noexcept
{
if constexpr (std::is_same_v<Row, sql::void_row>)
{
return false;
}
else
{
if constexpr (Row::column::name == Name)
{
return true;
}
else
{
return exists<Name, typename Row::next>();
}
}
}
template <typename Type, typename Char, std::size_t N>
constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
{
auto curr{ str.cbegin() }, end{ str.cend() };
constexpr Char dot{ '.' }, zro{ '0' }, min{ '-' };
Type acc{}, sign{ 1 }, scalar{ 10 };
if (*curr == min)
{
sign = -1;
++curr;
}
while (curr != end && *curr != dot)
{
acc = (acc * scalar) + (*curr - zro);
++curr;
}
if (curr != end && *curr == dot)
{
scalar = 1;
++curr;
while(curr != end)
{
acc += (*curr - zro) * (scalar /= Type{ 10 });
++curr;
}
}
return value<Type>{ acc * sign };
}
inline constexpr bool isquote(std::string_view const& tv) noexcept
{
return tv == "\"" || tv == "'";
}
inline constexpr bool isor(std::string_view const& tv) noexcept
{
return tv == "OR" || tv == "or";
}
inline constexpr bool isand(std::string_view const& tv) noexcept
{
return tv == "AND" || tv == "and";
}
inline constexpr bool isnot(std::string_view const& tv) noexcept
{
return tv == "NOT" || tv == "not";
}
inline constexpr bool isnatural(std::string_view const& tv) noexcept
{
return tv == "NATURAL" || tv == "natural";
}
inline constexpr bool isjoin(std::string_view const& tv) noexcept
{
return tv == "JOIN" || tv == "join";
}
inline constexpr bool iswhere(std::string_view const& tv) noexcept
{
return tv == "WHERE" || tv == "where";
}
inline constexpr bool isfrom(std::string_view const& tv) noexcept
{
return tv == "FROM" || tv == "from";
}
inline constexpr bool isas(std::string_view const& tv) noexcept
{
return tv == "AS" || tv == "as";
}
inline constexpr bool isselect(std::string_view const& tv) noexcept
{
return tv == "SELECT" || tv == "select";
}
inline constexpr bool iscomma(std::string_view const& tv) noexcept
{
return tv == ",";
}
constexpr bool isintegral(std::string_view const& tv) noexcept
{
bool result{ false };
for (auto c : tv)
{
result |= (c == '.');
}
return !result;
}
constexpr bool isdigit(char c) noexcept
{
return (c >= '0' && c <= '9') || c == '-' || c == '.';
}
constexpr bool iscomp(char c) noexcept
{
return c == '=' || c == '!' || c == '<' || c == '>';
}
constexpr bool iscolumn(std::string_view const& tv) noexcept
{
return !iscomma(tv) && !isas(tv) && !isfrom(tv);
}
constexpr bool isseparator(std::string_view const& tv) noexcept
{
return iscomma(tv) || isfrom(tv);
}
} // namespace
// structured binding compliant iterator for query objects
template <typename Expr>
class query_iterator
{
public:
using row_type = std::remove_cvref_t<typename Expr::output_type>;
// seeds row datamember for first dereference
query_iterator(bool end) : end_{ end }, row_{}
{
operator++();
}
inline bool operator==(query_iterator const& it) const noexcept
{
return end_ == it.end_;
}
inline bool operator!=(query_iterator const& it) const noexcept
{
return !(*this == it);
}
inline row_type const& operator*() const noexcept
{
return row_;
}
query_iterator& operator++()
{
if (!end_)
{
try
{
row_ = Expr::next();
}
catch (ra::data_end const& e)
{
end_ = true;
}
}
return *this;
}
private:
bool end_{};
row_type row_{};
};
template <cexpr::string Str, typename... Schemas>
class query
{
private:
// where predicate terminal parsing
template <std::size_t Pos, typename Row>
static constexpr auto parse_terms()
{
if constexpr (tokens_[Pos] == "(")
{
constexpr auto next{ parse_or<Pos + 1, Row>() };
using node = typename decltype(next)::node;
static_assert(tokens_[next.pos] == ")", "No closing paranthesis found.");
return context<next.pos + 1, node>{};
}
else if constexpr (isquote(tokens_[Pos]))
{
constexpr cexpr::string<char, tokens_[Pos + 1].length() + 1> name{ tokens_[Pos + 1] };
using str = decltype(name);
using node = sql::constant<value<str>{ name }, Row>;
static_assert(isquote(tokens_[Pos + 2]), "No closing quote found.");
return context<Pos + 3, node>{};
}
else if constexpr (isdigit(tokens_[Pos][0]))
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
using val = decltype(isintegral(tokens_[Pos]) ? std::int64_t{} : double{});
using node = sql::constant<sql::convert<val>(name), Row>;
return context<Pos + 1, node>{};
}
else
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
using node = sql::variable<name, Row>;
return context<Pos + 1, node>{};
}
}
// parses a single compare operation
template <typename Left, typename Row>
static constexpr auto recurse_comparison()
{
if constexpr (!iscomp(tokens_[Left::pos][0]))
{
return Left{};
}
else
{
constexpr auto next{ parse_terms<Left::pos + 1, Row>() };
constexpr cexpr::string<char, tokens_[Left::pos].length() + 1> name{ tokens_[Left::pos] };
using ranode = typename decltype(next)::node;
using node = sql::operation<name, Row, typename Left::node, ranode>;
return context<next.pos, node>{};
}
}
// descend further and attempt to parse a compare operation
template <std::size_t Pos, typename Row>
static constexpr auto parse_comparison()
{
using left = decltype(parse_terms<Pos, Row>());
return recurse_comparison<left, Row>();
}
// attempt to parse a negation operation then descend further
template <std::size_t Pos, typename Row>
static constexpr auto parse_negation()
{
if constexpr (isnot(tokens_[Pos]))
{
constexpr auto next{ parse_comparison<Pos + 1, Row>() };
using ranode = typename decltype(next)::node;
using node = sql::operation<"NOT", Row, ranode>;
return context<next.pos, node>{};
}
else
{
return parse_comparison<Pos, Row>();
}
}
// recursively parse chained AND operations
template <typename Left, typename Row>
static constexpr auto recurse_and()
{
if constexpr (!isand(tokens_[Left::pos]))
{
return Left{};
}
else
{
constexpr auto next{ parse_negation<Left::pos + 1, Row>() };
using ranode = typename decltype(next)::node;
using node = sql::operation<"AND", Row, typename Left::node, ranode>;
return recurse_and<context<next.pos, node>, Row>();
}
}
// descend further then attempt to parse AND operations
template <std::size_t Pos, typename Row>
static constexpr auto parse_and()
{
using left = decltype(parse_negation<Pos, Row>());
return recurse_and<left, Row>();
}
// recursively parse chained OR operations
template <typename Left, typename Row>
static constexpr auto recurse_or()
{
if constexpr (!isor(tokens_[Left::pos]))
{
return Left{};
}
else
{
constexpr auto next{ parse_and<Left::pos + 1, Row>() };
using ranode = typename decltype(next)::node;
using node = sql::operation<"OR", Row, typename Left::node, ranode>;
return recurse_or<context<next.pos, node>, Row>();
}
}
// descend further then attempt to parse OR operations
template <std::size_t Pos, typename Row>
static constexpr auto parse_or()
{
using left = decltype(parse_and<Pos, Row>());
return recurse_or<left, Row>();
}
// find correct schema for terminal relation
template <cexpr::string Name, std::size_t Id, typename Schema, typename... Others>
static constexpr auto recurse_schemas()
{
if constexpr (Name == Schema::name)
{
return ra::relation<Schema, Id>{};
}
else
{
static_assert(sizeof...(Others) != 0, "Schema name used in JOIN was not provided.");
return recurse_schemas<Name, Id, Others...>();
}
}
// wrapper function to determine terminal relation
template <std::size_t Pos>
static constexpr auto parse_schema()
{
if constexpr (tokens_[Pos] == "(")
{
constexpr auto next{ parse_root<Pos + 1>() };
using node = typename decltype(next)::node;
static_assert(tokens_[next.pos] == ")", "No closing paranthesis found.");
return context<next.pos + 1, node>{};
}
else
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
using node = decltype(recurse_schemas<name, Pos, Schemas...>());
return context<Pos + 1, node>{};
}
}
// stub which will choose the specific join RA node
template <std::size_t Pos, typename Left, typename Right>
static constexpr auto choose_join()
{
if constexpr (isnatural(tokens_[Pos]))
{
return ra::natural<Left, Right>{};
}
else
{
return ra::cross<Left, Right>{};
}
}
// parses join colinfo if a join is present else returns the single relation terminal
template <std::size_t Pos>
static constexpr auto parse_join()
{
constexpr auto lnext{ parse_schema<Pos>() };
using lnode = typename decltype(lnext)::node;
if constexpr (lnext.pos + 2 < tokens_.count() && isjoin(tokens_[lnext.pos + 1]))
{
constexpr auto rnext{ parse_schema<lnext.pos + 2>() };
using rnode = typename decltype(rnext)::node;
using join = decltype(choose_join<lnext.pos, lnode, rnode>());
return context<rnext.pos, join>{};
}
else
{
return context<lnext.pos, lnode>{};
}
}
// starting point to parse everything after the from keyword
template <std::size_t Pos>
static constexpr auto parse_from()
{
static_assert(isfrom(tokens_[Pos]), "Expected 'FROM' token not found.");
constexpr auto next{ parse_join<Pos + 1>() };
using node = typename decltype(next)::node;
if constexpr (next.pos < tokens_.count() && iswhere(tokens_[next.pos]))
{
using output = std::remove_cvref_t<typename node::output_type>;
constexpr auto predicate{ parse_or<next.pos + 1, output>() };
using pnext = typename decltype(predicate)::node;
using snode = ra::selection<pnext, node>;
return context<predicate.pos, snode>{};
}
else
{
return context<next.pos, node>{};
}
}
// recursively searches all schemas for the a matching column
template <cexpr::string Name, typename Schema, typename... Others>
static constexpr auto recurse_types()
{
if constexpr (sql::exists<Name, typename Schema::row_type>())
{
return decltype(sql::get<Name>(typename Schema::row_type{})){};
}
else
{
static_assert(sizeof...(Others) != 0, "Column name was not present in any schema.");
return recurse_types<Name, Others...>();
}
}
// wrapper to determine the type for the the column
template <std::size_t Pos>
static constexpr auto column_type()
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
return recurse_types<name, Schemas...>();
}
// asserts token is column separator, and if comma returns one past the comma else start position
template <std::size_t Pos>
static constexpr std::size_t next_column()
{
static_assert(isseparator(tokens_[Pos]), "Expected ',' or 'FROM' token following column.");
if constexpr (iscomma(tokens_[Pos]))
{
return Pos + 1;
}
else
{
return Pos;
}
}
template <std::size_t Pos, bool Rename>
static constexpr auto parse_colinfo()
{
static_assert(iscolumn(tokens_[Pos]), "Invalid token starting column delcaration.");
constexpr bool rename{ isas(tokens_[Pos + 1]) && iscolumn(tokens_[Pos + 2]) };
using col = decltype(column_type<Pos>());
if constexpr (Rename && rename)
{
constexpr auto next{ next_column<Pos + 3>() };
return colinfo<col, Pos + 2, next>{};
}
else if constexpr (rename)
{
constexpr auto next{ next_column<Pos + 3>() };
return colinfo<col, Pos, next>{};
}
else
{
constexpr auto next{ next_column<Pos + 1>() };
return colinfo<col, Pos, next>{};
}
}
// recursively parse all columns projected/renamed in the query
template <std::size_t Pos, bool Rename>
static constexpr auto recurse_columns()
{
if constexpr (isfrom(tokens_[Pos]))
{
return context<Pos, sql::void_row>{};
}
else
{
constexpr auto info{ parse_colinfo<Pos, Rename>() };
constexpr cexpr::string<char, tokens_[info.name].length() + 1> name{ tokens_[info.name] };
constexpr auto child{ recurse_columns<info.next, Rename>() };
using next = std::remove_const_t<typename decltype(child)::node>;
using col = std::remove_const_t<decltype(sql::column<name, typename decltype(info)::type>{})>;
using node = sql::row<col, next>;
return context<child.pos, node>{};
}
}
// wrapper to parse columns as a projection RA node
template <std::size_t Pos>
static constexpr auto parse_projection()
{
constexpr auto proj{ recurse_columns<Pos, false>() };
constexpr auto next{ parse_from<proj.pos>() };
using ranode = typename decltype(proj)::node;
using node = ra::projection<ranode, typename decltype(next)::node>;
return context<next.pos, node>{};
}
// wrapper to parse columns as a rename RA node
template <std::size_t Pos>
static constexpr auto parse_rename()
{
constexpr auto next = parse_projection<Pos>();
using ranode = typename decltype(recurse_columns<Pos, true>())::node;
using node = ra::rename<ranode, typename decltype(next)::node>;
return context<next.pos, node>{};
}
// attempts to match column rename operation pattern on a column
template <std::size_t Pos>
static constexpr bool has_rename()
{
if constexpr (isfrom(tokens_[Pos]) || isfrom(tokens_[Pos + 2]))
{
return false;
}
else if constexpr (iscolumn(tokens_[Pos]) && isas(tokens_[Pos + 1]) && iscolumn(tokens_[Pos + 2]))
{
return true;
}
else
{
constexpr bool comma{ iscomma(tokens_[Pos + 1]) };
static_assert(comma || isfrom(tokens_[Pos + 1]), "Expected ',' or 'FROM' token following column.");
if constexpr (comma)
{
return has_rename<Pos + 2>();
}
else
{
return has_rename<Pos + 1>();
}
}
}
// decide RA node to root the expression tree
template <std::size_t Pos>
static constexpr auto parse_root()
{
static_assert(isselect(tokens_[Pos]), "Expected 'SELECT' token not found.");
if constexpr (tokens_[Pos + 1] == "*")
{
return parse_from<Pos + 2>();
}
else if constexpr (has_rename<Pos + 1>())
{
return parse_rename<Pos + 1>();
}
else
{
return parse_projection<Pos + 1>();
}
}
static constexpr sql::tokens<char, sql::preprocess(Str)> tokens_{ Str };
using expression = typename decltype(parse_root<0>())::node;
bool empty_;
public:
using iterator = query_iterator<expression>;
using row_type = expression::output_type;
query(Schemas const&... tables)
{
try
{
expression::seed(tables...);
empty_ = false;
}
catch(ra::data_end const& e)
{
empty_ = true;
}
}
~query()
{
expression::reset();
}
inline iterator begin() const
{
return iterator{ empty_ };
}
inline iterator end() const
{
return iterator{ true };
}
};
} // namespace sql
================================================
FILE: include/sql/row.hpp
================================================
#pragma once
#include <type_traits>
#include <utility>
#include <vector>
#include "cexpr/string.hpp"
namespace sql
{
struct void_row
{
static constexpr std::size_t depth{ 0 };
};
template <typename Col, typename Next>
class row
{
public:
using column = Col;
using next = Next;
static constexpr std::size_t depth{ 1 + next::depth };
row() = default;
template <typename... ColTs>
row(column::type const& val, ColTs const&... vals) : value_{ val }, next_{ vals... }
{}
template <typename... ColTs>
row(column::type&& val, ColTs&&... vals) : value_{ std::forward<column::type>(val) }, next_{ std::forward<ColTs>(vals)... }
{}
inline constexpr next const& tail() const noexcept
{
return next_;
}
inline constexpr next& tail() noexcept
{
return next_;
}
inline constexpr column::type const& head() const noexcept
{
return value_;
}
inline constexpr column::type& head() noexcept
{
return value_;
}
private:
column::type value_;
next next_;
};
template <typename Col, typename... Cols>
struct variadic_row
{
private:
static inline constexpr auto resolve() noexcept
{
if constexpr (sizeof...(Cols) != 0)
{
return typename variadic_row<Cols...>::row_type{};
}
else
{
return void_row{};
}
}
public:
using row_type = row<Col, decltype(resolve())>;
};
// user function to query row elements by column name
template <cexpr::string Name, typename Row>
constexpr auto const& get(Row const& r) noexcept
{
static_assert(!std::is_same_v<Row, sql::void_row>, "Name does not match a column name.");
if constexpr (Row::column::name == Name)
{
return r.head();
}
else
{
return get<Name>(r.tail());
}
}
// compiler function used by structured binding declaration
template <std::size_t Pos, typename Row>
constexpr auto const& get(Row const& r) noexcept
{
static_assert(Pos < Row::depth, "Position is larger than number of row columns.");
if constexpr (Pos == 0)
{
return r.head();
}
else
{
return get<Pos - 1>(r.tail());
}
}
// function to assign a value to a column's value in a row
template <cexpr::string Name, typename Row, typename Type>
constexpr void set(Row& r, Type const& value)
{
static_assert(!std::is_same_v<Row, sql::void_row>, "Name does not match a column name.");
if constexpr (Row::column::name == Name)
{
r.head() = value;
}
else
{
set<Name>(r.tail(), value);
}
}
} // namespace sql
// STL injections to allow row to be used in structured binding declarations
namespace std
{
template <typename Col, typename Next>
class tuple_size<sql::row<Col, Next>> : public integral_constant<size_t, sql::row<Col, Next>::depth>
{};
template <size_t Index, typename Col, typename Next>
struct tuple_element<Index, sql::row<Col, Next>>
{
using type = decltype(sql::get<Index>(sql::row<Col, Next>{}));
};
} // namespace std
================================================
FILE: include/sql/schema.hpp
================================================
#pragma once
#include <fstream>
#include <set>
#include <type_traits>
#include <utility>
#include <vector>
#include "cexpr/string.hpp"
#include "sql/column.hpp"
#include "sql/index.hpp"
#include "sql/row.hpp"
namespace sql
{
template <cexpr::string Name, typename Index, typename... Cols>
class schema
{
public:
static constexpr auto name{ Name };
using row_type = sql::variadic_row<Cols...>::row_type;
using container = typename
std::conditional_t<
std::is_same_v<Index, sql::index<>>,
std::vector<row_type>,
std::multiset<row_type, typename Index::template comparator<row_type>>
>;
using const_iterator = typename container::const_iterator;
schema() = default;
template <typename Type, typename... Types>
schema(std::vector<Type> const& col, Types const&... cols) : schema{}
{
insert(col, cols...);
}
template <typename Type, typename... Types>
schema(std::vector<Type>&& col, Types&&... cols) : schema{}
{
insert(std::forward<Type>(col), std::forward<Types>(cols)...);
}
template <typename... Types>
inline void emplace(Types const&... vals)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.emplace_back(vals...);
}
else
{
table_.emplace(vals...);
}
}
template <typename... Types>
inline void emplace(Types&&... vals)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.emplace_back(vals...);
}
else
{
table_.emplace(vals...);
}
}
template <typename Type, typename... Types>
void insert(std::vector<Type> const& col, Types const&... cols)
{
for (std::size_t i{}; i < col.size(); ++i)
{
emplace(col[i], cols[i]...);
}
}
template <typename Type, typename... Types>
void insert(std::vector<Type>&& col, Types&&... cols)
{
for (std::size_t i{}; i < col.size(); ++i)
{
emplace(std::forward<Type>(col[i]), std::forward<Types>(cols[i])...);
}
}
void insert(row_type const& row)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.push_back(row);
}
else
{
table_.insert(row);
}
}
void insert(row_type&& row)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.push_back(std::forward<row_type>(row));
}
else
{
table_.insert(std::forward<row_type>(row));
}
}
inline const_iterator begin() const noexcept
{
return table_.begin();
}
inline const_iterator end() const noexcept
{
return table_.end();
}
private:
container table_;
};
namespace
{
template <typename Row>
void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
{
if constexpr (!std::is_same_v<Row, sql::void_row>)
{
if constexpr (std::is_same_v<typename Row::column::type, std::string>)
{
if constexpr (std::is_same_v<typename Row::next, sql::void_row>)
{
std::getline(fstr, row.head());
}
else
{
std::getline(fstr, row.head(), delim);
}
}
else
{
fstr >> row.head();
}
fill<typename Row::next>(fstr, row.tail(), delim);
}
}
template <typename Row>
void fill(std::fstream& fstr, Row const& row, char delim)
{
if constexpr (!std::is_same_v<Row, sql::void_row>)
{
fstr << row.head();
if constexpr (std::is_same_v<typename Row::next, sql::void_row>)
{
fstr << '\n';
}
else
{
fstr << delim;
}
fill<typename Row::next>(fstr, row.tail(), delim);
}
}
} // namespace
// helper function for users to load a data into a schema from a file
template <typename Schema>
Schema load(std::string const& file, char delim)
{
auto fstr{ std::fstream(file, fstr.in) };
Schema table{};
typename Schema::row_type row{};
while (fstr)
{
fill<typename Schema::row_type>(fstr, row, delim);
table.insert(std::move(row));
// in case last stream extraction did not remove newline
if (fstr.get() != '\n')
{
fstr.unget();
}
}
return table;
}
// for compat with previous versions
template <typename Schema, char Delim>
inline Schema load(std::string const& file)
{
return load<Schema>(file, Delim);
}
// will work with schema and query objects
template <typename Type>
void store(Type const& data, std::string const& file, char delim)
{
auto fstr{ std::fstream(file, fstr.out) };
for (auto const& row : data)
{
fill<typename Type::row_type>(fstr, row, delim);
}
}
// for devs who want to use the previous format
template <typename Type, char Delim>
inline void store(Type const& data, std::string const& file)
{
store<Type>(data, file, Delim);
}
} // namespace sql
================================================
FILE: include/sql/tokens.hpp
================================================
#pragma once
#include <array>
#include <cstddef>
#include <locale>
#include <string_view>
#include "cexpr/string.hpp"
namespace sql
{
namespace
{
template <typename Char>
constexpr bool whitespace(Char curr)
{
return curr == Char{ ' ' } || curr == Char{ '\t' } || curr == Char{ '\n' };
}
template <typename Char>
constexpr bool syntax(Char curr)
{
return curr == Char{ ',' } || curr == Char{ '(' } || curr == Char{ ')' } ||
curr == Char{ '\'' } || curr == Char{ '\"' } || curr == Char{ '=' };
}
template <typename Char>
constexpr const Char* skip(const Char *curr, const Char *end)
{
for (; curr != end && whitespace(*curr); ++curr);
return curr;
}
template <typename Char>
constexpr const Char* next(const Char *curr, const Char *end)
{
Char c{ *curr };
if (c == Char{ '>' } || c == Char{ '<' } || c == Char{ '!' })
{
++curr;
if (*curr == Char{ '=' } || (c == Char{ '<' } && *curr == Char{ '>' }))
{
++curr;
}
}
else if (syntax(c))
{
++curr;
}
else
{
for (; curr != end && !whitespace(*curr) && !syntax(*curr); ++curr);
}
return curr;
}
} // namespace
template <typename Char, std::size_t Count>
class tokens
{
public:
using token_view = std::basic_string_view<Char>;
constexpr tokens() = default;
template<std::size_t N>
constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
{
auto curr{ cs.cbegin() }, last{ cs.cbegin() };
const auto end{ cs.cend() };
std::size_t i{};
while (curr < end)
{
curr = skip(curr, end);
last = curr;
last = next(last, end);
if (*curr == Char{ '\"' } || *curr == Char{ '\'' })
{
tokens_[i++] = token_view{ curr, 1 };
for (char c{ *curr++ }; last != end && *last != c; ++last);
}
auto len{ reinterpret_cast<std::size_t>(last) - reinterpret_cast<std::size_t>(curr) };
tokens_[i++] = token_view{ curr, len };
if (*last == Char{ '\"' } || *last == Char{ '\'' })
{
tokens_[i++] = token_view{ last, 1 };
++last;
}
curr = last;
}
}
constexpr std::size_t count() const noexcept
{
return Count;
}
constexpr token_view* begin() noexcept
{
return tokens_.begin();
}
constexpr const token_view* cbegin() const noexcept
{
return tokens_.cbegin();
}
constexpr token_view* end() noexcept
{
return tokens_.end();
}
constexpr const token_view* cend() const noexcept
{
return tokens_.cend();
}
constexpr token_view& operator[](std::size_t i)
{
return tokens_[i];
}
constexpr token_view const& operator[](std::size_t i) const
{
return tokens_[i];
}
private:
std::array<token_view, Count> tokens_;
};
template<typename Char, std::size_t N>
constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noexcept
{
auto begin{ cs.cbegin() };
const auto end{ cs.cend() };
std::size_t count{ 1 };
while (begin < end)
{
begin = skip(begin, end);
begin = next(begin, end);
++count;
}
return count;
}
} // namespace sql
================================================
FILE: single-header/sql.hpp
================================================
#pragma once
#include <array>
#include <cstddef>
#include <exception>
#include <fstream>
#include <locale>
#include <set>
#include <string>
#include <string_view>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
namespace cexpr
{
template <typename Char, std::size_t N>
class string
{
public:
using char_type = Char;
constexpr string() noexcept : size_{ 0 }, string_{ 0 }
{}
constexpr string(const Char(&s)[N]) noexcept : string{}
{
for(; s[size_]; ++size_)
{
string_[size_] = s[size_];
}
}
constexpr string(cexpr::string<Char, N> const& s) noexcept : string{}
{
for (; s[size_]; ++size_)
{
string_[size_] = s[size_];
}
}
constexpr string(std::basic_string_view<Char> const& s) noexcept : string{}
{
if (s.length() < N)
{
for (; size_ < s.length(); ++size_)
{
string_[size_] = s[size_];
}
}
}
constexpr void fill(const Char* begin, const Char* end) noexcept
{
fill_from(begin, end, begin());
}
constexpr void fill_from(const Char* begin, const Char* end, Char* start) noexcept
{
if (end - begin < N)
{
for (auto curr{ start }; begin != end; ++begin, ++curr)
{
*curr = *begin;
}
}
}
inline constexpr std::size_t capacity() const noexcept
{
return N - 1;
}
inline constexpr std::size_t size() const noexcept
{
return size_;
}
inline constexpr Char* begin() noexcept
{
return string_;
}
inline constexpr const Char* cbegin() const noexcept
{
return string_;
}
inline constexpr Char* end() noexcept
{
return &string_[size_];
}
inline constexpr const Char* cend() const noexcept
{
return &string_[size_];
}
inline constexpr Char& operator[](std::size_t i)
{
return string_[i];
}
inline constexpr Char const& operator[](std::size_t i) const
{
return string_[i];
}
template <typename OtherChar, std::size_t OtherN>
constexpr bool operator==(string<OtherChar, OtherN> const& other) const noexcept
{
if constexpr (N != OtherN)
{
return false;
}
std::size_t i{};
for (; i < N && string_[i] == other[i]; ++i);
return i == N;
}
template <typename OtherChar, std::size_t OtherN>
constexpr bool operator==(const OtherChar(&other)[OtherN]) const noexcept
{
if constexpr (N != OtherN)
{
return false;
}
std::size_t i{};
for (; i < N && string_[i] == other[i]; ++i);
return i == N;
}
template <typename OtherChar>
inline bool operator==(std::basic_string<OtherChar> const& other) const noexcept
{
return other == string_;
}
template <typename OtherChar>
inline bool operator!=(std::basic_string<OtherChar> const& other) const noexcept
{
return !(other == string_);
}
private:
std::size_t size_;
Char string_[N];
};
template <typename Char, std::size_t N>
string(const Char[N]) -> string<Char, N>;
template <typename Char, std::size_t N>
inline bool operator==(std::basic_string<Char> const& str, string<Char, N> const& cstr) noexcept
{
return cstr == str;
}
template <typename Char, std::size_t N>
inline bool operator!=(std::basic_string<Char> const& str, string<Char, N> const& cstr) noexcept
{
return cstr != str;
}
} // namespace cexpr
namespace sql
{
template <cexpr::string Name, typename Type>
struct column
{
static constexpr auto name{ Name };
using type = Type;
};
} // namespace sql
namespace sql
{
struct void_row
{
static constexpr std::size_t depth{ 0 };
};
template <typename Col, typename Next>
class row
{
public:
using column = Col;
using next = Next;
static constexpr std::size_t depth{ 1 + next::depth };
row() = default;
template <typename... ColTs>
row(column::type const& val, ColTs const&... vals) : value_{ val }, next_{ vals... }
{}
template <typename... ColTs>
row(column::type&& val, ColTs&&... vals) : value_{ std::forward<column::type>(val) }, next_{ std::forward<ColTs>(vals)... }
{}
inline constexpr next const& tail() const noexcept
{
return next_;
}
inline constexpr next& tail() noexcept
{
return next_;
}
inline constexpr column::type const& head() const noexcept
{
return value_;
}
inline constexpr column::type& head() noexcept
{
return value_;
}
private:
column::type value_;
next next_;
};
template <typename Col, typename... Cols>
struct variadic_row
{
private:
static inline constexpr auto resolve() noexcept
{
if constexpr (sizeof...(Cols) != 0)
{
return typename variadic_row<Cols...>::row_type{};
}
else
{
return void_row{};
}
}
public:
using row_type = row<Col, decltype(resolve())>;
};
// user function to query row elements by column name
template <cexpr::string Name, typename Row>
constexpr auto const& get(Row const& r) noexcept
{
static_assert(!std::is_same_v<Row, sql::void_row>, "Name does not match a column name.");
if constexpr (Row::column::name == Name)
{
return r.head();
}
else
{
return get<Name>(r.tail());
}
}
// compiler function used by structured binding declaration
template <std::size_t Pos, typename Row>
constexpr auto const& get(Row const& r) noexcept
{
static_assert(Pos < Row::depth, "Position is larger than number of row columns.");
if constexpr (Pos == 0)
{
return r.head();
}
else
{
return get<Pos - 1>(r.tail());
}
}
// function to assign a value to a column's value in a row
template <cexpr::string Name, typename Row, typename Type>
constexpr void set(Row& r, Type const& value)
{
static_assert(!std::is_same_v<Row, sql::void_row>, "Name does not match a column name.");
if constexpr (Row::column::name == Name)
{
r.head() = value;
}
else
{
set<Name>(r.tail(), value);
}
}
} // namespace sql
// STL injections to allow row to be used in structured binding declarations
namespace std
{
template <typename Col, typename Next>
class tuple_size<sql::row<Col, Next>> : public integral_constant<size_t, sql::row<Col, Next>::depth>
{};
template <size_t Index, typename Col, typename Next>
struct tuple_element<Index, sql::row<Col, Next>>
{
using type = decltype(sql::get<Index>(sql::row<Col, Next>{}));
};
} // namespace std
namespace sql
{
template <cexpr::string... Columns>
struct index
{
template <typename Row>
struct comparator
{
bool operator()(Row const& left, Row const& right) const noexcept
{
return compare<Columns...>(left, right);
}
private:
template <cexpr::string Col, cexpr::string... Cols>
bool compare(Row const& left, Row const& right) const noexcept
{
auto const& l{ sql::get<Col>(left) };
auto const& r{ sql::get<Col>(right) };
if constexpr (sizeof...(Cols) != 0)
{
if (l == r)
{
return compare<Cols...>(left, right);
}
}
return l < r;
}
};
};
} // namespace sql
namespace sql
{
template <cexpr::string Name, typename Index, typename... Cols>
class schema
{
public:
static constexpr auto name{ Name };
using row_type = sql::variadic_row<Cols...>::row_type;
using container = typename
std::conditional_t<
std::is_same_v<Index, sql::index<>>,
std::vector<row_type>,
std::multiset<row_type, typename Index::template comparator<row_type>>
>;
using const_iterator = typename container::const_iterator;
schema() = default;
template <typename Type, typename... Types>
schema(std::vector<Type> const& col, Types const&... cols) : schema{}
{
insert(col, cols...);
}
template <typename Type, typename... Types>
schema(std::vector<Type>&& col, Types&&... cols) : schema{}
{
insert(std::forward<Type>(col), std::forward<Types>(cols)...);
}
template <typename... Types>
inline void emplace(Types const&... vals)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.emplace_back(vals...);
}
else
{
table_.emplace(vals...);
}
}
template <typename... Types>
inline void emplace(Types&&... vals)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.emplace_back(vals...);
}
else
{
table_.emplace(vals...);
}
}
template <typename Type, typename... Types>
void insert(std::vector<Type> const& col, Types const&... cols)
{
for (std::size_t i{}; i < col.size(); ++i)
{
emplace(col[i], cols[i]...);
}
}
template <typename Type, typename... Types>
void insert(std::vector<Type>&& col, Types&&... cols)
{
for (std::size_t i{}; i < col.size(); ++i)
{
emplace(std::forward<Type>(col[i]), std::forward<Types>(cols[i])...);
}
}
void insert(row_type const& row)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.push_back(row);
}
else
{
table_.insert(row);
}
}
void insert(row_type&& row)
{
if constexpr (std::is_same_v<Index, sql::index<>>)
{
table_.push_back(std::forward<row_type>(row));
}
else
{
table_.insert(std::forward<row_type>(row));
}
}
inline const_iterator begin() const noexcept
{
return table_.begin();
}
inline const_iterator end() const noexcept
{
return table_.end();
}
private:
container table_;
};
namespace
{
template <typename Row>
void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
{
if constexpr (!std::is_same_v<Row, sql::void_row>)
{
if constexpr (std::is_same_v<typename Row::column::type, std::string>)
{
if constexpr (std::is_same_v<typename Row::next, sql::void_row>)
{
std::getline(fstr, row.head());
}
else
{
std::getline(fstr, row.head(), delim);
}
}
else
{
fstr >> row.head();
}
fill<typename Row::next>(fstr, row.tail(), delim);
}
}
template <typename Row>
void fill(std::fstream& fstr, Row const& row, char delim)
{
if constexpr (!std::is_same_v<Row, sql::void_row>)
{
fstr << row.head();
if constexpr (std::is_same_v<typename Row::next, sql::void_row>)
{
fstr << '\n';
}
else
{
fstr << delim;
}
fill<typename Row::next>(fstr, row.tail(), delim);
}
}
} // namespace
// helper function for users to load a data into a schema from a file
template <typename Schema>
Schema load(std::string const& file, char delim)
{
auto fstr{ std::fstream(file, fstr.in) };
Schema table{};
typename Schema::row_type row{};
while (fstr)
{
fill<typename Schema::row_type>(fstr, row, delim);
table.insert(std::move(row));
// in case last stream extraction did not remove newline
if (fstr.get() != '\n')
{
fstr.unget();
}
}
return table;
}
// for compat with previous versions
template <typename Schema, char Delim>
inline Schema load(std::string const& file)
{
return load<Schema>(file, Delim);
}
// will work with schema and query objects
template <typename Type>
void store(Type const& data, std::string const& file, char delim)
{
auto fstr{ std::fstream(file, fstr.out) };
for (auto const& row : data)
{
fill<typename Type::row_type>(fstr, row, delim);
}
}
// for devs who want to use the previous format
template <typename Type, char Delim>
inline void store(Type const& data, std::string const& file)
{
store<Type>(data, file, Delim);
}
} // namespace sql
namespace ra
{
template <typename Input>
class unary
{
public:
using input_type = std::remove_cvref_t<decltype(Input::next())>;
template <typename... Inputs>
static inline void seed(Inputs const&... rs)
{
Input::seed(rs...);
}
static inline void reset()
{
Input::reset();
}
};
template <typename LeftInput, typename RightInput>
class binary
{
public:
using left_type = std::remove_cvref_t<decltype(LeftInput::next())>;
using right_type = std::remove_cvref_t<decltype(RightInput::next())>;
template <typename... Inputs>
static inline void seed(Inputs const&... rs)
{
LeftInput::seed(rs...);
RightInput::seed(rs...);
}
static inline void reset()
{
LeftInput::reset();
RightInput::reset();
}
};
} // namespace ra
namespace ra
{
namespace
{
template <typename Left, typename Right>
constexpr auto recr_merge()
{
if constexpr (std::is_same_v<Left, sql::void_row>)
{
return Right{};
}
else
{
using next = decltype(recr_merge<typename Left::next, Right>());
return sql::row<typename Left::column, next>{};
}
}
template <typename Left, typename Right>
inline constexpr auto merge()
{
if constexpr (Left::column::name == Right::column::name)
{
return recr_merge<Left, typename Right::next>();
}
else
{
return recr_merge<Left, Right>();
}
}
template <typename Dest, typename Row>
constexpr void recr_copy(Dest& dest, Row const& src)
{
if constexpr (std::is_same_v<Row, sql::void_row>)
{
return;
}
else
{
dest.head() = src.head();
recr_copy(dest.tail(), src.tail());
}
}
template <typename Dest, typename Row>
inline constexpr void copy(Dest& dest, Row const& src)
{
if constexpr (Dest::column::name == Row::column::name)
{
recr_copy(dest, src);
}
else
{
copy(dest.tail(), src);
}
}
} // namespace
template <typename LeftInput, typename RightInput>
class join : public ra::binary<LeftInput, RightInput>
{
using binary_type = ra::binary<LeftInput, RightInput>;
using left_type = typename binary_type::left_type;
using right_type = typename binary_type::right_type;
public:
using output_type = decltype(merge<left_type, right_type>());
template <typename... Inputs>
static inline void seed(Inputs const&... rs)
{
binary_type::seed(rs...);
copy(output_row, LeftInput::next());
}
static inline void reset()
{
binary_type::reset();
copy(output_row, LeftInput::next());
}
static output_type output_row;
};
template <typename LeftInput, typename RightInput>
typename join<LeftInput, RightInput>::output_type join<LeftInput, RightInput>::output_row{};
} // namespace ra
namespace ra
{
struct data_end : std::exception
{};
// Id template parameter allows unique ra::relation types to be instantiated from
// a single sql::schema type (for queries referencing a schema multiple times).
template <typename Schema, std::size_t Id>
class relation
{
public:
using output_type = Schema::row_type&;
static auto& next()
{
if (curr != end)
{
return *curr++;
}
else
{
throw ra::data_end{};
}
}
template <typename Input, typename... Inputs>
static void seed(Input const& r, Inputs const&... rs) noexcept
{
if constexpr (std::is_same_v<Input, Schema>)
{
curr = r.begin();
begin = r.begin();
end = r.end();
}
else
{
seed(rs...);
}
}
static inline void reset() noexcept
{
curr = begin;
}
private:
static Schema::const_iterator curr;
static Schema::const_iterator begin;
static Schema::const_iterator end;
};
template <typename Schema, std::size_t Id>
Schema::const_iterator relation<Schema, Id>::curr{};
template <typename Schema, std::size_t Id>
Schema::const_iterator relation<Schema, Id>::begin{};
template <typename Schema, std::size_t Id>
Schema::const_iterator relation<Schema, Id>::end{};
} // namespace ra
namespace ra
{
template <typename LeftInput, typename RightInput>
class cross : public ra::join<LeftInput, RightInput>
{
using join_type = ra::join<LeftInput, RightInput>;
public:
using output_type = join_type::output_type;
static auto&& next()
{
try
{
copy(join_type::output_row, RightInput::next());
}
catch(ra::data_end const& e)
{
copy(join_type::output_row, LeftInput::next());
RightInput::reset();
copy(join_type::output_row, RightInput::next());
}
return std::move(join_type::output_row);
}
};
} // namespace ra
namespace ra
{
template <typename LeftInput, typename RightInput>
class natural : public ra::join<LeftInput, RightInput>
{
using join_type = ra::join<LeftInput, RightInput>;
using key_type = std::remove_cvref_t<decltype(LeftInput::next().head())>;
using value_type = std::vector<std::remove_cvref_t<decltype(RightInput::next().tail())>>;
using map_type = std::unordered_map<key_type, value_type>;
public:
using output_type = join_type::output_type;
template <typename... Inputs>
static void seed(Inputs const&... rs)
{
join_type::seed(rs...);
if (row_cache.empty())
{
try
{
for (;;)
{
auto const& row{ RightInput::next() };
row_cache[row.head()].push_back(row.tail());
}
}
catch(ra::data_end const& e)
{
RightInput::reset();
}
}
auto const& active{ row_cache[join_type::output_row.head()] };
curr = active.cbegin();
end = active.cend();
}
static auto&& next()
{
while (curr == end)
{
copy(join_type::output_row, LeftInput::next());
auto const& active{ row_cache[join_type::output_row.head()] };
curr = active.cbegin();
end = active.cend();
}
copy(join_type::output_row, *curr++);
return std::move(join_type::output_row);
}
private:
static map_type row_cache;
static value_type::const_iterator curr;
static value_type::const_iterator end;
};
template <typename LeftInput, typename RightInput>
typename natural<LeftInput, RightInput>::map_type natural<LeftInput, RightInput>::row_cache{};
template <typename LeftInput, typename RightInput>
typename natural<LeftInput, RightInput>::value_type::const_iterator natural<LeftInput, RightInput>::curr;
template <typename LeftInput, typename RightInput>
typename natural<LeftInput, RightInput>::value_type::const_iterator natural<LeftInput, RightInput>::end;
} // namespace ra
namespace ra
{
template <typename Output, typename Input>
class projection : public ra::unary<Input>
{
using input_type = typename ra::unary<Input>::input_type;
public:
using output_type = Output;
static auto&& next()
{
fold<output_type>(output_row, Input::next());
return std::move(output_row);
}
private:
template <typename Dest>
static inline constexpr void fold(Dest& dest, input_type const& src)
{
if constexpr (Dest::depth == 0)
{
return;
}
else
{
dest.head() = sql::get<Dest::column::name>(src);
fold<typename Dest::next>(dest.tail(), src);
}
}
static output_type output_row;
};
template <typename Output, typename Input>
typename projection<Output, Input>::output_type projection<Output, Input>::output_row{};
} // namespace ra
namespace ra
{
template <typename Output, typename Input>
class rename : public ra::unary<Input>
{
using input_type = typename ra::unary<Input>::input_type;
public:
using output_type = Output;
static auto&& next()
{
fold<output_type, input_type>(output_row, Input::next());
return std::move(output_row);
}
private:
template <typename Dest, typename Src>
static inline constexpr void fold(Dest& dest, Src const& src)
{
if constexpr (Dest::depth == 0)
{
return;
}
else
{
dest.head() = src.head();
fold<typename Dest::next, typename Src::next>(dest.tail(), src.tail());
}
}
static output_type output_row;
};
template <typename Output, typename Input>
typename rename<Output, Input>::output_type rename<Output, Input>::output_row{};
} // namespace ra
namespace ra
{
template <typename Predicate, typename Input>
class selection : public ra::unary<Input>
{
using input_type = typename ra::unary<Input>::input_type;
public:
using output_type = input_type;
static auto&& next()
{
output_row = Input::next();
while(!Predicate::eval(output_row))
{
output_row = Input::next();
}
return std::move(output_row);
}
private:
static output_type output_row;
};
template <typename Output, typename Input>
typename selection<Output, Input>::output_type selection<Output, Input>::output_row{};
} // namespace ra
namespace sql
{
namespace
{
template <typename Char>
constexpr bool whitespace(Char curr)
{
return curr == Char{ ' ' } || curr == Char{ '\t' } || curr == Char{ '\n' };
}
template <typename Char>
constexpr bool syntax(Char curr)
{
return curr == Char{ ',' } || curr == Char{ '(' } || curr == Char{ ')' } ||
curr == Char{ '\'' } || curr == Char{ '\"' } || curr == Char{ '=' };
}
template <typename Char>
constexpr const Char* skip(const Char *curr, const Char *end)
{
for (; curr != end && whitespace(*curr); ++curr);
return curr;
}
template <typename Char>
constexpr const Char* next(const Char *curr, const Char *end)
{
Char c{ *curr };
if (c == Char{ '>' } || c == Char{ '<' } || c == Char{ '!' })
{
++curr;
if (*curr == Char{ '=' } || (c == Char{ '<' } && *curr == Char{ '>' }))
{
++curr;
}
}
else if (syntax(c))
{
++curr;
}
else
{
for (; curr != end && !whitespace(*curr) && !syntax(*curr); ++curr);
}
return curr;
}
} // namespace
template <typename Char, std::size_t Count>
class tokens
{
public:
using token_view = std::basic_string_view<Char>;
constexpr tokens() = default;
template<std::size_t N>
constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
{
auto curr{ cs.cbegin() }, last{ cs.cbegin() };
const auto end{ cs.cend() };
std::size_t i{};
while (curr < end)
{
curr = skip(curr, end);
last = curr;
last = next(last, end);
if (*curr == Char{ '\"' } || *curr == Char{ '\'' })
{
tokens_[i++] = token_view{ curr, 1 };
for (char c{ *curr++ }; last != end && *last != c; ++last);
}
auto len{ reinterpret_cast<std::size_t>(last) - reinterpret_cast<std::size_t>(curr) };
tokens_[i++] = token_view{ curr, len };
if (*last == Char{ '\"' } || *last == Char{ '\'' })
{
tokens_[i++] = token_view{ last, 1 };
++last;
}
curr = last;
}
}
constexpr std::size_t count() const noexcept
{
return Count;
}
constexpr token_view* begin() noexcept
{
return tokens_.begin();
}
constexpr const token_view* cbegin() const noexcept
{
return tokens_.cbegin();
}
constexpr token_view* end() noexcept
{
return tokens_.end();
}
constexpr const token_view* cend() const noexcept
{
return tokens_.cend();
}
constexpr token_view& operator[](std::size_t i)
{
return tokens_[i];
}
constexpr token_view const& operator[](std::size_t i) const
{
return tokens_[i];
}
private:
std::array<token_view, Count> tokens_;
};
template<typename Char, std::size_t N>
constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noexcept
{
auto begin{ cs.cbegin() };
const auto end{ cs.cend() };
std::size_t count{ 1 };
while (begin < end)
{
begin = skip(begin, end);
begin = next(begin, end);
++count;
}
return count;
}
} // namespace sql
namespace sql
{
namespace
{
// shim to allow all value types like double or float to be used as non-type template parameters.
template <typename Type>
struct value
{
constexpr value(Type v) : val{ v }
{}
Type val;
};
} // namespace
template <cexpr::string Op, typename Row, typename Left, typename Right=void>
struct operation
{
static constexpr bool eval(Row const& row) noexcept
{
if constexpr (Op == "=")
{
return Left::eval(row) == Right::eval(row);
}
else if constexpr (Op == ">")
{
return Left::eval(row) > Right::eval(row);
}
else if constexpr(Op == "<")
{
return Left::eval(row) < Right::eval(row);
}
else if constexpr(Op == ">=")
{
return Left::eval(row) >= Right::eval(row);
}
else if constexpr(Op == "<=")
{
return Left::eval(row) <= Right::eval(row);
}
else if constexpr(Op == "!=" || Op == "<>")
{
return Left::eval(row) != Right::eval(row);
}
else if constexpr(Op == "AND")
{
return Left::eval(row) && Right::eval(row);
}
else if constexpr(Op == "OR")
{
return Left::eval(row) || Right::eval(row);
}
else if constexpr(Op == "NOT")
{
return !Left::eval(row);
}
}
};
template <cexpr::string Column, typename Row>
struct variable
{
static constexpr auto eval(Row const& row) noexcept
{
return sql::get<Column>(row);
}
};
template <auto Const, typename Row>
struct constant
{
static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
{
return Const.val;
}
};
} // namespace sql
namespace sql
{
// anonymous namespace to hold helper data structures and functions
namespace
{
template <std::size_t Pos, typename Node>
struct context
{
using node = Node;
static constexpr std::size_t pos = Pos;
};
template <typename Type, std::size_t Name, std::size_t Next>
struct colinfo
{
using type = Type;
static constexpr std::size_t name = Name;
static constexpr std::size_t next = Next;
};
template <cexpr::string Name, typename Row>
constexpr bool exists() noexcept
{
if constexpr (std::is_same_v<Row, sql::void_row>)
{
return false;
}
else
{
if constexpr (Row::column::name == Name)
{
return true;
}
else
{
return exists<Name, typename Row::next>();
}
}
}
template <typename Type, typename Char, std::size_t N>
constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
{
auto curr{ str.cbegin() }, end{ str.cend() };
constexpr Char dot{ '.' }, zro{ '0' }, min{ '-' };
Type acc{}, sign{ 1 }, scalar{ 10 };
if (*curr == min)
{
sign = -1;
++curr;
}
while (curr != end && *curr != dot)
{
acc = (acc * scalar) + (*curr - zro);
++curr;
}
if (curr != end && *curr == dot)
{
scalar = 1;
++curr;
while(curr != end)
{
acc += (*curr - zro) * (scalar /= Type{ 10 });
++curr;
}
}
return value<Type>{ acc * sign };
}
inline constexpr bool isquote(std::string_view const& tv) noexcept
{
return tv == "\"" || tv == "'";
}
inline constexpr bool isor(std::string_view const& tv) noexcept
{
return tv == "OR" || tv == "or";
}
inline constexpr bool isand(std::string_view const& tv) noexcept
{
return tv == "AND" || tv == "and";
}
inline constexpr bool isnot(std::string_view const& tv) noexcept
{
return tv == "NOT" || tv == "not";
}
inline constexpr bool isnatural(std::string_view const& tv) noexcept
{
return tv == "NATURAL" || tv == "natural";
}
inline constexpr bool isjoin(std::string_view const& tv) noexcept
{
return tv == "JOIN" || tv == "join";
}
inline constexpr bool iswhere(std::string_view const& tv) noexcept
{
return tv == "WHERE" || tv == "where";
}
inline constexpr bool isfrom(std::string_view const& tv) noexcept
{
return tv == "FROM" || tv == "from";
}
inline constexpr bool isas(std::string_view const& tv) noexcept
{
return tv == "AS" || tv == "as";
}
inline constexpr bool isselect(std::string_view const& tv) noexcept
{
return tv == "SELECT" || tv == "select";
}
inline constexpr bool iscomma(std::string_view const& tv) noexcept
{
return tv == ",";
}
constexpr bool isintegral(std::string_view const& tv) noexcept
{
bool result{ false };
for (auto c : tv)
{
result |= (c == '.');
}
return !result;
}
constexpr bool isdigit(char c) noexcept
{
return (c >= '0' && c <= '9') || c == '-' || c == '.';
}
constexpr bool iscomp(char c) noexcept
{
return c == '=' || c == '!' || c == '<' || c == '>';
}
constexpr bool iscolumn(std::string_view const& tv) noexcept
{
return !iscomma(tv) && !isas(tv) && !isfrom(tv);
}
constexpr bool isseparator(std::string_view const& tv) noexcept
{
return iscomma(tv) || isfrom(tv);
}
} // namespace
// structured binding compliant iterator for query objects
template <typename Expr>
class query_iterator
{
public:
using row_type = std::remove_cvref_t<typename Expr::output_type>;
// seeds row datamember for first dereference
query_iterator(bool end) : end_{ end }, row_{}
{
operator++();
}
inline bool operator==(query_iterator const& it) const noexcept
{
return end_ == it.end_;
}
inline bool operator!=(query_iterator const& it) const noexcept
{
return !(*this == it);
}
inline row_type const& operator*() const noexcept
{
return row_;
}
query_iterator& operator++()
{
if (!end_)
{
try
{
row_ = Expr::next();
}
catch (ra::data_end const& e)
{
end_ = true;
}
}
return *this;
}
private:
bool end_{};
row_type row_{};
};
template <cexpr::string Str, typename... Schemas>
class query
{
private:
// where predicate terminal parsing
template <std::size_t Pos, typename Row>
static constexpr auto parse_terms()
{
if constexpr (tokens_[Pos] == "(")
{
constexpr auto next{ parse_or<Pos + 1, Row>() };
using node = typename decltype(next)::node;
static_assert(tokens_[next.pos] == ")", "No closing paranthesis found.");
return context<next.pos + 1, node>{};
}
else if constexpr (isquote(tokens_[Pos]))
{
constexpr cexpr::string<char, tokens_[Pos + 1].length() + 1> name{ tokens_[Pos + 1] };
using str = decltype(name);
using node = sql::constant<value<str>{ name }, Row>;
static_assert(isquote(tokens_[Pos + 2]), "No closing quote found.");
return context<Pos + 3, node>{};
}
else if constexpr (isdigit(tokens_[Pos][0]))
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
using val = decltype(isintegral(tokens_[Pos]) ? std::int64_t{} : double{});
using node = sql::constant<sql::convert<val>(name), Row>;
return context<Pos + 1, node>{};
}
else
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
using node = sql::variable<name, Row>;
return context<Pos + 1, node>{};
}
}
// parses a single compare operation
template <typename Left, typename Row>
static constexpr auto recurse_comparison()
{
if constexpr (!iscomp(tokens_[Left::pos][0]))
{
return Left{};
}
else
{
constexpr auto next{ parse_terms<Left::pos + 1, Row>() };
constexpr cexpr::string<char, tokens_[Left::pos].length() + 1> name{ tokens_[Left::pos] };
using ranode = typename decltype(next)::node;
using node = sql::operation<name, Row, typename Left::node, ranode>;
return context<next.pos, node>{};
}
}
// descend further and attempt to parse a compare operation
template <std::size_t Pos, typename Row>
static constexpr auto parse_comparison()
{
using left = decltype(parse_terms<Pos, Row>());
return recurse_comparison<left, Row>();
}
// attempt to parse a negation operation then descend further
template <std::size_t Pos, typename Row>
static constexpr auto parse_negation()
{
if constexpr (isnot(tokens_[Pos]))
{
constexpr auto next{ parse_comparison<Pos + 1, Row>() };
using ranode = typename decltype(next)::node;
using node = sql::operation<"NOT", Row, ranode>;
return context<next.pos, node>{};
}
else
{
return parse_comparison<Pos, Row>();
}
}
// recursively parse chained AND operations
template <typename Left, typename Row>
static constexpr auto recurse_and()
{
if constexpr (!isand(tokens_[Left::pos]))
{
return Left{};
}
else
{
constexpr auto next{ parse_negation<Left::pos + 1, Row>() };
using ranode = typename decltype(next)::node;
using node = sql::operation<"AND", Row, typename Left::node, ranode>;
return recurse_and<context<next.pos, node>, Row>();
}
}
// descend further then attempt to parse AND operations
template <std::size_t Pos, typename Row>
static constexpr auto parse_and()
{
using left = decltype(parse_negation<Pos, Row>());
return recurse_and<left, Row>();
}
// recursively parse chained OR operations
template <typename Left, typename Row>
static constexpr auto recurse_or()
{
if constexpr (!isor(tokens_[Left::pos]))
{
return Left{};
}
else
{
constexpr auto next{ parse_and<Left::pos + 1, Row>() };
using ranode = typename decltype(next)::node;
using node = sql::operation<"OR", Row, typename Left::node, ranode>;
return recurse_or<context<next.pos, node>, Row>();
}
}
// descend further then attempt to parse OR operations
template <std::size_t Pos, typename Row>
static constexpr auto parse_or()
{
using left = decltype(parse_and<Pos, Row>());
return recurse_or<left, Row>();
}
// find correct schema for terminal relation
template <cexpr::string Name, std::size_t Id, typename Schema, typename... Others>
static constexpr auto recurse_schemas()
{
if constexpr (Name == Schema::name)
{
return ra::relation<Schema, Id>{};
}
else
{
static_assert(sizeof...(Others) != 0, "Schema name used in JOIN was not provided.");
return recurse_schemas<Name, Id, Others...>();
}
}
// wrapper function to determine terminal relation
template <std::size_t Pos>
static constexpr auto parse_schema()
{
if constexpr (tokens_[Pos] == "(")
{
constexpr auto next{ parse_root<Pos + 1>() };
using node = typename decltype(next)::node;
static_assert(tokens_[next.pos] == ")", "No closing paranthesis found.");
return context<next.pos + 1, node>{};
}
else
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
using node = decltype(recurse_schemas<name, Pos, Schemas...>());
return context<Pos + 1, node>{};
}
}
// stub which will choose the specific join RA node
template <std::size_t Pos, typename Left, typename Right>
static constexpr auto choose_join()
{
if constexpr (isnatural(tokens_[Pos]))
{
return ra::natural<Left, Right>{};
}
else
{
return ra::cross<Left, Right>{};
}
}
// parses join colinfo if a join is present else returns the single relation terminal
template <std::size_t Pos>
static constexpr auto parse_join()
{
constexpr auto lnext{ parse_schema<Pos>() };
using lnode = typename decltype(lnext)::node;
if constexpr (lnext.pos + 2 < tokens_.count() && isjoin(tokens_[lnext.pos + 1]))
{
constexpr auto rnext{ parse_schema<lnext.pos + 2>() };
using rnode = typename decltype(rnext)::node;
using join = decltype(choose_join<lnext.pos, lnode, rnode>());
return context<rnext.pos, join>{};
}
else
{
return context<lnext.pos, lnode>{};
}
}
// starting point to parse everything after the from keyword
template <std::size_t Pos>
static constexpr auto parse_from()
{
static_assert(isfrom(tokens_[Pos]), "Expected 'FROM' token not found.");
constexpr auto next{ parse_join<Pos + 1>() };
using node = typename decltype(next)::node;
if constexpr (next.pos < tokens_.count() && iswhere(tokens_[next.pos]))
{
using output = std::remove_cvref_t<typename node::output_type>;
constexpr auto predicate{ parse_or<next.pos + 1, output>() };
using pnext = typename decltype(predicate)::node;
using snode = ra::selection<pnext, node>;
return context<predicate.pos, snode>{};
}
else
{
return context<next.pos, node>{};
}
}
// recursively searches all schemas for the a matching column
template <cexpr::string Name, typename Schema, typename... Others>
static constexpr auto recurse_types()
{
if constexpr (sql::exists<Name, typename Schema::row_type>())
{
return decltype(sql::get<Name>(typename Schema::row_type{})){};
}
else
{
static_assert(sizeof...(Others) != 0, "Column name was not present in any schema.");
return recurse_types<Name, Others...>();
}
}
// wrapper to determine the type for the the column
template <std::size_t Pos>
static constexpr auto column_type()
{
constexpr cexpr::string<char, tokens_[Pos].length() + 1> name{ tokens_[Pos] };
return recurse_types<name, Schemas...>();
}
// asserts token is column separator, and if comma returns one past the comma else start position
template <std::size_t Pos>
static constexpr std::size_t next_column()
{
static_assert(isseparator(tokens_[Pos]), "Expected ',' or 'FROM' token following column.");
if constexpr (iscomma(tokens_[Pos]))
{
return Pos + 1;
}
else
{
return Pos;
}
}
template <std::size_t Pos, bool Rename>
static constexpr auto parse_colinfo()
{
static_assert(iscolumn(tokens_[Pos]), "Invalid token starting column delcaration.");
constexpr bool rename{ isas(tokens_[Pos + 1]) && iscolumn(tokens_[Pos + 2]) };
using col = decltype(column_type<Pos>());
if constexpr (Rename && rename)
{
constexpr auto next{ next_column<Pos + 3>() };
return colinfo<col, Pos + 2, next>{};
}
else if constexpr (rename)
{
constexpr auto next{ next_column<Pos + 3>() };
return colinfo<col, Pos, next>{};
}
else
{
constexpr auto next{ next_column<Pos + 1>() };
return colinfo<col, Pos, next>{};
}
}
// recursively parse all columns projected/renamed in the query
template <std::size_t Pos, bool Rename>
static constexpr auto recurse_columns()
{
if constexpr (isfrom(tokens_[Pos]))
{
return context<Pos, sql::void_row>{};
}
else
{
constexpr auto info{ parse_colinfo<Pos, Rename>() };
constexpr cexpr::string<char, tokens_[info.name].length() + 1> name{ tokens_[info.name] };
constexpr auto child{ recurse_columns<info.next, Rename>() };
using next = std::remove_const_t<typename decltype(child)::node>;
using col = std::remove_const_t<decltype(sql::column<name, typename decltype(info)::type>{})>;
using node = sql::row<col, next>;
return context<child.pos, node>{};
}
}
// wrapper to parse columns as a projection RA node
template <std::size_t Pos>
static constexpr auto parse_projection()
{
constexpr auto proj{ recurse_columns<Pos, false>() };
constexpr auto next{ parse_from<proj.pos>() };
using ranode = typename decltype(proj)::node;
using node = ra::projection<ranode, typename decltype(next)::node>;
return context<next.pos, node>{};
}
// wrapper to parse columns as a rename RA node
template <std::size_t Pos>
static constexpr auto parse_rename()
{
constexpr auto next = parse_projection<Pos>();
using ranode = typename decltype(recurse_columns<Pos, true>())::node;
using node = ra::rename<ranode, typename decltype(next)::node>;
return context<next.pos, node>{};
}
// attempts to match column rename operation pattern on a column
template <std::size_t Pos>
static constexpr bool has_rename()
{
if constexpr (isfrom(tokens_[Pos]) || isfrom(tokens_[Pos + 2]))
{
return false;
}
else if constexpr (iscolumn(tokens_[Pos]) && isas(tokens_[Pos + 1]) && iscolumn(tokens_[Pos + 2]))
{
return true;
}
else
{
constexpr bool comma{ iscomma(tokens_[Pos + 1]) };
static_assert(comma || isfrom(tokens_[Pos + 1]), "Expected ',' or 'FROM' token following column.");
if constexpr (comma)
{
return has_rename<Pos + 2>();
}
else
{
return has_rename<Pos + 1>();
}
}
}
// decide RA node to root the expression tree
template <std::size_t Pos>
static constexpr auto parse_root()
{
static_assert(isselect(tokens_[Pos]), "Expected 'SELECT' token not found.");
if constexpr (tokens_[Pos + 1] == "*")
{
return parse_from<Pos + 2>();
}
else if constexpr (has_rename<Pos + 1>())
{
return parse_rename<Pos + 1>();
}
else
{
return parse_projection<Pos + 1>();
}
}
static constexpr sql::tokens<char, sql::preprocess(Str)> tokens_{ Str };
using expression = typename decltype(parse_root<0>())::node;
bool empty_;
public:
using iterator = query_iterator<expression>;
using row_type = expression::output_type;
query(Schemas const&... tables)
{
try
{
expression::seed(tables...);
empty_ = false;
}
catch(ra::data_end const& e)
{
empty_ = true;
}
}
~query()
{
expression::reset();
}
inline iterator begin() const
{
return iterator{ empty_ };
}
inline iterator end() const
{
return iterator{ true };
}
};
} // namespace sql
================================================
FILE: tests/data/authored.tsv
================================================
1984 George Orwell
!!!The!!Teddy!Crazy!!Show!!! Harlan Ellison
(Learning About) Machine Sex Candas Jane Dorsey
...the World, as we Know 't Howard Waldrop
2001: A Space Odyssey Arthur C. Clarke
2004, or Thereabouts David R. Bunch
20th Century Boys vol.1 Naoki Urasawa
20th Century Boys vol.2 Naoki Urasawa
20th Century Boys vol.3 Naoki Urasawa
20th Century Boys vol.4 Naoki Urasawa
20th Century Boys vol.5 Naoki Urasawa
20th Century Boys vol.6 Naoki Urasawa
A Biography of Tadeo Isidoro Cruz (1829-1874) Jorge Luis Borges
A Brief History of the Trans-Pacific Tunnel Ken Liu
A Canticle for Leibowitz Walter M. Miller, Jr.
A Case of Conscience James Blish
A Case of Identity Arthur Conan Doyle
A Clash of Cymbals James Blish
A Clockwork Orange Anthony Burgess
A Day at Harmenz Tadeusz Borowski
A Deskful of Girls Fritz Leiber
A Dialog About A Dialog Jorge Luis Borges
A Dialog Between Dead Men Jorge Luis Borges
A Farewell to Arms Ernest Hemingway
A Feast of Demons William Morrison
A Few Things I Know About While Away Joanna Russ
A Hundred Ghosts Parade Tonight Xia Jia
A is for Automation Kate Wilhelm
A Life for the Stars James Blish
A Midwinter's Tale Michael Swanwick
A Momentary Taste of Being James Tiptree, Jr.
A Mouse in the Walls of the Global Village Dean R. Koontz
A New Refutation of Time Jorge Luis Borges
A Note on (toward) Bernard Shaw Jorge Luis Borges
A Path Through the Darkness Harlan Ellison
A Prayer for No One's Enemies Harlan Ellison
A Problem Jorge Luis Borges
A Scandal in Bohemia Arthur Conan Doyle
A Scanner Darkly Philip K. Dick
A Time of Changes Robert Silverberg
A Tour of C++ 2nd Bjarne Stroustrup
A Toy for Juliette Robert Bloch
A True Story Tadeusz Borowski
A Visit Tadeusz Borowski
A Way of Thinking Theodore Sturgeon
Absalom, Absalom! William Faulkner
Adrift Just Off the Islets of Langerhans: Latitude 38o54'N, Longitude 77o00'13W Harlan Ellison
Adrift on the Policy Level Chandler Davis
Aesop Clifford D. Simak
After the Days of Dead-Eye 'Dee Pat Cadigan
Again, Dangerous Visions Harlan Ellison
Akira vol.1 Katsuhiro Otomo
Akira vol.2 Katsuhiro Otomo
Akira vol.3 Katsuhiro Otomo
Akira vol.4 Katsuhiro Otomo
Akira vol.5 Katsuhiro Otomo
Akira vol.6 Katsuhiro Otomo
Algorithms 4th Kevin Wayne
Algorithms 4th Robert Sedgewick
All in Good Time Miram Allen deFord
All the Birds Come Home to Roost Harlan Ellison
All the Flavors Ken Liu
All the Lies Lies That Are My Life Harlan Ellison
All The People R. A. Lafferty
All the Sound of Fear Harlan Ellison
All Tomorrow's Parties William Gibson
Along the Scenic Route Harlan Ellison
Alpha Ralpha Boulevard Cordwainer Smith
Amateur in Chancery George O. Smith
America Orson Scott Card
An Advanced Readers' Picture Book of Comparative Cognition Ken Liu
An Examination of the Work of Herbert Quain Jorge Luis Borges
And Chaos Died Joanna Russ
And the Angels Sing Kate Wilhelm
And the Moon be Still as Bright Ray Bradbury
And the Sea Like Mirrors Gregory Benford
Andover and the Android Kate Wilhelm
Angry Candy Harlan Ellison
Animal Farm George Orwell
Anybody Else Like Me? Walter M. Miller, Jr.
Anywhere But Here, With Anybody But You Harlan Ellison
Approaching Oblivion Harlan Ellison
April Fools' Day Forever Kate Wilhelm
Argumentum Ornithologicum Jorge Luis Borges
Army of None Paul Scharre
As Simple As That Zenna Henderson
At the End of the Orbit Arthur C. Clarke
At the Mouse Circus Harlan Ellison
Aunt Parnetta's Electric Blisters Diane Glancy
Auschwitz, Our Home (A Letter) Tadeusz Borowski
Auto-De-Fe Roger Zelazny
Avatars of the Tortoise Jorge Luis Borges
Averroes' Search Jorge Luis Borges
Aye, and Gomorrah... Samuel R. Delany
Balanced Ecology James H. Schmitz
Basilisk Harlan Ellison
Battle for the Mind William Sargant
Battle Without Banners Harlan Ellison
Battlefield Harlan Ellison
Beachhead Clifford D. Simak
Beauty's Beast Robert Bloch
Bed Sheets are White Evelyn Lief
Beowulf Anonymous
Bettyann Kris Neville
Beyond the Blue Event Horizon Frederik Pohl
Bianca's Hands Theodore Sturgeon
Bible and Sword Barbara W. Tuchman
Big Joe and the Nth Generation Walter M. Miller, Jr.
Blabbermouth Theodore Sturgeon
Black Bargain Robert Bloch
Blame! vol.1 Tsumotu Nihei
Blame! vol.2 Tsumotu Nihei
Blame! vol.3 Tsumotu Nihei
Blame! vol.4 Tsumotu Nihei
Blame! vol.5 Tsumotu Nihei
Blame! vol.6 Tsumotu Nihei
Blank? Harlan Ellison
Bleeding Stones Harlan Ellison
Blind Bird, Blind Bird, Go Away From Me! Harlan Ellison
Blood Bank Walter M. Miller, Jr.
Blot Gahan Wilson
Blowups Happen Robert A. Heilein
Blue Spring Taiyo Matsumoto
Borges and I Jorge Luis Borges
Bounty T. L. Sherred
Brain Wave Poul Anderson
Brass and Gold (or Horse and Zeppelin in Beverly Hills) Philip Jose Farmer
Brave New World Aldous Huxley
Bright Eyes Harlan Ellison
Bright Segment Theodore Sturgeon
Broken Glass Harlan Ellison
Brownshoes Theodore Sturgeon
Burning Chrome William Gibson
By His Bootstraps Robert A. Heinlein
C Primer Plus 5th Stephen Prata
C++ Primer 5th Barbara E. Moo
C++ Primer 5th Josee Lajoie
C++ Primer 5th Stanley B. Lippman
Call Girl Tang Fei
Camps Jack Dann
Capitalism Without Capital Jonathan Haskel
Capitalism Without Capital Stian Westlake
Captain Harlock: The Classic Collection vol.1 Leiji Matsumoto
Captain Harlock: The Classic Collection vol.2 Leiji Matsumoto
Captain Harlock: The Classic Collection vol.3 Leiji Matusmoto
Carcinoma Angels Norman Spinard
Catch That Rabbit Isaac Asimov
Catch-22 Joseph Heller
Catman Harlan Ellison
Caviar Theodore Sturgeon
Census Clifford D. Simak
Chain Reaction Boyd Ellanby
Chained to the Fast Lane in the Red Queen's Race Harlan Ellison
Changewar Fritz Leiber
Chapterhouse: Dune Frank Herbert
Chatting with Anubis Harlan Ellison
Childhood's End Arthur C. Clarke
Children of Dune Frank Herbert
Children of the Sea vol.1 Daisuke Igarashi
Children of the Sea vol.2 Daisuke Igarashi
Children of the Sea vol.3 Daisuke Igarashi
Children of the Sea vol.4 Daisuke Igarashi
Children of the Sea vol.5 Daisuke Igarashi
Ching Witch! Ross Rocklynne
Christ, Old Student in a New School Ray Bradbury
Chuck Berry, Won't You Please Come Home Ken McCullough
City Clifford D. Simak
Cold Friend Harlan Ellison
Collecting Team Robert Silverberg
Colossus B. Jack Copeland
Columbus Was a Dope Robert A. Heinlein
Come to the Party F. M. Busby
Comes Now the Power Roger Zelazny
Commuter's Problem Harlan Ellison
Conversations With Jorge Luis Borges Richard Burgin
Corpse Harlan Ellison
Count the Clock That Tells the Time Harlan Ellison
Count Zero William Gibson
Covered Mirrors Jorge Luis Borges
Crate Theodore Sturgeon
Crazy as a Soup Sandwich Harlan Ellison
Croatoan Harlan Ellison
Crome Yellow Aldous Huxley
Crucifixus Etiam Walter M. Miller, Jr.
Curse 5.0 Liu Cixin
Damnation Morning Fritz Leiber
Dandelion Wine Ray Bradbury
Dangerous Visions Harlan Ellison
Danger-Human! Gordon R. Dickson
Daniel White for the Greater Good Harlan Ellison
Darkness Upon the Face of the Deep Harlan Ellison
Day Million Frederik Pohl
Deal From the Bottom Harlan Ellison
Death and the Compass Jorge Luis Borges
Death and the Penguin Andrey Kurkov
Deathbird Stories Harlan Ellison
Death's End Liu Cixin
Deeper than the Darkness Harlan Ellison
Delia Elena San Marco Jorge Luis Borges
Delusion for a Dragon Slayer Harlan Ellison
Design Patterns Erich Gamma
Design Patterns John Vlissides
Design Patterns Ralph Johnson
Design Patterns Richard Helm
Destined for War Graham Allison
Deutsches Requiem Jorge Luis Borges
Devourer Liu Cixin
Dirk Gently's Holistic Detective Agency Douglas Adams
Distant Signals Andrew Weiner
Distrust That Particular Flavor William Gibson
Division by Zero Ted Chiang
Django Harlan Ellison
Djinn, No Chaser Harlan Ellison
Do Androids Dream of Electric Sheep? Philip K. Dick
Doctor Zhivago Boris Pasternak
Dogfight Michael Swanwick
Dogfight William Gibson
Do-It-Yourself Harlan Ellison
Don Quixote Miguel de Cervantes Saavedra
Double Star Robert A. Heinlein
Downward to the Earth Robert Silverberg
Dr. Bloodmoney Philip K. Dick
Dreamtigers Jorge Luis Borges
Dumb Waiter Walter M. Miller, Jr.
Dune Frank Herbert
Dune Messiah Frank Herbert
Dying Inside Robert Silverberg
Each an Explorer Isaac Asimov
Earthman, Come Home James Blish
Earthman, Go Home! Harlan Ellison
Ecowarewness Harlan Ellison
Eidolons Harlan Ellison
Elbow Room Marion Zimmer Bradley
Elegy Jorge Luis Borges
Elouise and the Doctors of the Planet Pergamon Josephine Saxton
Emanon vol.1: Memories of Emanon Kenji Tsuruta
Emanon vol.2: Emanon Wanderer pt.1 Kenji Tsuruta
Emanon vol.3: Emanon Wanderer pt.2 Kenji Tsuruta
Emissary from Hamelin Harlan Ellison
Emma Zunz Jorge Luis Borges
Empire of the Sun Andrew Weiner
Empire Star Samuel R. Delany
Encounter With A Hick Jonathan Brand
Ender's Game Orson Scott Card
Endless Frontier G. Pascal Zachary
Endymion Dan Simmons
Enemy Mine Barry B. Longyear
Eniac Scott McCartney
Epilogue Clifford D. Simak
Epiphany for Aliens David Kerr
Ernest and the Machine God Harlan Ellison
Erotophobia Harlan Ellison
Ersatz Henry Slesar
Escape! Isaac Asimov
Escapegoat Harlan Ellison
Eutopia Poul Anderson
Evensong Lester del Rey
Everything and Nothing Jorge Luis Borges
Evidence Isaac Asimov
Exploration Team Murray Leinster
Explorers of Space Robert Silverberg
Exposures Gregory Benford
Eye of the Beholder Burt K. Filer
Fahrenheit 451 Ray Bradbury
Faith of our Fathers Philip K. Dick
Fault-Tolerant Computer System Designs Dhiraj K. Pradhan
Fear is a Cold Black Kate Wilhelm
Feather Tigers Gene Wolfe
Featherbed on Chlyntha Miram Allen deFord
Fiasco Stanislaw Lem
Ficciones Jorge Luis Borges
Final Trophy Harlan Ellison
Flies Robert Silverberg
Flop Sweat Harlan Ellison
Flow My Tears, the Policeman Said Philip K. Dick
Flowers for Algernon Daniel Keyes
Folding Beijing Hao Jingfang
Footsteps Harlan Ellison
For the Sake of Grace Suzette Haden Elgin
For Value Received Andrew J. Ouffutt
For Whom the Bell Tolls Ernest Hemingway
Forward the Foundation Isaac Asimov
Foundation Isaac Asimov
Foundation and Earth Isaac Asimov
Foundation and Empire Isaac Asimov
Foundation's Edge Isaac Asimov
Fragments of a Hologram Rose William Gibson
Frank Herbert Nebula Winners Fifteen
Frederik Pohl The Expert Dreamers
From A to Z, In The Chocolate Alphabet Harlan Ellison
From the Government Printing Office Kris Neville
Frozen Journey Philip K. Dick
Funes the Memorious Jorge Luis Borges
G. B. K.-A Many-Flavored Bird Harlan Ellison
Gateway Frederik Pohl
Gather Blue Roses Pamela Sargent
Gathi Miram Allen deFord
Getting Along James Blish
Ghost in the Shell Shirow Masamune
Ghost in the Shell vol.1.5: Human-Error Processor Shirow Masamune
Ghost in the Shell vol.2: Man-Machine Interface Shirow Masamune
Ghost of a Chance Theodore Sturgeon
giANTS Edward Bryant
Gift from the Stars Kate Wilhelm
Giganto Maxia Kentaro Miura
Gnomebody Harlan Ellison
Go Toward the Light Harlan Ellison
Go, Go, Go, Said the Bird Sonya Dorman
God Emperor of Dune Frank Herbert
Goldfish Bowl Robert A. Heinlein
Gonna Roll the Bones Fritz Leiber
Good Hunting Ken Liu
Good News from the Vatican Robert Silverberg
Gopher in the Gilly Harlan Ellison
Grail Harlan Ellison
Grave of the Fireflies Cheng Jingbo
Gutter Gang Harlan Ellison
Hadj Harlan Ellison
Half-Life Paul Preuss
Hamlet William Shakespeare
Harry the Hare James B. Hemesath
Hawksbill Station Robert Silverberg
Heart of Darkness Joseph Conrad
Heavyplanet Lee Gregor
Heechee Rendezvous Frederik Pohl
Heechee Treasures Frederik Pohl
Hell Is the Absence of God Ted Chiang
Heretics of Dune Frank Herbert
High Weir Samuel R. Delany
Hindsight: 480 Seconds Harlan Ellison
Hinterlands William Gibson
His Vegetable Pat Murphy
Hitler Painted Roses Harlan Ellison
Hobbies Clifford D. Simak
Homecoming Ray Bradbury
Homelanding Margaret Atwood
Houston, Houston, Do You Read? James Tiptree, Jr.
How Beautiful with Banners James Blish
How's the Night Life on Cassalda? Harlan Ellison
Huddling Place Clifford D. Simak
Humpty Dumpty had a Great Fall Frank Belknap
Hyperion Dan Simmons
I Curse the Lesson and Bless the Knowledge Harlan Ellison
I Will Fear No Evil Robert A. Heinlein
I, Dreamer Walter M. Miller, Jr.
I, Robot Isaac Asimov
Ibn-Hakam al-Bokhari, Murdered in His Labyrinth Jorge Luis Borges
Ichi-F Kazuto Tatsuta
Idoru William Gibson
If All Men Were Brothers, Would You Let One Marry Your Sister? Theodore Sturgeon
I'm Looking for Kadak Harlan Ellison
In Fear of K Harlan Ellison
In Lonely Islands Harlan Ellison
In Memoriam, J. F. K. Jorge Luis Borges
In re Glover Leonard Tushnet
In the Barn Piers Anthony
In the Core Frederik Pohl
In the Fourth Year of the War Harlan Ellison
Incident in Moderan David R. Bunch
Inferno, I, 32 Jorge Luis Borges
Inferno: The World at War, 1939-1945 Max Hastings
Interim Ray Bradbury
Interlocking Pieces Molly Gloss
Into the Wild Jon Krakauer
Into Thin Air Jon Krakauer
Invaders John Kessel
Invasion Footnote Harlan Ellison
Invisible Man Ralph Ellison
Invisible Planets Hao Jingfang
It Theodore Sturgeon
It was Nothing-Really Theodore Sturgeon
It's You! Theodore Sturgeon
J. C. on the Dude Ranch Philip Jose Farmer
Jack-in-the-Box Ray Bradbury
Jane Doe #112 Harlan Ellison
Jeffty is Five Harlan Ellison
Jenny with Wings Kate Wilhelm
Johnny Mnemonic William Gibson
Jorry's Gap Theodore Sturgeon
Judas John Brunner
Julius Caesar William Shakespeare
Jupiter Five Arthur C. Clarke
Jurassic Park Michael Crichton
Kafka and His Precursors Jorge Luis Borges
Invisible Planets Ken Liu
Keyboard Harlan Ellison
Killdozer! Theodore Sturgeon
Killing Bernstein Harlan Ellison
King of the Hill Chad Oliver
Kirinyaga Mike Resnick
Kiss of Fire Harlan Ellison
Knights to Move Fritz Leiber
Knox Harlan Ellison
Kyrie Poul Anderson
Labyrinths Jorge Luis Borges
Ladies and Gentlemen, This Is Your Crisis Kate Wilhelm
Lamia Mutable M. John Harrison
Land of the Great Horses R. A. Lafferty
Last Train to Kankakee Robin Scott
Laugh Track Harlan Ellison
Leadership in Turbulent Times Doris Kearns Goodwin
Lenny Isaac Asimov
Let There Be Light Robert A. Heilein
Liar! Isaac Asimov
Life in Our Time Robert Bloch
Life, the Universe and Everything Douglas Adams
Life-Line Robert A. Heilein
Liking What You See: A Documentary Ted Chiang
Little Lost Robot Isaac Asimov
Lollipop and the Tar Baby John Varley
Lonley Women Are the Vessels of Time Harlan Ellison
Looking for Company Frederik Pohl
Lord of Light Roger Zelazny
Lord of the Flies William Golding
Lord Randy, My Son Joe L. Hensley
Love Ain't Nothing but Sex Misspelled Harlan Ellison
Lucy Comes To Stay Robert Bloch
Madame Curie Eve Curie
Making It All the Way into the Future on Gaxton Falls of the Red Planet Barry N. Malzberg
Man of Letters Kate Wilhelm
Man Plus Frederik Pohl
Martin Fierro Jorge Luis Borges
Martin the Warrior Brian Jacques
Master and Commander Patrick O'Brian
Mathoms from the Time Closet Gene Wolfe
Mattimeo Brian Jacques
Mealtime Harlan Ellison
Medusa Theodore Sturgeon
Mefisto in Onyx Harlan Ellison
Microcosmic God Theodore Sturgeon
Midnight in the Sunken Cathedral Harlan Ellison
Midnight News Lisa Goldstein
Mom Harlan Ellison
Mona at Her Windows Harlan Ellison
Mona Lisa Overdrive William Gibson
Monitored Dreams & Strategic Cremations Bernard Wolfe
Mono no Aware Ken Liu
Monolog Philip Jose Farmer
Monster vol.1 Naoki Urasawa
Monster vol.2 Naoki Urasawa
Monster vol.3 Naoki Urasawa
Monster vol.4 Naoki Urasawa
Monster vol.5 Naoki Urasawa
Monster vol.6 Naoki Urasawa
Monster vol.7 Naoki Urasawa
Monster vol.8 Naoki Urasawa
Monster vol.9 Naoki Urasawa
More Than Human Theodore Sturgeon
Moth Race Richard Hill
Mountain Liu Cixin
Mr. Costello, Hero Theodore Sturgeon
Mrs. Bagley Goes to Mars Kate Wilhelm
Mutations Jorge Luis Borges
Nackles vr.1 Donald E. Westlake
Nackles vr.2 Donald E. Westlake
Nackles vr.2 Harlan Ellison
Nausicaa of the Valley of the Wind vol.1 Hayao Miyazaki
Nausicaa of the Valley of the Wind vol.2 Hayao Miyazaki
Neither Your Jenny Nor Mine Harlan Ellison
Neon Harlan Ellison
Neuromancer William Gibson
New Rose Hotel William Gibson
Night Journey of the Dragon-Horse Xia Jia
Night Meeting Ray Bradbury
Night of Black Glass Harlan Ellison
Nightfall Isaac Asimov
Nightfall Robert Silverberg
Night-Rise Katherine MacLean
Nijigagara Holograph Inio Asano
Nine Hundred Grandmothers R. A. Lafferty
No Game for Children Harlan Ellison
No Great Magic Fritz Leiber
No Light in the Windows Kate Wilhelm
Nothing for My Noon Meal Harlan Ellison
Nova Samuel R. Delany
O Ye of Little Faith Harlan Ellison
Oddy and Id Alfred Bester
Of Ants and Dinosaurs Liu Cixin
On Exactitude and Science Jorge Luis Borges
On the Downhill Slide Harlan Ellison
On the Feasibility of Coal-Driven Power Stations O. R. Frisch
On the Slab Harlan Ellison
One Day in the Life of Ivan Denisovich Aleksandr Solzhenitsyn
One for the Road Kate Wilhelm
One Life, Furnished in Early Poverty Harlan Ellison
One-Way Journey Miram Allen deFord
Operating Systems in Depth Thomas W. Doeppner
Operation Cassandra Miram Allen deFord
Opium Harlan Ellison
Other Worlds Frederik Pohl
Out of All Them Bright Stars Nancy Kress
Over the River and Through the Woods Clifford D. Simak
Overlord Max Hastings
Ozymandias Terry Car
Paingod Harlan Ellison
Paingod and Other Delusions Harlan Ellison
Paladin of the Last Hour Harlan Ellison
Parable of Cervantes and the Quixote Jorge Luis Borges
Parable of the Palace Jorge Luis Borges
Paradise Clifford D. Simak
Paradiso, XXXI, 108 Jorge Luis Borges
Partial Magic in the Quixote Jorge Luis Borges
Pattern Recognition William Gibson
Paulie Charmed the Sleeping Woman Harlan Ellison
Permanent Record Edward Snowden
Persona 3: Official Design Works Shigenori Soejima
Persona 4 Arena: Official Design Works Shigenori Soejima
Persona 4: Official Design Works Shigenori Soejima
Philtre Tip Robert Bloch
Picnic on Paradise Joanna Russ
Pierre Menrad, Author of Don Quixote Jorge Luis Borges
Planet Story Kate Wilhelm
Planetes vol.1 Makoto Yukimura
Planetes vol.2 Makoto Yukimura
Player Piano Kurt Vonnegut
Precession Edward Bryant
Prelude to Foundation Isaac Asimov
Presidents of War Michael Beschloss
Pretty Maggie Moneyeyes Harlan Ellison
Prince Myshkin, and Hold the Relish Harlan Ellison
Prodigy Theodore Sturgeon
Project Nightmare Robert A. Heinlein
Pulling Hard Time Harlan Ellison
Punky & The Yale Men Harlan Ellison
Queen Emeraldas vol.1 Leiji Matsumoto
Queen Emeraldas vol.2 Leiji Matsumoto
Quick to Haste Miram Allen deFord
Quicktime Harlan Ellison
Radio Free Albemuth Philip K. Dick
Ragnarok Jorge Luis Borges
Rain, Rain, Go Away Harlan Ellison
Rat James Patrick Kelly
Reason Isaac Asimov
Red Star, Winter Orbit Bruce Sterling
Red Star, Winter Orbit William Gibson
Redwall Brian Jacques
Rendezvous with Rama Arthur C. Clarke
Repent, Harlequin! Said the Ticktockman Harlan Ellison
Requiem Robert A. Heilein
Riders of the Purple Wage Philip Jose Farmer
Riding the Dark Train Out Harlan Ellison
Ringworld Larry Niven
Riverworld Philip Jose Farmer
Riverworld and Other Stories Philip Jose Farmer
Roadside Picnic Arkady Strugatsky
Roadside Picnic Boris Strugatsky
Robbie Isaac Asimov
Rock God Harlan Ellison
Rocket Summer Ray Bradbury
Runaround Isaac Asimov
Sandkings George R. R. Martin
Saturn, November 11th Harlan Ellison
Scartaris, June 28th Harlan Ellison
Schrodinger's Plague Greg Bear
Schwarzschild Radius Connie Willis
Second Foundation Isaac Asimov
Seeing Harlan Ellison
Selected Poems T. S. Eliot
Selected Stories Theodore Sturgeon
Sensible City Harlan Ellison
Seraphim: 266613336 Wings Satoshi Kon
Seventy-Two Letters Ted Chiang
Sex and/or Mr. Morrison Carol Emshwiller
Shadow, Shadow on the Wall Theodore Sturgeon
Shall the Dust Praise Thee? Damon Knight
Shatterday Harlan Ellison
Shattered Like a Glass Goblin Harlan Ellison
She's a Young Thing and Cannot Leaver Her Mother Harlan Ellison
Shin Megami Tensei 4: Official Artworks Masayuki Doi
Shoppe Keeper Harlan Ellison
Silence Tadeusz Borowski
Silent in Gehenna Harlan Ellison
Silhouette Gene Wolfe
Simulacrum Ken Liu
Sir Gawain and the Green Knight J. R. R. Tolkien
Skeleton Ray Bradbury
Skunk Works Ben R. Rich
Skunk Works Leo Janos
Sky Lift Robert A. Heinlein
Slippage Harlan Ellison
Slow Sculpture Theodore Sturgeon
Snow John Crowley
So Long, and Thanks for All the Fish Douglas Adams
Soft Monkey Harlan Ellison
Solanin Inio Asano
Solaris Stanislaw Lem
Some Assembly Required Timothy S. Margush
Somehow, I Don't Think We're in Kansas, Toto Harlan Ellison
Somerset Dreams Kate Wilhelm
Somerset Dreams and Other Fictions Kate Wilhelm
Souls Joanna Russ
Soundless Evening Lee Hoffman
Speech Sound Octavia E. Butler
Spook Country William Gibson
Stable Strategies for Middle Management Eileen Gunn
Stalingrad Antony Beevor
Stalking the Nightmare Harlan Ellison
Stand Still and Die Harlan Ellison
Starship Troopers Robert A. Heinlein
State Change Ken Liu
State of Grace Kate Wilhelm
Still-Life K. M. O'Donnell
Stillwell and the American Experience in China 1911-1945 Barbara W. Tuchman
Stoned Counsel H. H. Hollis
Stories of Your Life and Others Ted Chiang
Story of the Warrior and the Captive Maiden Jorge Luis Borges
Story of Your Life Ted Chiang
Strange Gifts Robert Silverberg
Strange Wine Harlan Ellison
Stranger in a Strange Land Robert A. Heinlein
Stuffing Harlan Ellison
Sturgeon is Alive and Well... Theodore Sturgeon
Suicide Theodore Sturgeon
Sun of China Liu Cixin
Symbiosis Kate Wilhelm
Take Care of Joey Theodore Sturgeon
Taking Care of God Liu Cixin
Tandy's Story Theodore Sturgeon
Tauf Aleph Physillis Gotlieb
Team of Rivals Doris Kearns Goodwin
Tekkonkinkreet: Black and White Taiyo Matsumoto
Tell Your Fortune Robert Bloch
Test to Destruction Keith Laummer
That Girl Who Knew What They Meant Theodore Sturgeon
The [Widget], the [Wadget], and Boff Theodore Sturgeon
The 10:00 Report is Brought to You By... Edward Bryant
The 3 Most Important Things in Life Harlan Ellison
The Absolutely Perfect Murder Miram Allen deFord
The Adventure of Black Peter Arthur Conan Doyle
The Adventure of Charles Augustus Milverton Arthur Conan Doyle
The Adventure of the Gloria Scott Arthur Conan Doyle
The Adventure of the Abbey Grange Arthur Conan Doyle
The Adventure of the Beryl Coronet Arthur Conan Doyle
The Adventure of the Blue Carbuncle Arthur Conan Doyle
The Adventure of the Cardboard Box Arthur Conan Doyle
The Adventure of the Copper Beeches Arthur Conan Doyle
The Adventure of the Crooked Man Arthur Conan Doyle
The Adventure of the Dancing Men Arthur Conan Doyle
The Adventure of the Empty House Arthur Conan Doyle
The Adventure of the Engineer's Thumb Arthur Conan Doyle
The Adventure of the Final Problem Arthur Conan Doyle
The Adventure of the Golden Pince-Nez Arthur Conan Doyle
The Adventure of the Greek Interpreter Arthur Conan Doyle
The Adventure of the Missing Three-Quarter Arthur Conan Doyle
The Adventure of the Musgrave Ritual Arthur Conan Doyle
The Adventure of the Naval Treaty Arthur Conan Doyle
The Adventure of the Noble Bachelor Arthur Conan Doyle
The Adventure of the Norwood Builder Arthur Conan Doyle
The Adventure of the Priory School Arthur Conan Doyle
The Adventure of the Reigate Squires Arthur Conan Doyle
The Adventure of the Resident Patient Arthur Conan Doyle
The Adventure of the Second Stain Arthur Conan Doyle
The Adventure of the Silver Blaze Arthur Conan Doyle
The Adventure of the Six Napoleons Arthur Conan Doyle
The Adventure of the Solitary Cyclist Arthur Conan Doyle
The Adventure of the Speckled Band Arthur Conan Doyle
The Adventure of the Stockbroker's Clerk Arthur Conan Doyle
The Adventure of the Yellow Face Arthur Conan Doyle
The Age of Gold Frederik Pohl
The Ajeri Diary Miram Allen deFord
The Aleph Jorge Luis Borges
The Aleph and Other Stories Jorge Luis Borges
The Annals of the Heechee Frederik Pohl
The Approach to Al-Mu'tasim Jorge Luis Borges
The Argentine Writer and Tradition Jorge Luis Borges
The Art of Computer Programming vol.1 Donald E. Knuth
The Art of Nausicaa of the Valley of the Wind Hayao Miyazaki
The Art of Persona 5 Shigenori Soejima
The Art of Space Ron Miller
The Avenger of Death Harlan Ellison
The Babylon Lottery Jorge Luis Borges
The Beast of Barsac Robert Bloch
The Belonging Kind John Shirley
The Belonging Kind William Gibson
The Big Hunger Walter M. Miller, Jr.
The Big Space Fuck Kurt Vonnegut, Jr.
The Big Time Fritz Leiber
The Black Cloud Fred Hoyle
The Bob Dylan Tambourine Software & Satori Support Services Consortium, Ltd. Michael Bishop
The Book of Skulls Robert Silverberg
The Bookmaking Habits of Select Species Ken Liu
The Boscombe Valley Mystery Arthur Conan Doyle
The Boulevard of Broken Dreams Harlan Ellison
The Boy Who Would Live Forever Frederik Pohl
The Brains of Rats Michael Blumlein
The Byrds Michael G. Coney
The Captive Jorge Luis Borges
The Cat Who Walks Through Walls Robert A. Heinlein
The Catcher in the Rye J. D. Salinger
The Cheese Stands Alone Harlan Ellison
The Children Miram Allen deFord
The Chrysalids John Wyndham
The Circle Liu Cixin
The Circular Ruins Jorge Luis Borges
The Cistern Ray Bradbury
The City of Silence Ma Boyong
The Classic Horror Stories H. P. Lovecraft
The Crackpots Harlan Ellison
The Crowd Ray Bradbury
The Dark Design Philip Jose Farmer
The Dark Forest Liu Cixin
The Daughter of the Tree Miram Allen deFord
The Day After the Day the Martians Came Frederik Pohl
The Day I Died Harlan Ellison
The Day of the Triffids John Wyndham
The Dead Man Jorge Luis Borges
The Death of Schillinger Tadeusz Borowski
The Deathbird Harlan Ellison
The Demolished Man Alfred Bester
The Diagnosis of Dr. Darqueangel Harlan Ellison
The Difference Engine Bruce Sterling
The Difference Engine William Gibson
The Discarded Harlan Ellison
The Dispossessed Ursula K. Le Guin
The Divine Invasion Philip K. Dick
The Doll-House James Cross
The Dragon on the Bookshelf Harlan Ellison
The Dragon on the Bookshelf Robert Silverberg
The Dreaming Jewels Theodore Sturgeon
The Dreams a Nightmare Dreams Harlan Ellison
The Dune Encyclopedia Dr. Willis E. McNelly
The Dwarf Ray Bradbury
The Earth Men Ray Bradbury
The Electric Kool-Aid Acid Test Tom Wolfe
The Emissary Ray Bradbury
The Encounter Kate Wilhelm
The End Jorge Luis Borges
The Evitable Conflict Isaac Asimov
The Evolution of Human Science Ted Chiang
The Executioner of the Malformed Children Harlan Ellison
The Extraordinary Voyages of Amelie Bertrand Joanna Russ
The Eyes of Heisenberg Frank Herbert
The Face of Helene Bournouw Harlan Ellison
The Fall of Hyperion Dan Simmons
The Fearful Sphere of Pascal Jorge Luis Borges
The Fellowship of the Ring J. R. R. Tolkien
The Few, the Proud Harlan Ellison
The Fish of Lijiang Chen Qiufan
The Five Orange Pips Arthur Conan Doyle
The Flower of Shazui Chen Qiufan
The Forces that Crush Harlan Ellison
The Forever War Joe Haldeman
The Form of the Sword Jorge Luis Borges
The Fountains of Paradise Arthur C. Clarke
The Function of Dream Sleep Harlan Ellison
The Funeral Kate Wilhelm
The Fusion Bomb Kate Wilhelm
The Garden of Forking Paths Jorge Luis Borges
The Gateway Asteroid Frederik Pohl
The Gateway Trip Frederik Pohl
The Gernsback Continum William Gibson
The Girl From Mars Robert Bloch
The Goddess in the Ice Harlan Ellison
The Godmakers Frank Herbert
The Gods Lie. Kaori Ozaki
The God's Script Jorge Luis Borges
The Gods Themselves Isaac Asimov
The Golden Helix Theodore Sturgeon
The Golden Man Philip K. Dick
The Great Gatsby F. Scott Fitzgerald
The Green Morning Ray Bradbury
The Guns of August Barbara W. Tuchman
The Handler Damon Knight
The Happy Breed John T. Sladek
The Heart of the Other Side George Gamow
The Henry Miller Dawn Patrol Philip Jose Farmer
The Hitchhiker's Guide to the Galaxy Douglas Adams
The Hobbit J. R. R. Tolkien
The Home Planet Frederik Pohl
The Hounds Kate Wilhelm
The Hour That Stretches Harlan Ellison
The House of Asterion Jorge Luis Borges
The House the Blakeneys Built Avram Davidson
The Immortal Jorge Luis Borges
The Incredible Voyage Tristan Jones
The Indian Spirit Guide Robert Bloch
The Infinity Box Kate Wilhelm
The Invasion Robert Willey
The January Offensive Tadeusz Borowski
The Jar Ray Bradbury
The Jigsaw Man Larry Niven
The Jungle Rot Kid on the Nod Philip Jose Farmer
The Korean War Max Hastings
The Lake Ray Bradbury
The Lake Was Full of Artificial Things Karen Joy Fowler
The Last Days of the Captain Kate Wilhelm
The Last Generation? Miram Allen deFord
The Lathe of Heaven Ursula K. Le Guin
The Leaser of Two Evils Philip Jose Farmer
The Library of Babel Jorge Luis Borges
The Life of Anybody Robert Sheckley
The Lingering Scent of Woodsmoke Harlan Ellison
The Literomancer Ken Liu
The Litigation Master and the Monkey King Ken Liu
The Living Demons Robert Bloch
The Locusts Ray Bradbury
The Long Dark Tea-Time of the Soul Douglas Adams
The Long Space Age Alexander MacDonald
The Long Years Ray Bradbury
The Longest Fall Liu Cixin
The Lost World Michael Crichton
The Lottery in Babylon Jorge Luis Borges
The Lucky Strike Kim Stanley Robinson
The Luggage Store Ray Bradbury
The Maker Jorge Luis Borges
The Malley System Miriam Allen deFord
The Man in the High Castle Philip K. Dick
The Man on the Threshold Jorge Luis Borges
The Man Upstairs Ray Bradbury
The Man Who Ended History: A Documentary Ken Liu
The Man Who Lost the Sea Theodore Sturgeon
The Man Who Rowed Christopher Columbus Ashore Harlan Ellison
The Man Who Sold the Moon Robert A. Heinlein
The Man Who Was Heavily into Revenge Harlan Ellison
The Man Who Went to the Moon-Twice Howard Rodman
The Man With English Horace L. Gold
The Man with the Package Tadeusz Borowski
The Man With the Twisted Lips Arthur Conan Doyle
The Man without a Planet Kate Wilhelm
The Manhattan Project Al Cimino
The March of Folly Barbara W. Tuchman
The Mark Gable Foundation Leo Szilard
The Martian Ray Bradbury
The Martian Chronicles Ray Bradbury
The Menace from Earth Robert A. Heinlein
The Merchants of Venus Frederik Pohl
The Micro-Age Liu Cixin
The Mile-Long Spaceship Kate Wilhelm
The Milk of Paradise James Tiptree, Jr.
The Million-Year Picnic Ray Bradbury
The Miracle of the Broom Closet W. Norbert
The Mirrors of Enigmas Jorge Luis Borges
The Moon is a Harsh Mistress Robert A. Heinlein
The Mountains of Sunset, the Mountains of Dawn Vonda N. McIntyre
The Mountebank Jorge Luis Borges
The Museum on Cyclops Avenue Harlan Ellison
The Musicians Ray Bradbury
The Naming of Names Ray Bradbury
The New Atlantis Robert Silverberg
The New Atlantis Ursula K. Le Guin
The New York Review of Bird Harlan Ellison
The Next in Line Ray Bradbury
The Night That All Time Broke Out Brian W. Aldiss
The Norton Book of Science Fiction Brian Attebery
The Norton Book of Science Fiction Ursula K. Le Guin
The October Country Ray Bradbury
The Off Season Ray Bradbury
The Old Man and the Sea Ernest Hemingway
The Old Ones Ray Bradbury
The Oldest Soldier Fritz Leiber
The Original Hitchhiker Radio Scripts Douglas Adams
The Original Illustrated Sherlock Holmes Arthur Conan Doyle
The Other Death Jorge Luis Borges
The Other Eye of Polyphemus Harlan Ellison
The Outcast of Redwall Brian Jacques
The Outpost Undiscovered by Tourists Harlan Ellison
The Oxford Book of English Verse Christopher Ricks
The Pale Silver Dollar of the Moon Pays Its Way and Makes Change vr.1 Harlan Ellison
The Pale Silver Dollar of the Moon Pays Its Way and Makes Change vr.2 Harlan Ellison
The Paper Menagerie Ken Liu
The Patterns of Drone Theodore Sturgeon
The People Who Walked On Tadeusz Borowski
The Perfect Match Ken Liu
The Peripheral William Gibson
The Phantom of the Sewers Philip Jose Farmer
The Place with No Name Harlan Ellison
The Plot Jorge Luis Borges
The Plot Is the Thing Robert Bloch
The Private War of Private Jacob Joe Haldeman
The Problem of the Sore Bridge-Among Others Philip Jose Farmer
The Proud Tower Barbara W. Tuchman
The Prowler in the City on the Edge of Forever Harlan Ellison
The Recognition J. G. Ballard
The Red Canary Kate Wilhelm
The Red-Headed League Arthur Conan Doyle
The Region Between Harlan Ellison
The Regular Ken Liu
The Resurgence of Miss Ankle-Strap Wedgie Harlan Ellison
The Return of the King J. R. R. Tolkien
The Right Stuff Tom Wolfe
The Rise of Endymion Dan Simmons
The Road Cormac McCarthy
The Roads Must Roll Robert A. Heilein
The Salmon of Doubt Douglas Adams
The Season of Babies Miram Allen deFord
The Secret Miracle Jorge Luis Borges
The Sect of Phoenix Jorge Luis Borges
The Settlers Ray Bradbury
The Sex Opposite Theodore Sturgeon
The Shape of the Sword Jorge Luis Borges
The Shore Ray Bradbury
The Silent Towns Ray Bradbury
The Silver Corridor Harlan Ellison
The Simple Way Clifford D. Simak
The Singers W. Grey Walter
The Sirens of Titan Kurt Vonnegut
The Skills of Xanadu Theodore Sturgeon
The Sky is Burning Harlan Ellison
The Small Assaassin Ray Bradbury
The Smiling Future Miram Allen deFord
The Sound and the Fury William Faulkner
The South Jorge Luis Borges
The Space Merchants C. M. Kornbluth
The Space Merchants Frederik Pohl
The Stars My Destination Alfred Bester
The Starseekers Frederik Pohl
The Start of the End of It All Carol Emshwiller
The Stochastic Man Robert Silverberg
The Summer Night Ray Bradbury
The Sun also Rises Ernest Hemingway
The Superior Sex Miram Allen deFord
The Supper Tadeusz Borowski
The Sycthe Ray Bradbury
The Taxpayer Ray Bradbury
The Tell-Tale Heart and Other Writings Edgar Allan Poe
The Tempest William Shakespeare
The Test Stand Lee Corey
The Test-Tube Creature, Afterward Joan Bernott
The Theologians Jorge Luis Borges
The Third Ear Curt Siodmak
The Third Expedition Ray Bradbury
The Three Stigmata of Palmer Eldritch Philip K. Dick
The Three-Body Problem Liu Cixin
The Tides of the Mind David Gelernter
The Time Piece Kate Wilhelm
The Transit of Venus Miram Allen deFord
The Transmigration of Timothy Archer Philip K. Dick
The Tree Lord of Imeten Tom Purdom
The Trial Franz Kafka
The Two Kings and the Two Labyrinths Jorge Luis Borges
The Two Towers J. R. R. Tolkien
The Ultimate Hitchhiker's Guide Douglas Adams
The Universe of Robert Blake Harlan Ellison
The Unspeakable Betrothal Robert Bloch
The Very Last Day of a Good Woman Harlan Ellison
The View from the Stars Walter M. Miller, Jr.
The Village Kate Wilhelm
The Visit Frederik Pohl
The Voice of the Sonar in My Veriform Appendix Philip Jose Farmer
The Volcano Philip Jose Farmer
The Wages of Humanity Liu Cixin
The Waiting Jorge Luis Borges
The Wall and the Books Jorge Luis Borges
The Wandering Earth Liu Cixin
The War at Home Lewis Shiner
The Warlord of Saturn's Moon Eleanor Aranason
The Watchers Ray Bradbury
The Watchful Poker Chip of H. Matisse Ray Bradbury
The Waves Ken Liu
The Westing Game Ellen Raskin
The Whimper of Whipped Dogs Harlan Ellison
The Will Walter M. Miller, Jr.
The Wind Ray Bradbury
The Wind Beyond the Mountains Harlan Ellison
The Windup Girl Paolo Bacigalupi
The Wine Has Been Left Open Too Long and the Memory Has Gone Flat Harlan Ellison
The Winter Flies Fritz Leiber
The Winter Market William Gibson
The Witness Jorge Luis Borges
The Women Men Don't See James Tiptree, Jr.
The Wonderful Death of Dudley Stone Ray Bradbury
The Word for World is Forrest Ursula K. Le Guin
The World Inside Robert Silverberg
The World of Professor Layton Jun Suzuki
The World of Stone Tadeusz Borowski
The Writing of the God Jorge Luis Borges
The Year of the Jackpot Robert A. Heinlein
The Year of the Rat Chen Qiufan
The Yellow Rose Jorge Luis Borges
The Zahir Jorge Luis Borges
The Zimmermann Telegram Barbara W. Tuchman
Theme of the Traitor and Hero Jorge Luis Borges
There Was an Old Woman Ray Bradbury
There Will Come Soft Rains Ray Bradbury
They Shall Have Stars James Blish
Things Lost Thomas M. Disch
This Immortal Roger Zelazny
This Way for the Gas, Ladies and Gentlemen Tadeusz Borowski
Thorns Robert Silverberg
Thousand Cranes Yasunari Kawabata
Three Versions of Judas Jorge Luis Borges
Throwback Miram Allen deFord
Thunder and Roses Theodore Sturgeon
Time Travel for Pedestrians Ray Nelson
Tiny Ally Harlan Ellison
Tissue James Sallis
Tlon, Uqbar, Orbis Teritus Jorge Luis Borges
To Be Continued Robert Silverberg
To Explain to Mrs. Thompson Phillip Latham
To Here and the Easel Theodore Sturgeon
To Kill a Mockingbird Harper Lee
To Open the Sky Robert Silverberg
Toenails Jorge Luis Borges
Tongtong's Summer Xia Jia
Totenbuch A. Parra (y Figuerado)
Touched With Fire Ray Bradbury
Tower of Babylon Ted Chiang
Tower of Glass Robert Silverberg
Tracking Level Harlan Ellison
Transcending Destiny Harlan Ellison
Treasure Island Robert Lewis Stevenson
Trigun Omnibus Yasuhiro Nightow
Triss Brian Jacques
Trouble With Ants Clifford D. Simak
Try and Change the Past Fritz Leiber
Twink Theodore Sturgeon
Ubik Philip K. Dick
Unaccompanied Sonata Orson Scott Card
Uncle Einar Ray Bradbury
Uncle Fremmis Theodore Sturgeon
Underground Robert Bloch
Understand Ted Chiang
Unlocking the Air Ursula K. Le Guin
Usher II Ray Bradbury
Valerie Harlan Ellison
Valery as Symbol Jorge Luis Borges
VALIS Philip K. Dick
Vaster than Empires and More Slow Ursula K. Le Guin
Venus Plus X Theodore Sturgeon
Vietnam: An Epic Tragedy, 1945-1975 Max Hastings
Virtual Light William Gibson
Visionary Harlan Ellison
Walden; or, Life in the Woods Henry David Thoreau
Wandering Island vol.1 Kenji Tsuruta
Wandering Island vol.2 Kenji Tsuruta
Wanted in Surgery Harlan Ellison
Watchmen Alan Moore
Water Is for Washing Robert A. Heinlein
Watership Down Richard Adams
Way in the Middle of the Air Ray Bradbury
Way Station Clifford D. Simak
We Yevgeny Zamyatin
We See Things Differently Bruce Sterling
Web of the City Harlan Ellison
What Happened to Auguste Clarot? Larry Eisenberg
What I Did on My Vaction This Summer by Little Bobby Hirschhorn, Age 27 Harlan Ellison
What's It Like Out There? Edmond Hamilton
When Auld's Acquaintance is Forgot Harlan Ellison
When I was a Hired Gun Harlan Ellison
When I Was Miss Dow Sonya Dorman
When it Changed Joanna Russ
When the Bentfin Boomer Boys on Old New Alabama Richard A. Lupoff
When the Change-Winds Blow Fritz Leiber
Where Have You Been, Billy Boy, Billy Boy? Kate Wilhelm
Where I Shall Dwell in the Next World Harlan Ellison
Where Late the Sweet Birds Sang Kate Wilhelm
With a Finger in My I David Gerrold
With Her Eyes Liu Cixin
With Virgin Oddum at the East Pole Harlan Ellison
Working with the Little People Harlan Ellison
Would You Do It for a Penny Harlan Ellison
Xenogenesis Miriam Allen deFord
Yeager Chuck Yeager
Yeager Leo Janos
Ylla Ray Bradbury
You Triflin' Skunk Walter M. Miller, Jr.
Zero Gee Ben Bova
Zero History William Gibson
================================================
FILE: tests/data/books.tsv
================================================
1984 science fiction 1950 328
2001: A Space Odyssey science fiction 1968 221
20th Century Boys vol.1 science fiction 2018 413
20th Century Boys vol.2 science fiction 2018 412
20th Century Boys vol.3 science fiction 2019 410
20th Century Boys vol.4 science fiction 2019 416
20th Century Boys vol.5 science fiction 2019 422
20th Century Boys vol.6 science fiction 2019 456
A Canticle for Leibowitz science fiction 1959 338
A Case of Conscience science fiction 1958 188
A Clash of Cymbals science fiction 1959 199
A Clockwork Orange science fiction 1962 139
A Farewell to Arms american lit 1929 332
A Life for the Stars science fiction 1962 147
A Scanner Darkly science fiction 1977 217
A Time of Changes science fiction 1975 205
A Tour of C++ 2nd textbook 2018 238
Absalom, Absalom! american lit 1936 303
Again, Dangerous Visions science fiction 1972 830
Akira vol.1 science fiction 2010 363
Akira vol.2 science fiction 2010 301
Akira vol.3 science fiction 2010 282
Akira vol.4 science fiction 2010 394
Akira vol.5 science fiction 2011 413
Akira vol.6 science fiction 2011 434
Algorithms 4th textbook 2011 959
All Tomorrow's Parties science fiction 1999 339
And Chaos Died science fiction 1970 189
Angry Candy science fiction 1988 324
Animal Farm british lit 1956 139
Approaching Oblivion science fiction 1974 164
Army of None history 2018 436
Battle for the Mind informative 1954 350
Beowulf fantasy 1994 92
Beyond the Blue Event Horizon science fiction 1980 309
Bible and Sword history 1984 346
Blame! vol.1 science fiction 2016 348
Blame! vol.2 science fiction 2016 374
Blame! vol.3 science fiction 2017 352
Blame! vol.4 science fiction 2017 367
Blame! vol.5 science fiction 2017 334
Blame! vol.6 science fiction 2017 326
Blue Spring fiction 2004 213
Brain Wave science fiction 1954 166
Brave New World science fiction 1932 259
Burning Chrome science fiction 1986 191
C Primer Plus 5th textbook 2005 959
C++ Primer 5th textbook 2013 938
Capitalism Without Capital economics 2018 278
Captain Harlock: The Classic Collection vol.1 science fiction 2018 396
Captain Harlock: The Classic Collection vol.2 science fiction 2018 397
Captain Harlock: The Classic Collection vol.3 science fiction 2019 392
Catch-22 american lit 1955 453
Caviar science fiction 1955 182
Changewar science fiction 1983 198
Chapterhouse: Dune science fiction 1985 436
Childhood's End science fiction 1953 212
Children of Dune science fiction 1976 408
Children of the Sea vol.1 fiction 2013 316
Children of the Sea vol.2 fiction 2013 315
Children of the Sea vol.3 fiction 2013 334
Children of the Sea vol.4 fiction 2013 324
Children of the Sea vol.5 fiction 2013 329
City science fiction 1952 267
Colossus history 2006 462
Conversations With Jorge Luis Borges interviews 1968 144
Count Zero science fiction 1986 246
Crome Yellow british lit 1921 174
Dandelion Wine american lit 1957 239
Dangerous Visions science fiction 1967 598
Death and the Penguin mystery 1996 228
Deathbird Stories science fiction 1975 347
Death's End science fiction 2016 604
Destined for War history 2017 364
Dirk Gently's Holistic Detective Agency science fiction 1987 306
Distrust That Particular Flavor essays 2012 255
Do Androids Dream of Electric Sheep? science fiction 1968 244
Doctor Zhivago east euro lit 1957 456
Don Quixote adventure 1950 940
Double Star science fiction 1956 243
Downward to the Earth science fiction 1970 181
Dr. Bloodmoney science fiction 1965 298
Dune science fiction 1965 883
Dune Messiah science fiction 1969 279
Dying Inside science fiction 1972 200
Earthman, Come Home science fiction 1955 256
Earthman, Go Home! science fiction 1962 191
Emanon vol.1: Memories of Emanon science fiction 2019 190
Emanon vol.2: Emanon Wanderer pt.1 science fiction 2019 213
Emanon vol.3: Emanon Wanderer pt.2 science fiction 2019 233
Empire Star science fiction 1966 102
Ender's Game science fiction 1977 324
Endless Frontier history 1997 527
Endymion science fiction 1995 563
Eniac history 1999 262
Explorers of Space science fiction 1975 253
Fahrenheit 451 science fiction 1953 190
Fault-Tolerant Computer System Designs textbook 1996 550
Fiasco science fiction 1987 322
Ficciones fiction 1956 174
Flow My Tears, the Policeman Said science fiction 1974 231
Flowers for Algernon science fiction 1966 216
For Whom the Bell Tolls american lit 1940 507
Forward the Foundation science fiction 1993 435
Foundation science fiction 1951 296
Foundation and Earth science fiction 1986 494
Foundation and Empire science fiction 1952 282
Foundation's Edge science fiction 1982 426
Gateway science fiction 1977 313
Ghost in the Shell science fiction 2009 348
Ghost in the Shell vol.2: Man-Machine Interface science fiction 2010 306
Ghost in the Shell vol.1.5: Human-Error Processor science fiction 2007 176
Giganto Maxia fantasy 2016 232
God Emperor of Dune science fiction 1981 423
Hamlet tragedy 1599 287
Hawksbill Station science fiction 1968 185
Heart of Darkness east euro lit 1899 166
Heechee Rendezvous science fiction 1984 331
Heretics of Dune science fiction 1984 480
Houston, Houston, Do You Read? science fiction 1976 92
Hyperion science fiction 1989 482
I Will Fear No Evil science fiction 1970 512
I, Robot science fiction 1950 192
Ichi-F nonfiction 2017 550
Idoru science fiction 1996 383
Inferno: The World at War, 1939-1945 informative 2012 729
Into the Wild nonfiction 1996 207
Into Thin Air nonfiction 1997 404
Invisible Man american lit 1952 581
Invisible Planets science fiction 2016 393
Julius Caesar tragedy 1599 209
Jurassic Park science fiction 1990 399
Labyrinths fiction 2007 256
Leadership in Turbulent Times history 2018 473
Life, the Universe and Everything science fiction 1982 162
Lord of Light science fiction 1967 296
Lord of the Flies british lit 1954 208
Love Ain't Nothing but Sex Misspelled science fiction 1968 380
Madame Curie history 1939 390
Man Plus science fiction 1976 277
Martin the Warrior fantasy 1994 376
Master and Commander adventure 1970 408
Mattimeo fantasy 1990 432
Mona Lisa Overdrive science fiction 1988 308
Monster vol.1 thriller 2014 422
Monster vol.2 thriller 2014 398
Monster vol.3 thriller 2015 430
Monster vol.4 thriller 2015 412
Monster vol.5 thriller 2015 404
Monster vol.6 thriller 2015 400
Monster vol.7 thriller 2016 410
Monster vol.8 thriller 2016 424
Monster vol.9 thriller 2016 470
More Than Human science fiction 1953 188
Nausicaa of the Valley of the Wind vol.1 fantasy 2012 548
Nausicaa of the Valley of the Wind vol.2 fantasy 2012 533
Nebula Winners Fifteen science fiction 1981 223
Neuromancer science fiction 1984 271
Nightfall science fiction 1990 339
Nijigagara Holograph fiction 2015 200
Nova science fiction 1968 215
One Day in the Life of Ivan Denisovich east euro lit 1962 210
Operating Systems in Depth textbook 2011 444
Overlord history 1984 462
Paingod and Other Delusions science fiction 1965 157
Pattern Recognition science fiction 2003 356
Permanent Record history 2019 340
Persona 3: Official Design Works art 2006 141
Persona 4 Arena: Official Design Works art 2012 176
Persona 4: Official Design Works art 2008 191
Picnic on Paradise science fiction 1968 157
Planetes vol.1 science fiction 2015 524
Planetes vol.2 science fiction 2016 524
Player Piano science fiction 1952 320
Prelude to Foundation science fiction 1988 434
Presidents of War history 2018 740
Queen Emeraldas vol.1 science fiction 2016 415
Queen Emeraldas vol.2 science fiction 2017 423
Radio Free Albemuth science fiction 1985 214
Redwall fantasy 1986 333
Rendezvous with Rama science fiction 1973 243
Riders of the Purple Wage science fiction 1992 216
Ringworld science fiction 1970 288
Riverworld and Other Stories science fiction 1979 264
Roadside Picnic science fiction 1972 209
Second Foundation science fiction 1953 279
Selected Poems american lit 1954 114
Selected Stories science fiction 2000 439
Seraphim: 266613336 Wings science fiction 2015 268
Shatterday science fiction 1980 332
Shin Megami Tensei 4: Official Artworks art 2013 208
Sir Gawain and the Green Knight fantasy 1975 212
Skunk Works history 1994 372
Slippage science fiction 1997 359
So Long, and Thanks for All the Fish science fiction 1984 214
Solanin fiction 2008 432
Solaris science fiction 1961 223
Some Assembly Required informative 2012 611
Somerset Dreams and Other Fictions science fiction 1979 174
Souls fantasy 1982 84
Spook Country science fiction 2007 480
Stalingrad history 1998 493
Stalking the Nightmare science fiction 1982 301
Starship Troopers science fiction 1959 335
Stillwell and the American Experience in China 1911-1945 history 1971 794
Stories of Your Life and Others science fiction 2002 281
Strange Gifts science fiction 1975 191
Strange Wine science fiction 1979 316
Stranger in a Strange Land science fiction 1961 438
Sturgeon is Alive and Well... science fiction 1971 207
Team of Rivals history 2005 757
Tekkonkinkreet: Black and White fiction 2007 614
The Aleph and Other Stories fiction 1998 210
The Annals of the Heechee science fiction 1987 341
The Art of Computer Programming vol.1 textbook 1997 652
The Art of Nausicaa of the Valley of the Wind art 2007 207
The Art of Persona 5 art 2017 447
The Art of Space art 2014 224
The Big Time science fiction 1958 184
The Book of Skulls science fiction 1972 222
The Boy Who Would Live Forever science fiction 2004 452
The Cat Who Walks Through Walls science fiction 1985 388
The Catcher in the Rye american lit 1945 214
The Chrysalids science fiction 1955 200
The Classic Horror Stories horror 2013 487
The Dark Forest science fiction 2015 512
The Day of the Triffids science fiction 1951 191
The Demolished Man science fiction 1954 175
The Difference Engine science fiction 1991 429
The Dispossessed science fiction 1974 311
The Divine Invasion science fiction 1981 260
The Dreaming Jewels science fiction 1950 174
The Dune Encyclopedia encyclopedia 1985 526
The Electric Kool-Aid Acid Test informative 1968 416
The Expert Dreamers science fiction 1962 248
The Eyes of Heisenberg science fiction 1966 158
The Fall of Hyperion science fiction 1990 518
The Fellowship of the Ring fantasy 1954 458
The Forever War science fiction 1974 254
The Fountains of Paradise science fiction 1980 305
The Gateway Trip science fiction 1990 245
The Godmakers science fiction 1972 221
The Gods Lie. fiction 2016 216
The Gods Themselves science fiction 1972 288
The Great Gatsby american lit 1952 180
The Guns of August history 1962 606
The Hitchhiker's Guide to the Galaxy science fiction 1979 215
The Hobbit fantasy 1937 305
The Incredible Voyage nonfiction 1977 390
The Infinity Box science fiction 1975 272
The Korean War history 1987 389
The Lathe of Heaven science fiction 1971 175
The Living Demons horror 1967 156
The Long Dark Tea-Time of the Soul science fiction 1988 307
The Long Space Age history 2017 258
The Lost World science fiction 1995 430
The Man in the High Castle science fiction 1962 259
The Man Who Sold the Moon science fiction 1951 267
The Manhattan Project history 2016 187
The March of Folly history 1984 447
The Martian Chronicles science fiction 1950 181
The Menace from Earth science fiction 1962 189
The Mile-Long Spaceship science fiction 1963 160
The Moon is a Harsh Mistress science fiction 1966 382
The New Atlantis science fiction 1975 182
The Norton Book of Science Fiction science fiction 1993 861
The October Country science fiction 1956 306
The Old Man and the Sea american lit 1952 127
The Original Hitchhiker Radio Scripts science fiction 1985 248
The Original Illustrated Sherlock Holmes mystery 1976 636
The Outcast of Redwall fantasy 1995 367
The Oxford Book of English Verse british lit 1999 668
The Paper Menagerie science fiction 2016 450
The Peripheral science fiction 2014 486
The Proud Tower history 1966 615
The Return of the King fantasy 1955 466
The Right Stuff nonfiction 1970 352
The Rise of Endymion science fiction 1997 709
The Road thriller 2006 287
The Salmon of Doubt fiction 2002 299
The Sirens of Titan science fiction 1959 224
The Sound and the Fury american lit 1929 326
The Space Merchants science fiction 1953 216
The Stars My Destination science fiction 1956 234
The Stochastic Man science fiction 1976 240
The Sun also Rises american lit 1926 251
The Tell-Tale Heart and Other Writings horror 1982 419
The Tempest tragedy 1599 177
The Third Ear science fiction 1971 254
The Three Stigmata of Palmer Eldritch science fiction 1964 230
The Three-Body Problem science fiction 2014 399
The Tides of the Mind nonfiction 2016 267
The Transmigration of Timothy Archer science fiction 1991 255
The Tree Lord of Imeten science fiction 1966 152
The Trial east euro lit 1925 271
The Two Towers fantasy 1954 398
The Ultimate Hitchhiker's Guide science fiction 2005 815
The View from the Stars science fiction 1965 192
The Wandering Earth science fiction 2013 478
The Westing Game mystery 1978 182
The Windup Girl science fiction 2015 466
The World Inside science fiction 1970 167
The World of Professor Layton art 2015 191
The Zimmermann Telegram history 1966 225
They Shall Have Stars science fiction 1956 181
This Immortal science fiction 1966 184
This Way for the Gas, Ladies and Gentlemen east euro lit 1959 180
Thorns science fiction 1967 222
Thousand Cranes asian lit 1965 144
To Kill a Mockingbird american lit 1960 376
To Open the Sky science fiction 1967 222
Tower of Glass science fiction 1971 184
Treasure Island adventure 1882 202
Trigun Omnibus science fiction 2013 691
Triss fantasy 2002 389
Ubik science fiction 1969 216
VALIS science fiction 1991 241
Venus Plus X science fiction 1960 160
Vietnam: An Epic Tragedy, 1945-1975 history 2018 857
Virtual Light science fiction 1993 352
Walden; or, Life in the Woods essays 1854 216
Wandering Island vol.1 fiction 2016 198
Wandering Island vol.2 fiction 2018 190
Watchmen science fiction 1986 414
Watership Down fantasy 1973 478
Way Station science fiction 1963 190
We science fiction 1924 226
Web of the City thriller 1958 284
What's It Like Out There? science fiction 1974 320
Where Late the Sweet Birds Sang science fiction 1976 207
Xenogenesis science fiction 1969 231
Yeager history 1985 331
Zero History science fiction 2010 529
================================================
FILE: tests/data/collected.tsv
================================================
!!!The!!Teddy!Crazy!!Show!!! Stalking the Nightmare 14
(Learning About) Machine Sex The Norton Book of Science Fiction 16
...the World, as we Know 't The Norton Book of Science Fiction 16
2004, or Thereabouts The Norton Book of Science Fiction 5
A Biography of Tadeo Isidoro Cruz (1829-1874) The Aleph and Other Stories 4
A Brief History of the Trans-Pacific Tunnel The Paper Menagerie and Other Stories 19
A Case of Identity The Original Illustrated Sherlock Holmes 12
A Day at Harmenz This Way for the Gas, Ladies and Gentlemen 32
A Deskful of Girls Changewar 44
A Dialog About A Dialog The Aleph and Other Stories 1
A Dialog Between Dead Men The Aleph and Other Stories 3
A Feast of Demons The Expert Dreamers 26
A Few Things I Know About While Away The Norton Book of Science Fiction 13
A Hundred Ghosts Parade Tonight Invisible Planets 20
A is for Automation The Mile-Long Spaceship 17
A Midwinter's Tale The Norton Book of Science Fiction 13
A Momentary Taste of Being The New Atlantis 174
A Mouse in the Walls of the Global Village Again, Dangerous Visions 15
A New Refutation of Time Labyrinths 20
A Note on (toward) Bernard Shaw Labyrinths 4
A Path Through the Darkness Love Ain't Nothing but Sex Misspelled 14
A Prayer for No One's Enemies Love Ain't Nothing but Sex Misspelled 21
A Problem Labyrinths 2
A Problem The Aleph and Other Stories 2
A Scandal in Bohemia The Original Illustrated Sherlock Holmes 15
A Toy for Juliette Dangerous Visions 15
A True Story This Way for the Gas, Ladies and Gentlemen 4
A Visit This Way for the Gas, Ladies and Gentlemen 3
A Way of Thinking Selected Stories 29
Adrift Just Off the Islets of Langerhans: Latitude 38o54'N, Longitude 77o00'13W Deathbird Stories 40
Adrift on the Policy Level The Expert Dreamers 24
Aesop City 42
After the Days of Dead-Eye 'Dee The Norton Book of Science Fiction 11
All in Good Time Xenogensis 10
All the Birds Come Home to Roost Shatterday 18
All the Flavors The Paper Menagerie and Other Stories 89
All the Lies Lies That Are My Life Shatterday 58
All The People Strange Gifts 12
All the Sound of Fear Earthman, Go Home! 12
Along the Scenic Route Deathbird Stories 14
Alpha Ralpha Boulevard The Norton Book of Science Fiction 25
Amateur in Chancery The Expert Dreamers 18
America The Norton Book of Science Fiction 24
An Advanced Readers' Picture Book of Comparative Cognition The Paper Menagerie and Other Stories 15
An Examination of the Work of Herbert Quain Ficciones 6
And the Angels Sing The Norton Book of Science Fiction 17
And the Sea Like Mirrors Again, Dangerous Visions 20
Andover and the Android The Mile-Long Spaceship 13
Anybody Else Like Me? The View from the Stars 17
Anywhere But Here, With Anybody But You Slippage 8
April Fools' Day Forever The Infinity Box 58
Argumentum Ornithologicum The Aleph and Other Stories 1
As Simple As That The Norton Book of Science Fiction 11
At the End of the Orbit The Expert Dreamers 20
At the Mouse Circus Deathbird Stories 10
Aunt Parnetta's Electric Blisters The Norton Book of Science Fiction 5
Auschwitz, Our Home (A Letter) This Way for the Gas, Ladies and Gentlemen 45
Auto-De-Fe Dangerous Visions 10
Avatars of the Tortoise Labyrinths 7
Averroes' Search Labyrinths 8
Averroes' Search The Aleph and Other Stories 10
Aye, and Gomorrah... Dangerous Visions 14
Balanced Ecology The Norton Book of Science Fiction 17
Basilisk Deathbird Stories 22
Battle Without Banners Love Ain't Nothing but Sex Misspelled 14
Battlefield Earthman, Go Home! 12
Beachhead Explorers of Space 25
Beauty's Beast The Living Demons 17
Bed Sheets are White Again, Dangerous Visions 8
Bettyann Strange Gifts 44
Bianca's Hands Selected Stories 9
Big Joe and the Nth Generation The View from the Stars 19
Blabbermouth Caviar 28
Black Bargain The Living Demons 16
Blank? Stalking the Nightmare 8
Bleeding Stones Deathbird Stories 8
Blind Bird, Blind Bird, Go Away From Me! Love Ain't Nothing but Sex Misspelled 22
Blood Bank The View from the Stars 46
Blot Again, Dangerous Visions 15
Blowups Happen The Man Who Sold the Moon 54
Borges and I Labyrinths 2
Borges and I The Aleph and Other Stories 2
Bounty Again, Dangerous Visions 7
Brass and Gold (or Horse and Zeppelin in Beverly Hills) Riverworld and Other Stories 18
Bright Eyes Paingod and Other Delusions 12
Bright Segment Caviar 28
Bright Segment Selected Stories 25
Broken Glass Angry Candy 12
Brownshoes Sturgeon is Alive and Well... 12
Burning Chrome Burning Chrome 23
By His Bootstraps The Menace from Earth 49
Call Girl Invisible Planets 12
Camps Nebula Winners Fifteen 29
Carcinoma Angels Dangerous Visions 15
Catch That Rabbit I, Robot 15
Catman Approaching Oblivion 34
Census City 35
Chain Reaction The Expert Dreamers 16
Chained to the Fast Lane in the Red Queen's Race Angry Candy 16
Chatting with Anubis Slippage 8
Ching Witch! Again, Dangerous Visions 24
Christ, Old Student in a New School Again, Dangerous Visions 9
Chuck Berry, Won't You Please Come Home Again, Dangerous Visions 12
City City 34
Cold Friend Approaching Oblivion 11
Collecting Team Explorers of Space 18
Columbus Was a Dope The Menace from Earth 4
Come to the Party The Collected Stories of Frank Herbert 21
Comes Now the Power The Norton Book of Science Fiction 5
Commuter's Problem Earthman, Go Home! 22
Corpse Deathbird Stories 12
Count the Clock That Tells the Time Shatterday 22
Covered Mirrors The Aleph and Other Stories 2
Crate Sturgeon is Alive and Well... 14
Crazy as a Soup Sandwich Slippage 48
Croatoan Strange Wine 18
Crucifixus Etiam The View from the Stars 18
Curse 5.0 The Wandering Earth 23
Damnation Morning Changewar 19
Danger-Human! Strange Gifts 21
Daniel White for the Greater Good Love Ain't Nothing but Sex Misspelled 13
Darkness Upon the Face of the Deep Slippage 16
Day Million The Norton Book of Science Fiction 5
Deal From the Bottom Earthman, Go Home! 7
Death and the Compass Ficciones 14
Death and the Compass Labyrinths 12
Deeper than the Darkness Paingod and Other Delusions 20
Delia Elena San Marco The Aleph and Other Stories 1
Delusion for a Dragon Slayer Deathbird Stories 18
Deutsches Requiem Labyrinths 7
Deutsches Requiem The Aleph and Other Stories 7
Devourer The Wandering Earth 46
Distant Signals The Norton Book of Science Fiction 13
Division by Zero Stories of Your Life and Others 20
Django Shatterday 12
Djinn, No Chaser Stalking the Nightmare 22
Dogfight Burning Chrome 24
Do-It-Yourself Earthman, Go Home! 14
Dreamtigers The Aleph and Other Stories 1
Dumb Waiter The View from the Stars 34
Each an Explorer Explorers of Space 18
Ecowarewness Approaching Oblivion 2
Eidolons Angry Candy 18
Elbow Room The Norton Book of Science Fiction 15
Elegy Labyrinths 2
Elouise and the Doctors of the Planet Pergamon Again, Dangerous Visions 19
Emissary from Hamelin Strange Wine 13
Emma Zunz Labyrinths 6
Emma Zunz The Aleph and Other Stories 7
Empire of the Sun Again, Dangerous Visions 8
Encounter With A Hick Dangerous Visions 7
Enemy Mine Nebula Winners Fifteen 64
Epilogue City 13
Epiphany for Aliens Again, Dangerous Visions 11
Ernest and the Machine God Deathbird Stories 20
Erotophobia Approaching Oblivion 7
Ersatz Dangerous Visions 9
Escape! I, Robot 21
Escapegoat Angry Candy 4
Eutopia Dangerous Visions 23
Evensong Dangerous Visions 10
Everything and Nothing Labyrinths 3
Everything and Nothing The Aleph and Other Stories 3
Evidence I, Robot 23
Exploration Team Explorers of Space 58
Exposures The Norton Book of Science Fiction 12
Eye of the Beholder Again, Dangerous Visions 15
Faith of our Fathers Dangerous Visions 38
Fear is a Cold Black The Mile-Long Spaceship 25
Feather Tigers The Norton Book of Science Fiction 7
Featherbed on Chlyntha Xenogensis 17
Final Trophy Stalking the Nightmare 12
Flies Dangerous Visions 13
Flop Sweat Shatterday 18
Folding Beijing Invisible Planets 44
Footsteps Angry Candy 14
For the Sake of Grace The Norton Book of Science Fiction 20
For Value Received Again, Dangerous Visions 18
Fragments of a Hologram Rose Burning Chrome 7
From A to Z, In The Chocolate Alphabet Strange Wine 24
From the Government Printing Office Dangerous Visions 9
Frozen Journey The Norton Book of Science Fiction 16
Funes the Memorious Labyrinths 8
Funes the Memorious Ficciones 10
G. B. K.-A Many-Flavored Bird Love Ain't Nothing but Sex Misspelled 11
Gather Blue Roses The Norton Book of Science Fiction 5
Gathi Xenogensis 7
Getting Along Again, Dangerous Visions 32
Ghost of a Chance Caviar 20
giANTS Nebula Winners Fifteen 20
Gift from the Stars The Mile-Long Spaceship 17
Gnomebody Earthman, Go Home! 7
Go Toward the Light Slippage 10
Go, Go, Go, Said the Bird Dangerous Visions 9
Goldfish Bowl The Menace from Earth 29
Gonna Roll the Bones Dangerous Visions 26
Good Hunting The Paper Menagerie and Other Stories 23
Good News from the Vatican The Norton Book of Science Fiction 8
Gopher in the Gilly Stalking the Nightmare 6
Grail Stalking the Nightmare 28
Grave of the Fireflies Invisible Planets 18
Gutter Gang Web of the City 25
Hadj Earthman, Go Home! 5
Half-Life The Norton Book of Science Fiction 14
Harry the Hare Again, Dangerous Visions 5
Heavyplanet The Expert Dreamers 13
Heechee Treasures The Gateway Trip 19
Hell Is the Absence of God Stories of Your Life and Others 32
High Weir The Norton Book of Science Fiction 18
Hindsight: 480 Seconds Approaching Oblivion 6
Hinterlands Burning Chrome 22
His Vegetable The Norton Book of Science Fiction 5
Hitler Painted Roses Strange Wine 18
Hobbies City 28
Homecoming The October Country 17
Homelanding The Norton Book of Science Fiction 3
How Beautiful with Banners The Norton Book of Science Fiction 9
How's the Night Life on Cassalda? Shatterday 18
Huddling Place City 23
Humpty Dumpty had a Great Fall Strange Gifts 27
I Curse the Lesson and Bless the Knowledge Love Ain't Nothing but Sex Misspelled 14
I, Dreamer The View from the Stars 12
Ibn-Hakam al-Bokhari, Murdered in His Labyrinth The Aleph and Other Stories 10
If All Men Were Brothers, Would You Let One Marry Your Sister? Dangerous Visions 49
I'm Looking for Kadak Approaching Oblivion 27
In Fear of K Strange Wine 16
In Lonely Islands Earthman, Go Home! 5
In Memoriam, J. F. K. The Aleph and Other Stories 1
In re Glover Again, Dangerous Visions 13
In the Barn Again, Dangerous Visions 37
In the Core The Gateway Trip 9
In the Fourth Year of the War Shatterday 14
Incident in Moderan Dangerous Visions 6
Inferno, I, 32 Labyrinths 1
Inferno, I, 32 The Aleph and Other Stories 1
Interim The Martian Chronicles 1
Interlocking Pieces The Norton Book of Science Fiction 6
Invaders The Norton Book of Science Fiction 20
Invasion Footnote Stalking the Nightmare 8
Invisible Planets Invisible Planets 20
It Selected Stories 25
It was Nothing-Really Sturgeon is Alive and Well... 15
It's You! Sturgeon is Alive and Well... 10
J. C. on the Dude Ranch Riverworld and Other Stories 16
Jack-in-the-Box The October Country 20
Jane Doe #112 Slippage 12
Jeffty is Five Shatterday 28
Jenny with Wings The Mile-Long Spaceship 13
Johnny Mnemonic Burning Chrome 22
Jorry's Gap Sturgeon is Alive and Well... 12
Judas Dangerous Visions 12
Jupiter Five Explorers of Space 38
Kafka and His Precursors Labyrinths 3
Keyboard Slippage 7
Killdozer! Selected Stories 70
Killing Bernstein Strange Wine 18
King of the Hill Again, Dangerous Visions 20
Kirinyaga The Norton Book of Science Fiction 17
Kiss of Fire Approaching Oblivion 11
Knights to Move Changewar 13
Knox Approaching Oblivion 15
Kyrie Explorers of Space 15
Kyrie The Norton Book of Science Fiction 10
Ladies and Gentlemen, This Is Your Crisis Somerset Dreams and Other Fictions 16
Lamia Mutable Again, Dangerous Visions 10
Land of the Great Horses Dangerous Visions 12
Last Train to Kankakee Again, Dangerous Visions 11
Laugh Track Angry Candy 22
Lenny The Expert Dreamers 18
Let There Be Light The Man Who Sold the Moon 19
Liar! I, Robot 16
Life in Our Time The Living Demons 9
Life-Line The Man Who Sold the Moon 22
Liking What You See: A Documentary Stories of Your Life and Others 38
Little Lost Robot I, Robot 26
Lollipop and the Tar Baby The Norton Book of Science Fiction 19
Lonley Women Are the Vessels of Time Strange Wine 8
Looking for Company The Gateway Trip 13
Lord Randy, My Son Dangerous Visions 18
Lucy Comes To Stay The Living Demons 6
Making It All the Way into the Future on Gaxton Falls of the Red Planet The Norton Book of Science Fiction 4
Man of Letters The Infinity Box 19
Martin Fierro The Aleph and Other Stories 2
Mathoms from the Time Closet Again, Dangerous Visions 12
Mealtime Earthman, Go Home! 11
Medusa Caviar 26
Mefisto in Onyx Slippage 46
Microcosmic God Caviar 34
Midnight in the Sunken Cathedral Slippage 10
Midnight News The Norton Book of Science Fiction 11
Mom Strange Wine 22
Mona at Her Windows Love Ain't Nothing but Sex Misspelled 5
Monitored Dreams & Strategic Cremations Again, Dangerous Visions 67
Mono no Aware The Paper Menagerie and Other Stories 21
Monolog Riverworld and Other Stories 8
Moth Race Again, Dangerous Visions 13
Mountain The Wandering Earth 48
Mr. Costello, Hero Selected Stories 26
Mrs. Bagley Goes to Mars Somerset Dreams and Other Fictions 10
Mutations The Aleph and Other Stories 1
Nackles vr.1 Slippage 8
Nackles vr.2 Slippage 31
Neither Your Jenny Nor Mine Love Ain't Nothing but Sex Misspelled 44
Neon Deathbird Stories 12
New Rose Hotel Burning Chrome 14
Night Journey of the Dragon-Horse Invisible Planets 20
Night Meeting The Martian Chronicles 9
Night of Black Glass Stalking the Nightmare 16
Night-Rise The Norton Book of Science Fiction 10
Nine Hundred Grandmothers The Norton Book of Science Fiction 9
No Game for Children Web of the City 51
No Great Magic Changewar 68
No Light in the Windows The Mile-Long Spaceship 11
Nothing for My Noon Meal Earthman, Go Home! 15
O Ye of Little Faith Deathbird Stories 10
Oddy and Id Strange Gifts 17
Of Ants and Dinosaurs The Wandering Earth 57
On Exactitude and Science The Aleph and Other Stories 1
On the Downhill Slide Deathbird Stories 18
On the Feasibility of Coal-Driven Power Stations The Expert Dreamers 4
On the Slab Angry Candy 12
One for the Road The Mile-Long Spaceship 16
One Life, Furnished in Early Poverty Approaching Oblivion 14
One-Way Journey Xenogensis 11
Operation Cassandra Xenogensis 27
Opium Shatterday 8
Other Worlds The Gateway Trip 19
Out of All Them Bright Stars The Norton Book of Science Fiction 7
Over the River and Through the Woods The Norton Book of Science Fiction 8
Ozymandias Again, Dangerous Visions 21
Paingod Deathbird Stories 12
Paingod Paingod and Other Delusions 12
Paladin of the Last Hour Angry Candy 26
Parable of Cervantes and the Quixote Labyrinths 1
Parable of the Palace The Aleph and Other Stories 2
Paradise City 16
Paradiso, XXXI, 108 Labyrinths 2
Paradiso, XXXI, 108 The Aleph and Other Stories 2
Partial Magic in the Quixote Labyrinths 4
Paulie Charmed the Sleeping Woman Approaching Oblivion 4
Philtre Tip The Living Demons 5
Pierre Menrad, Author of Don Quixote Ficciones 12
Pierre Menrad, Author of Don Quixote Labyrinths 9
Planet Story Somerset Dreams and Other Fictions 16
Precession The Norton Book of Science Fiction 10
Pretty Maggie Moneyeyes Deathbird Stories 24
Prince Myshkin, and Hold the Relish Angry Candy 10
Prodigy Caviar 14
Project Nightmare The Menace from Earth 21
Pulling Hard Time Slippage 6
Punky & The Yale Men Love Ain't Nothing but Sex Misspelled 30
Quick to Haste Xenogensis 12
Quicktime Angry Candy 10
Ragnarok Labyrinths 2
Ragnarok The Aleph and Other Stories 2
Rain, Rain, Go Away Earthman, Go Home! 9
Rat The Norton Book of Science Fiction 11
Reason I, Robot 18
Red Star, Winter Orbit Burning Chrome 23
Repent, Harlequin! Said the Ticktockman Paingod and Other Delusions 14
Requiem The Man Who Sold the Moon 20
Riders of the Purple Wage Dangerous Visions 80
Riding the Dark Train Out Love Ain't Nothing but Sex Misspelled 10
Riverworld Riverworld and Other Stories 86
Robbie I, Robot 19
Rock God Deathbird Stories 14
Rocket Summer The Martian Chronicles 1
Runaround I, Robot 17
Sandkings Nebula Winners Fifteen 43
Saturn, November 11th Stalking the Nightmare 16
Scartaris, June 28th Slippage 22
Schrodinger's Plague The Norton Book of Science Fiction 8
Schwarzschild Radius The Norton Book of Science Fiction 16
Seeing Strange Wine 34
Sensible City Slippage 10
Seventy-Two Letters Stories of Your Life and Others 54
Sex and/or Mr. Morrison Dangerous Visions 14
Shadow, Shadow on the Wall Caviar 12
Shall the Dust Praise Thee? Dangerous Visions 7
Shatterday Shatterday 17
Shattered Like a Glass Goblin Deathbird Stories 14
She's a Young Thing and Cannot Leaver Her Mother Slippage 16
Shoppe Keeper Shatterday 24
Silence This Way for the Gas, Ladies and Gentlemen 3
Silent in Gehenna Approaching Oblivion 16
Silhouette The New Atlantis 56
Simulacrum The Paper Menagerie and Other Stories 11
Skeleton The October Country 20
Sky Lift The Menace from Earth 14
Slow Sculpture Selected Stories 20
Slow Sculpture Sturgeon is Alive and Well... 22
Snow The Norton Book of Science Fiction 14
Soft Monkey Angry Candy 16
Somehow, I Don't Think We're in Kansas, Toto Stalking the Nightmare 10
Somerset Dreams Somerset Dreams and Other Fictions 46
Soundless Evening Again, Dangerous Visions 8
Speech Sound The Norton Book of Science Fiction 12
Stable Strategies for Middle Management The Norton Book of Science Fiction 11
Stand Still and Die Web of the City 203
State Change The Paper Menagerie and Other Stories 16
State of Grace Somerset Dreams and Other Fictions 9
Still-Life Again, Dangerous Visions 15
Stoned Counsel Again, Dangerous Visions 16
Story of the Warrior and the Captive Maiden Labyrinths 5
Story of the Warrior and the Captive Maiden The Aleph and Other Stories 5
Story of Your Life Stories of Your Life and Others 56
Strange Wine Strange Wine 12
Strange Wine The Norton Book of Science Fiction 7
Stuffing Angry Candy 8
Suicide Sturgeon is Alive and Well... 8
Sun of China The Wandering Earth 49
Symbiosis Somerset Dreams and Other Fictions 20
Take Care of Joey Sturgeon is Alive and Well... 12
Taking Care of God Invisible Planets 40
Taking Care of God The Wandering Earth 41
Tandy's Story The Norton Book of Science Fiction 19
Tauf Aleph The Norton Book of Science Fiction 18
Tell Your Fortune The Living Demons 25
Test to Destruction Dangerous Visions 29
That Girl Who Knew What They Meant Sturgeon is Alive and Well... 10
The [Widget], the [Wadget], and Boff Selected Stories 84
The 10:00 Report is Brought to You By... Again, Dangerous Visions 16
The 3 Most Important Things in Life Stalking the Nightmare 20
The Absolutely Perfect Murder Xenogensis 11
The Adventure of Black Peter The Original Illustrated Sherlock Holmes 13
The Adventure of Charles Augustus Milverton The Original Illustrated Sherlock Holmes 12
The Adventure of the Gloria Scott The Original Illustrated Sherlock Holmes 12
The Adventure of the Abbey Grange The Original Illustrated Sherlock Holmes 15
The Adventure of the Beryl Coronet The Original Illustrated Sherlock Holmes 15
The Adventure of the Blue Carbuncle The Original Illustrated Sherlock Holmes 13
The Adventure of the Cardboard Box The Original Illustrated Sherlock Holmes 13
The Adventure of the Copper Beeches The Original Illustrated Sherlock Holmes 17
The Adventure of the Crooked Man The Original Illustrated Sherlock Holmes 11
The Adventure of the Dancing Men The Original Illustrated Sherlock Holmes 16
The Adventure of the Empty House The Original Illustrated Sherlock Holmes 15
The Adventure of the Engineer's Thumb The Original Illustrated Sherlock Holmes 13
The Adventure of the Final Problem The Original Illustrated Sherlock Holmes 14
The Adventure of the Golden Pince-Nez The Original Illustrated Sherlock Holmes 15
The Adventure of the Greek Interpreter The Original Illustrated Sherlock Holmes 12
The Adventure of the Missing Three-Quarter The Original Illustrated Sherlock Holmes 14
The Adventure of the Musgrave Ritual The Original Illustrated Sherlock Holmes 11
The Adventure of the Naval Treaty The Original Illustrated Sherlock Holmes 22
The Adventure of the Noble Bachelor The Original Illustrated Sherlock Holmes 14
The Adventure of the Norwood Builder The Original Illustrated Sherlock Holmes 15
The Adventure of the Priory School The Original Illustrated Sherlock Holmes 19
The Adventure of the Reigate Squires The Original Illustrated Sherlock Holmes 12
The Adventure of the Resident Patient The Original Illustrated Sherlock Holmes 11
The Adventure of the Second Stain The Original Illustrated Sherlock Holmes 14
The Adventure of the Silver Blaze The Original Illustrated Sherlock Holmes 16
The Adventure of the Six Napoleons The Original Illustrated Sherlock Holmes 14
The Adventure of the Solitary Cyclist The Original Illustrated Sherlock Holmes 13
The Adventure of the Speckled Band The Original Illustrated Sherlock Holmes 16
The Adventure of the Stockbroker's Clerk The Original Illustrated Sherlock Holmes 11
The Adventure of the Yellow Face The Original Illustrated Sherlock Holmes 11
The Age of Gold The Gateway Trip 16
The Ajeri Diary Xenogensis 20
The Aleph The Aleph and Other Stories 16
The Approach to Al-Mu'tasim Ficciones 8
The Argentine Writer and Tradition Labyrinths 9
The Avenger of Death Angry Candy 14
The Babylon Lottery Ficciones 8
The Beast of Barsac The Living Demons 19
The Belonging Kind Burning Chrome 15
The Big Hunger The View from the Stars 14
The Big Space Fuck Again, Dangerous Visions 11
The Black Cloud The Expert Dreamers 18
The Bob Dylan Tambourine Software & Satori Support Services Consortium, Ltd. The Norton Book of Science Fiction 12
The Bookmaking Habits of Select Species The Paper Menagerie and Other Stories 9
The Boscombe Valley Mystery The Original Illustrated Sherlock Holmes 16
The Boulevard of Broken Dreams Strange Wine 6
The Brains of Rats The Norton Book of Science Fiction 14
The Byrds The Norton Book of Science Fiction 12
The Captive The Aleph and Other Stories 2
The Cheese Stands Alone Stalking the Nightmare 14
The Children Xenogensis 29
The Circle Invisible Planets 22
The Circular Ruins Ficciones 8
The Circular Ruins Labyrinths 6
The Cistern The October Country 10
The City of Silence Invisible Planets 44
The Crackpots Paingod and Other Delusions 40
The Crowd The October Country 12
The Daughter of the Tree Xenogensis 12
The Day After the Day the Martians Came Dangerous Visions 10
The Day I Died Stalking the Nightmare 10
The Dead Man The Aleph and Other Stories 6
The Death of Schillinger This Way for the Gas, Ladies and Gentlemen 4
The Deathbird Deathbird Stories 32
The Diagnosis of Dr. Darqueangel Strange Wine 17
The Discarded Paingod and Other Delusions 14
The Doll-House Dangerous Visions 24
The Dragon on the Bookshelf Slippage 12
The Dreams a Nightmare Dreams Slippage 4
The Dwarf The October Country 15
The Earth Men The Martian Chronicles 15
The Emissary The October Country 10
The Encounter Somerset Dreams and Other Fictions 28
The End Ficciones 4
The Evitable Conflict I, Robot 22
The Evolution of Human Science Stories of Your Life and Others 4
The Executioner of the Malformed Children Shatterday 16
The Extraordinary Voyages of Amelie Bertrand Nebula Winners Fifteen 15
The Face of Helene Bournouw Deathbird Stories 12
The Fearful Sphere of Pascal Labyrinths 4
The Few, the Proud Slippage 10
The Fish of Lijiang Invisible Planets 18
The Five Orange Pips The Original Illustrated Sherlock Holmes 11
The Flower of Shazui Invisible Planets 20
The Forces that Crush Earthman, Go Home! 15
The Form of the Sword Ficciones 6
The Function of Dream Sleep Angry Candy 23
The Funeral Again, Dangerous Visions 28
The Funeral The Infinity Box 27
The Fusion Bomb The Infinity Box 39
The Garden of Forking Paths Ficciones 14
The Garden of Forking Paths Labyrinths 11
The Gateway Asteroid The Gateway Trip 9
The Gernsback Continuum The Norton Book of Science Fiction 9
The Gernsback Continuum Burning Chrome 13
The Girl From Mars The Living Demons 7
The Goddess in the Ice Stalking the Nightmare 6
The God's Script Labyrinths 8
The Golden Helix Selected Stories 56
The Golden Man Strange Gifts 33
The Green Morning The Martian Chronicles 5
The Handler The Norton Book of Science Fiction 4
The Happy Breed Dangerous Visions 22
The Heart of the Other Side The Expert Dreamers 11
The Henry Miller Dawn Patrol Riverworld and Other Stories 16
The Home Planet The Gateway Trip 9
The Hounds Somerset Dreams and Other Fictions 28
The Hour That Stretches Stalking the Nightmare 22
The House of Asterion Labyrinths 3
The House of Asterion The Aleph and Other Stories 3
The House the Blakeneys Built The Norton Book of Science Fiction 10
The Immortal Labyrinths 14
The Immortal The Aleph and Other Stories 17
The Indian Spirit Guide The Living Demons 16
The Infinity Box The Infinity Box 65
The Invasion The Expert Dreamers 18
The January Offensive This Way for the Gas, Ladies and Gentlemen 10
The Jar The October Country 17
The Jigsaw Man Dangerous Visions 17
The Jungle Rot Kid on the Nod Riverworld and Other Stories 12
The Lake The October Country 7
The Lake Was Full of Artificial Things The Norton Book of Science Fiction 11
The Last Days of the Captain The Mile-Long Spaceship 15
The Last Generation? Xenogensis 12
The Leaser of Two Evils Riverworld and Other Stories 16
The Library of Babel Ficciones 10
The Library of Babel Labyrinths 8
The Life of Anybody The Norton Book of Science Fiction 2
The Lingering Scent of Woodsmoke Slippage 4
The Literomancer The Paper Menagerie and Other Stories 38
The Litigation Master and the Monkey King The Paper Menagerie and Other Stories 26
The Locusts The Martian Chronicles 1
The Long Years The Martian Chronicles 11
The Longest Fall The Wandering Earth 56
The Lottery in Babylon Labyrinths 6
The Lucky Strike The Norton Book of Science Fiction 31
The Luggage Store The Martian Chronicles 1
The Maker The Aleph and Other Stories 3
The Malley System Dangerous Visions 11
The Man on the Threshold The Aleph and Other Stories 6
The Man Upstairs The October Country 16
The Man Who Ended History: A Documentary The Paper Menagerie and Other Stories 61
The Man Who Lost the Sea Selected Stories 12
The Man Who Rowed Christopher Columbus Ashore Slippage 18
The Man Who Sold the Moon The Man Who Sold the Moon 106
The Man Who Was Heavily into Revenge Shatterday 8
The Man Who Went to the Moon-Twice Dangerous Visions 13
The Man With English Strange Gifts 10
The Man with the Package This Way for the Gas, Ladies and Gentlemen 5
The Man With the Twisted Lips The Original Illustrated Sherlock Holmes 15
The Man without a Planet The Mile-Long Spaceship 7
The Mark Gable Foundation The Expert Dreamers 13
The Martian The Martian Chronicles 12
The Menace from Earth The Menace from Earth 13
The Merchants of Venus The Gateway Trip 122
The Micro-Age The Wandering Earth 33
The Mile-Long Spaceship The Mile-Long Spaceship 10
The Milk of Paradise Again, Dangerous Visions 13
The Million-Year Picnic The Martian Chronicles 9
The Miracle of the Broom Closet The Expert Dreamers 7
The Mirrors of Enigmas Labyrinths 4
The Mountains of Sunset, the Mountains of Dawn The Norton Book of Science Fiction 13
The Mountebank The Aleph and Other Stories 2
The Museum on Cyclops Avenue Slippage 12
The Musicians The Martian Chronicles 1
The Naming of Names The Martian Chronicles 1
The New Atlantis The New Atlantis 30
The New Atlantis The Norton Book of Science Fiction 20
The New York Review of Bird Strange Wine 44
The Next in Line The October Country 41
The Night That All Time Broke Out Dangerous Visions 16
The Off Season The Martian Chronicles 12
The Old Ones The Martian Chronicles 1
The Oldest Soldier Changewar 27
The Other Death The Aleph and Other Stories 8
The Other Eye of Polyphemus Shatterday 14
The Outpost Undiscovered by Tourists Stalking the Nightmare 8
The Pale Silver Dollar of the Moon Pays Its Way and Makes Change vr.1 Slippage 6
The Pale Silver Dollar of the Moon Pays Its Way and Makes Change vr.2 Slippage 8
The Paper Menagerie The Paper Menagerie and Other Stories 15
The Patterns of Drone Sturgeon is Alive and Well... 16
The People Who Walked On This Way for the Gas, Ladies and Gentlemen 16
The Perfect Match The Paper Menagerie and Other Stories 25
The Phantom of the Sewers Riverworld and Other Stories 25
The Place with No Name Deathbird Stories 16
The Plot The Aleph and Other Stories 1
The Plot Is the Thing The Living Demons 7
The Private War of Private Jacob The Norton Book of Science Fiction 5
The Problem of the Sore Bridge-Among Others Riverworld and Other Stories 32
The Prowler in the City on the Edge of Forever Dangerous Visions 20
The Recognition Dangerous Visions 14
The Red Canary The Infinity Box 18
The Red-Headed League The Original Illustrated Sherlock Holmes 15
The Region Between Angry Candy 86
The Regular The Paper Menagerie and Other Stories 25
The Resurgence of Miss Ankle-Strap Wedgie Love Ain't Nothing but Sex Misspelled 91
The Roads Must Roll The Man Who Sold the Moon 45
The Season of Babies Xenogensis 14
The Secret Miracle Ficciones 8
The Secret Miracle Labyrinths 7
The Sect of Phoenix Ficciones 4
The Sect of Phoenix Labyrinths 4
The Settlers The Martian Chronicles 1
The Sex Opposite Selected Stories 28
The Shape of the Sword Labyrinths 5
The Shore The Martian Chronicles 1
The Silent Towns The Martian Chronicles 10
The Silver Corridor Earthman, Go Home! 20
The Simple Way City 25
The Singers The Expert Dreamers 4
The Skills of Xanadu Selected Stories 28
The Sky is Burning Earthman, Go Home! 9
The Small Assaassin The October Country 21
The Smiling Future Xenogensis 13
The South Ficciones 7
The Starseekers The Gateway Trip 19
The Start of the End of It All The Norton Book of Science Fiction 11
The Summer Night The Martian Chronicles 2
The Superior Sex Xenogensis 11
The Supper This Way for the Gas, Ladies and Gentlemen 5
The Sycthe The October Country 8
The Taxpayer The Martian Chronicles 1
The Test Stand The Expert Dreamers 14
The Test-Tube Creature, Afterward Again, Dangerous Visions 5
The Theologians Labyrinths 8
The Theologians The Aleph and Other Stories 9
The Third Expedition The Martian Chronicles 16
The Time Piece The Infinity Box 22
The Transit of Venus Xenogensis 11
The Two Kings and the Two Labyrinths The Aleph and Other Stories 2
The Universe of Robert Blake Love Ain't Nothing but Sex Misspelled 5
The Unspeakable Betrothal The Living Demons 14
The Very Last Day of a Good Woman Earthman, Go Home! 9
The Village The Infinity Box 10
The Visit The Gateway Trip 9
The Voice of the Sonar in My Veriform Appendix Riverworld and Other Stories 14
The Volcano Riverworld and Other Stories 20
The Wages of Humanity The Wandering Earth 44
The Waiting Labyrinths 4
The Wall and the Books Labyrinths 3
The Wandering Earth The Wandering Earth 46
The War at Home The Norton Book of Science Fiction 3
The Warlord of Saturn's Moon The Norton Book of Science Fiction 8
The Watchers The Martian Chronicles 1
The Watchful Poker Chip of H. Matisse The October Country 12
The Waves The Paper Menagerie and Other Stories 26
The Whimper of Whipped Dogs Deathbird Stories 22
The Will The View from the Stars 14
The Wind The October Country 12
The Wind Beyond the Mountains Earthman, Go Home! 10
The Wine Has Been Left Open Too Long and the Memory Has Gone Flat Strange Wine 16
The Winter Flies The Norton Book of Science Fiction 12
The Winter Market Burning Chrome 25
The Witness Labyrinths 1
The Witness The Aleph and Other Stories 1
The Women Men Don't See The Norton Book of Science Fiction 25
The Wonderful Death of Dudley Stone The October Country 13
The Word for World is Forrest Again, Dangerous Visions 96
The World of Stone This Way for the Gas, Ladies and Gentlemen 3
The Writing of the God The Aleph and Other Stories 6
The Year of the Jackpot The Menace from Earth 32
The Year of the Rat Invisible Planets 30
The Yellow Rose The Aleph and Other Stories 1
The Zahir Labyrinths 5
The Zahir The Aleph and Other Stories 10
Theme of the Traitor and Hero Ficciones 6
Theme of the Traitor and Hero Labyrinths 4
There Was an Old Woman The October Country 16
There Will Come Soft Rains The Martian Chronicles 6
Things Lost Again, Dangerous Visions 30
This Way for the Gas, Ladies and Gentlemen This Way for the Gas, Ladies and Gentlemen 21
Three Versions of Judas Ficciones 8
Three Versions of Judas Labyrinths 6
Throwback Xenogensis 13
Thunder and Roses Selected Stories 24
Time Travel for Pedestrians Again, Dangerous Visions 31
Tiny Ally Stalking the Nightmare 6
Tissue Again, Dangerous Visions 16
Tlon, Uqbar, Orbis Teritus Ficciones 20
Tlon, Uqbar, Orbis Teritus Labyrinths 16
To Be Continued Strange Gifts 14
To Explain to Mrs. Thompson The Expert Dreamers 23
To Here and the Easel Sturgeon is Alive and Well... 56
Toenails The Aleph and Other Stories 1
Tongtong's Summer Invisible Planets 20
Totenbuch Again, Dangerous Visions 10
Touched With Fire The October Country 15
Tower of Babylon Stories of Your Life and Others 28
Tracking Level Stalking the Nightmare 12
Transcending Destiny Stalking the Nightmare 26
Trouble With Ants City 38
Try and Change the Past Changewar 11
Twink Caviar 19
Unaccompanied Sonata Nebula Winners Fifteen 20
Uncle Einar The October Country 10
Uncle Fremmis Sturgeon is Alive and Well... 18
Underground The Living Demons 6
Understand Stories of Your Life and Others 42
Unlocking the Air The Unreal and the Real 26
Usher II The Martian Chronicles 15
Valerie Love Ain't Nothing but Sex Misspelled 16
Valery as Symbol Labyrinths 2
Vaster than Empires and More Slow Explorers of Space 57
Visionary Stalking the Nightmare 14
Wanted in Surgery Paingod and Other Delusions 30
Water Is for Washing The Menace from Earth 10
Way in the Middle of the Air The Martian Chronicles 3
We See Things Differently The Norton Book of Science Fiction 18
What Happened to Auguste Clarot? Dangerous Visions 8
What I Did on My Vaction This Summer by Little Bobby Hirschhorn, Age 27 Love Ain't Nothing but Sex Misspelled 19
What's It Like Out There? Explorers of Space 27
When Auld's Acquaintance is Forgot Angry Candy 10
When I was a Hired Gun Love Ain't Nothing but Sex Misspelled 12
When I Was Miss Dow The Norton Book of Science Fiction 10
When it Changed Again, Dangerous Visions 16
When the Bentfin Boomer Boys on Old New Alabama Again, Dangerous Visions 107
When the Change-Winds Blow Changewar 15
Where Have You Been, Billy Boy, Billy Boy? The Infinity Box 13
Where I Shall Dwell in the Next World Slippage 12
With a Finger in My I Again, Dangerous Visions 15
With Her Eyes The Wandering Earth 19
With Virgin Oddum at the East Pole Angry Candy 20
Working with the Little People Strange Wine 18
Would You Do It for a Penny Shatterday 22
Ylla The Martian Chronicles 12
You Triflin' Skunk The View from the Stars 11
Zero Gee Again, Dangerous Visions 31
And the Moon be Still as Bright The Martian Chronicles 24
================================================
FILE: tests/data/stories.tsv
================================================
!!!The!!Teddy!Crazy!!Show!!! science fiction 1968
(Learning About) Machine Sex science fiction 1988
...the World, as we Know 't science fiction 1982
2004, or Thereabouts science fiction 1964
A Biography of Tadeo Isidoro Cruz (1829-1874) fiction 1944
A Brief History of the Trans-Pacific Tunnel science fiction 2013
A Case of Identity mystery 1891
A Day at Harmenz east euro lit 1959
A Deskful of Girls science fiction 1958
A Dialog About A Dialog fiction 1936
A Dialog Between Dead Men fiction 1957
A Feast of Demons science fiction 1958
A Few Things I Know About While Away science fiction 1975
A Hundred Ghosts Parade Tonight science fiction 2010
A is for Automation science fiction 1959
A Midwinter's Tale science fiction 1988
A Momentary Taste of Being science fiction 1975
A Mouse in the Walls of the Global Village science fiction 1972
A New Refutation of Time essay 1947
A Note on (toward) Bernard Shaw essay 1962
A Path Through the Darkness science fiction 1963
A Prayer for No One's Enemies science fiction 1966
A Problem fiction 1957
A Scandal in Bohemia mystery 1891
A Toy for Juliette science fiction 1967
A True Story east euro lit 1959
A Visit east euro lit 1959
A Way of Thinking science fiction 1953
Adrift Just Off the Islets of Langerhans: Latitude 38o54'N, Longitude 77o00'13W science fiction 1974
Adrift on the Policy Level science fiction 1959
Aesop science fiction 1947
After the Days of Dead-Eye 'Dee science fiction 1985
All in Good Time science fiction 1960
All the Birds Come Home to Roost science fiction 1978
All the Flavors science fiction 2012
All the Lies Lies That Are My Life science fiction 1980
All The People science fiction 1961
All the Sound of Fear science fiction 1962
Along the Scenic Route science fiction 1969
Alpha Ralpha Boulevard science fiction 1961
Amateur in Chancery science fiction 1961
America science fiction 1987
An Advanced Readers' Picture Book of Comparative Cognition science fiction 2016
An Examination of the Work of Herbert Quain fiction 1941
And the Angels Sing science fiction 1990
And the Sea Like Mirrors science fiction 1972
Andover and the Android science fiction 1963
Anybody Else Like Me? science fiction 1952
Anywhere But Here, With Anybody But You science fiction 1996
April Fools' Day Forever science fiction 1970
Argumentum Ornithologicum fiction 1952
As Simple As That science fiction 1971
At the End of the Orbit science fiction 1961
At the Mouse Circus science fiction 1971
Aunt Parnetta's Electric Blisters science fiction 1990
Auschwitz, Our Home (A Letter) east euro lit 1959
Auto-De-Fe science fiction 1967
Avatars of the Tortoise essay 1939
Averroes' Search fiction 1947
Aye, and Gomorrah... science fiction 1967
Balanced Ecology science fiction 1965
Basilisk science fiction 1972
Battle Without Banners science fiction 1964
Battlefield science fiction 1958
Beachhead science fiction 1951
Beauty's Beast science fiction 1941
Bed Sheets are White science fiction 1972
Bettyann science fiction 1951
Bianca's Hands science fiction 1947
Big Joe and the Nth Generation science fiction 1952
Blabbermouth science fiction 1945
Black Bargain science fiction 1942
Blank? science fiction 1957
Bleeding Stones science fiction 1973
Blind Bird, Blind Bird, Go Away From Me! science fiction 1963
Blood Bank science fiction 1952
Blot science fiction 1972
Blowups Happen science fiction 1940
Borges and I fiction 1957
Bounty science fiction 1972
Brass and Gold (or Horse and Zeppelin in Beverly Hills) science fiction 1971
Bright Eyes science fiction 1965
Bright Segment science fiction 1955
Broken Glass science fiction 1981
Brownshoes science fiction 1969
Burning Chrome science fiction 1982
By His Bootstraps science fiction 1941
Call Girl science fiction 2014
Camps science fiction 1979
Carcinoma Angels science fiction 1967
Catch That Rabbit science fiction 1944
Catman science fiction 1974
Census science fiction 1944
Chain Reaction science fiction 1956
Chained to the Fast Lane in the Red Queen's Race science fiction 1983
Chatting with Anubis science fiction 1995
Ching Witch! science fiction 1972
Christ, Old Student in a New School science fiction 1972
Chuck Berry, Won't You Please Come Home science fiction 1972
City science fiction 1944
Cold Friend science fiction 1973
Collecting Team science fiction 1956
Columbus Was a Dope science fiction 1947
Come to the Party science fiction 1978
Comes Now the Power science fiction 1966
Commuter's Problem science fiction 1957
Corpse science fiction 1972
Count the Clock That Tells the Time science fiction 1978
Covered Mirrors fiction 1936
Crate science fiction 1970
Crazy as a Soup Sandwich science fiction 1989
Croatoan science fiction 1975
Crucifixus Etiam science fiction 1953
Curse 5.0 science fiction 2013
Damnation Morning science fiction 1959
Danger-Human! science fiction 1957
Daniel White for the Greater Good science fiction 1961
Darkness Upon the Face of the Deep science fiction 1991
Day Million science fiction 1966
Deal From the Bottom science fiction 1960
Death and the Compass fiction 1942
Deeper than the Darkness science fiction 1957
Delia Elena San Marco fiction 1957
Delusion for a Dragon Slayer science fiction 1966
Deutsches Requiem fiction 1946
Devourer science fiction 2013
Distant Signals science fiction 1984
Division by Zero science fiction 1991
Django science fiction 1978
Djinn, No Chaser science fiction 1982
Dogfight science fiction 1985
Do-It-Yourself science fiction 1961
Dreamtigers fiction 1936
Dumb Waiter science fiction 1952
Each an Explorer science fiction 1956
E
gitextract_sm4g9zum/
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── example.cpp
├── generator.py
├── include/
│ ├── cexpr/
│ │ └── string.hpp
│ ├── ra/
│ │ ├── cross.hpp
│ │ ├── join.hpp
│ │ ├── natural.hpp
│ │ ├── operation.hpp
│ │ ├── projection.hpp
│ │ ├── relation.hpp
│ │ ├── rename.hpp
│ │ └── selection.hpp
│ └── sql/
│ ├── column.hpp
│ ├── index.hpp
│ ├── predicate.hpp
│ ├── query.hpp
│ ├── row.hpp
│ ├── schema.hpp
│ └── tokens.hpp
├── single-header/
│ └── sql.hpp
└── tests/
├── data/
│ ├── authored.tsv
│ ├── books.tsv
│ ├── collected.tsv
│ └── stories.tsv
├── data.hpp
├── perf/
│ ├── data/
│ │ ├── lib-query0
│ │ ├── lib-query1
│ │ ├── lib-query2
│ │ ├── lib-query3
│ │ ├── lib-query4
│ │ ├── lib-query5
│ │ ├── query0
│ │ ├── query1
│ │ ├── query2
│ │ ├── query3
│ │ ├── query4
│ │ └── query5
│ ├── queries/
│ │ ├── lib-query0.cpp
│ │ ├── lib-query1.cpp
│ │ ├── lib-query2.cpp
│ │ ├── lib-query3.cpp
│ │ ├── lib-query4.cpp
│ │ ├── lib-query5.cpp
│ │ ├── query0.cpp
│ │ ├── query1.cpp
│ │ ├── query2.cpp
│ │ ├── query3.cpp
│ │ ├── query4.cpp
│ │ └── query5.cpp
│ ├── runner.sh
│ └── scripts/
│ └── runner.py
├── runner.sh
└── scripts/
├── compose.py
├── generate.py
├── runner.py
└── select.py
SYMBOL INDEX (370 symbols across 37 files)
FILE: example.cpp
function main (line 30) | int main()
FILE: generator.py
function include (line 3) | def include(header, incs, root, included):
function main (line 25) | def main():
FILE: include/cexpr/string.hpp
type cexpr (line 7) | namespace cexpr
class string (line 11) | class string
method string (line 16) | constexpr string() noexcept : size_{ 0 }, string_{ 0 }
method string (line 19) | constexpr string(const Char(&s)[N]) noexcept : string{}
method string (line 27) | constexpr string(cexpr::string<Char, N> const& s) noexcept : string{}
method string (line 35) | constexpr string(std::basic_string_view<Char> const& s) noexcept : s...
method fill (line 46) | constexpr void fill(const Char* begin, const Char* end) noexcept
method fill_from (line 51) | constexpr void fill_from(const Char* begin, const Char* end, Char* s...
method capacity (line 62) | inline constexpr std::size_t capacity() const noexcept
method size (line 67) | inline constexpr std::size_t size() const noexcept
method Char (line 72) | inline constexpr Char* begin() noexcept
method Char (line 76) | inline constexpr const Char* cbegin() const noexcept
method Char (line 81) | inline constexpr Char* end() noexcept
method Char (line 85) | inline constexpr const Char* cend() const noexcept
method Char (line 90) | inline constexpr Char& operator[](std::size_t i)
method Char (line 94) | inline constexpr Char const& operator[](std::size_t i) const
FILE: include/ra/cross.hpp
type ra (line 6) | namespace ra
class cross (line 10) | class cross : public ra::join<LeftInput, RightInput>
FILE: include/ra/join.hpp
type ra (line 9) | namespace ra
function recr_merge (line 16) | constexpr auto recr_merge()
function merge (line 31) | inline constexpr auto merge()
function recr_copy (line 44) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 58) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 73) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 82) | static inline void seed(Inputs const&... rs)
method reset (line 88) | static inline void reset()
FILE: include/ra/natural.hpp
type ra (line 10) | namespace ra
class natural (line 14) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 24) | static void seed(Inputs const&... rs)
FILE: include/ra/operation.hpp
type ra (line 5) | namespace ra
class unary (line 9) | class unary
method seed (line 15) | static inline void seed(Inputs const&... rs)
method reset (line 20) | static inline void reset()
class binary (line 27) | class binary
method seed (line 34) | static inline void seed(Inputs const&... rs)
method reset (line 40) | static inline void reset()
FILE: include/ra/projection.hpp
type ra (line 7) | namespace ra
class projection (line 11) | class projection : public ra::unary<Input>
method fold (line 26) | static inline constexpr void fold(Dest& dest, input_type const& src)
FILE: include/ra/relation.hpp
type ra (line 6) | namespace ra
type data_end (line 9) | struct data_end : std::exception
class relation (line 15) | class relation
method seed (line 33) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 47) | static inline void reset() noexcept
FILE: include/ra/rename.hpp
type ra (line 7) | namespace ra
class rename (line 11) | class rename : public ra::unary<Input>
method fold (line 26) | static inline constexpr void fold(Dest& dest, Src const& src)
FILE: include/ra/selection.hpp
type ra (line 5) | namespace ra
class selection (line 9) | class selection : public ra::unary<Input>
FILE: include/sql/column.hpp
type sql (line 5) | namespace sql
type column (line 9) | struct column
FILE: include/sql/index.hpp
type sql (line 9) | namespace sql
type index (line 13) | struct index
type comparator (line 16) | struct comparator
method compare (line 25) | bool compare(Row const& left, Row const& right) const noexcept
FILE: include/sql/predicate.hpp
type sql (line 7) | namespace sql
type value (line 15) | struct value
method value (line 17) | constexpr value(Type v) : val{ v }
type operation (line 26) | struct operation
method eval (line 28) | static constexpr bool eval(Row const& row) noexcept
type variable (line 70) | struct variable
method eval (line 72) | static constexpr auto eval(Row const& row) noexcept
type constant (line 79) | struct constant
method eval (line 81) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
FILE: include/sql/query.hpp
type sql (line 23) | namespace sql
type context (line 31) | struct context
type colinfo (line 38) | struct colinfo
function exists (line 46) | constexpr bool exists() noexcept
function convert (line 66) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 99) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 104) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 109) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 114) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 119) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 124) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 129) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 134) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 139) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 144) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 149) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 154) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 166) | constexpr bool isdigit(char c) noexcept
function iscomp (line 171) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 176) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 181) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 190) | class query_iterator
method query_iterator (line 196) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 211) | inline row_type const& operator*() const noexcept
method query_iterator (line 216) | query_iterator& operator++()
class query (line 239) | class query
method parse_terms (line 244) | static constexpr auto parse_terms()
method recurse_comparison (line 288) | static constexpr auto recurse_comparison()
method parse_comparison (line 308) | static constexpr auto parse_comparison()
method parse_negation (line 317) | static constexpr auto parse_negation()
method recurse_and (line 336) | static constexpr auto recurse_and()
method parse_and (line 355) | static constexpr auto parse_and()
method recurse_or (line 364) | static constexpr auto recurse_or()
method parse_or (line 383) | static constexpr auto parse_or()
method recurse_schemas (line 392) | static constexpr auto recurse_schemas()
method parse_schema (line 408) | static constexpr auto parse_schema()
method choose_join (line 432) | static constexpr auto choose_join()
method parse_join (line 446) | static constexpr auto parse_join()
method parse_from (line 469) | static constexpr auto parse_from()
method recurse_types (line 496) | static constexpr auto recurse_types()
method column_type (line 512) | static constexpr auto column_type()
method next_column (line 521) | static constexpr std::size_t next_column()
method parse_colinfo (line 536) | static constexpr auto parse_colinfo()
method recurse_columns (line 566) | static constexpr auto recurse_columns()
method parse_projection (line 588) | static constexpr auto parse_projection()
method parse_rename (line 601) | static constexpr auto parse_rename()
method has_rename (line 613) | static constexpr bool has_rename()
method parse_root (line 642) | static constexpr auto parse_root()
method query (line 670) | query(Schemas const&... tables)
method iterator (line 688) | inline iterator begin() const
method iterator (line 693) | inline iterator end() const
FILE: include/sql/row.hpp
type sql (line 9) | namespace sql
type void_row (line 12) | struct void_row
class row (line 18) | class row
method row (line 26) | row() = default;
method row (line 29) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 33) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 36) | inline constexpr next const& tail() const noexcept
method next (line 41) | inline constexpr next& tail() noexcept
type variadic_row (line 62) | struct variadic_row
method resolve (line 65) | static inline constexpr auto resolve() noexcept
function set (line 115) | constexpr void set(Row& r, Type const& value)
type std (line 132) | namespace std
class tuple_size<sql::row<Col, Next>> (line 136) | class tuple_size<sql::row<Col, Next>> : public integral_constant<size_...
type tuple_element<Index, sql::row<Col, Next>> (line 140) | struct tuple_element<Index, sql::row<Col, Next>>
FILE: include/sql/schema.hpp
type sql (line 15) | namespace sql
class schema (line 19) | class schema
method schema (line 33) | schema() = default;
method schema (line 36) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 42) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 48) | inline void emplace(Types const&... vals)
method emplace (line 61) | inline void emplace(Types&&... vals)
method insert (line 74) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 83) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 91) | void insert(row_type const& row)
method insert (line 103) | void insert(row_type&& row)
method const_iterator (line 115) | inline const_iterator begin() const noexcept
method const_iterator (line 120) | inline const_iterator end() const noexcept
function fill (line 133) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 158) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 181) | Schema load(std::string const& file, char delim)
function Schema (line 204) | inline Schema load(std::string const& file)
function store (line 211) | void store(Type const& data, std::string const& file, char delim)
function store (line 223) | inline void store(Type const& data, std::string const& file)
FILE: include/sql/tokens.hpp
type sql (line 10) | namespace sql
function whitespace (line 16) | constexpr bool whitespace(Char curr)
function syntax (line 22) | constexpr bool syntax(Char curr)
function Char (line 29) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 36) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 64) | class tokens
method tokens (line 69) | constexpr tokens() = default;
method tokens (line 72) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 103) | constexpr std::size_t count() const noexcept
method token_view (line 108) | constexpr token_view* begin() noexcept
method token_view (line 112) | constexpr const token_view* cbegin() const noexcept
method token_view (line 117) | constexpr token_view* end() noexcept
method token_view (line 121) | constexpr const token_view* cend() const noexcept
method token_view (line 126) | constexpr token_view& operator[](std::size_t i)
method token_view (line 130) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 140) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
FILE: single-header/sql.hpp
type cexpr (line 16) | namespace cexpr
class string (line 20) | class string
method string (line 25) | constexpr string() noexcept : size_{ 0 }, string_{ 0 }
method string (line 28) | constexpr string(const Char(&s)[N]) noexcept : string{}
method string (line 36) | constexpr string(cexpr::string<Char, N> const& s) noexcept : string{}
method string (line 44) | constexpr string(std::basic_string_view<Char> const& s) noexcept : s...
method fill (line 55) | constexpr void fill(const Char* begin, const Char* end) noexcept
method fill_from (line 60) | constexpr void fill_from(const Char* begin, const Char* end, Char* s...
method capacity (line 71) | inline constexpr std::size_t capacity() const noexcept
method size (line 76) | inline constexpr std::size_t size() const noexcept
method Char (line 81) | inline constexpr Char* begin() noexcept
method Char (line 85) | inline constexpr const Char* cbegin() const noexcept
method Char (line 90) | inline constexpr Char* end() noexcept
method Char (line 94) | inline constexpr const Char* cend() const noexcept
method Char (line 99) | inline constexpr Char& operator[](std::size_t i)
method Char (line 103) | inline constexpr Char const& operator[](std::size_t i) const
type sql (line 170) | namespace sql
type column (line 174) | struct column
type void_row (line 186) | struct void_row
class row (line 192) | class row
method row (line 200) | row() = default;
method row (line 203) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 207) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 210) | inline constexpr next const& tail() const noexcept
method next (line 215) | inline constexpr next& tail() noexcept
type variadic_row (line 236) | struct variadic_row
method resolve (line 239) | static inline constexpr auto resolve() noexcept
function set (line 289) | constexpr void set(Row& r, Type const& value)
type index (line 325) | struct index
type comparator (line 328) | struct comparator
method compare (line 337) | bool compare(Row const& left, Row const& right) const noexcept
class schema (line 361) | class schema
method schema (line 375) | schema() = default;
method schema (line 378) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 384) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 390) | inline void emplace(Types const&... vals)
method emplace (line 403) | inline void emplace(Types&&... vals)
method insert (line 416) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 425) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 433) | void insert(row_type const& row)
method insert (line 445) | void insert(row_type&& row)
method const_iterator (line 457) | inline const_iterator begin() const noexcept
method const_iterator (line 462) | inline const_iterator end() const noexcept
function fill (line 475) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 500) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 523) | Schema load(std::string const& file, char delim)
function Schema (line 546) | inline Schema load(std::string const& file)
function store (line 553) | void store(Type const& data, std::string const& file, char delim)
function store (line 565) | inline void store(Type const& data, std::string const& file)
function whitespace (line 989) | constexpr bool whitespace(Char curr)
function syntax (line 995) | constexpr bool syntax(Char curr)
function Char (line 1002) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 1009) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 1037) | class tokens
method tokens (line 1042) | constexpr tokens() = default;
method tokens (line 1045) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 1076) | constexpr std::size_t count() const noexcept
method token_view (line 1081) | constexpr token_view* begin() noexcept
method token_view (line 1085) | constexpr const token_view* cbegin() const noexcept
method token_view (line 1090) | constexpr token_view* end() noexcept
method token_view (line 1094) | constexpr const token_view* cend() const noexcept
method token_view (line 1099) | constexpr token_view& operator[](std::size_t i)
method token_view (line 1103) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 1113) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
type value (line 1139) | struct value
method value (line 1141) | constexpr value(Type v) : val{ v }
type operation (line 1150) | struct operation
method eval (line 1152) | static constexpr bool eval(Row const& row) noexcept
type variable (line 1194) | struct variable
method eval (line 1196) | static constexpr auto eval(Row const& row) noexcept
type constant (line 1203) | struct constant
method eval (line 1205) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
type context (line 1221) | struct context
type colinfo (line 1228) | struct colinfo
function exists (line 1236) | constexpr bool exists() noexcept
function convert (line 1256) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 1289) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 1294) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 1299) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 1304) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 1309) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 1314) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 1319) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 1324) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 1329) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 1334) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 1339) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 1344) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 1356) | constexpr bool isdigit(char c) noexcept
function iscomp (line 1361) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 1366) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 1371) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 1380) | class query_iterator
method query_iterator (line 1386) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 1401) | inline row_type const& operator*() const noexcept
method query_iterator (line 1406) | query_iterator& operator++()
class query (line 1429) | class query
method parse_terms (line 1434) | static constexpr auto parse_terms()
method recurse_comparison (line 1478) | static constexpr auto recurse_comparison()
method parse_comparison (line 1498) | static constexpr auto parse_comparison()
method parse_negation (line 1507) | static constexpr auto parse_negation()
method recurse_and (line 1526) | static constexpr auto recurse_and()
method parse_and (line 1545) | static constexpr auto parse_and()
method recurse_or (line 1554) | static constexpr auto recurse_or()
method parse_or (line 1573) | static constexpr auto parse_or()
method recurse_schemas (line 1582) | static constexpr auto recurse_schemas()
method parse_schema (line 1598) | static constexpr auto parse_schema()
method choose_join (line 1622) | static constexpr auto choose_join()
method parse_join (line 1636) | static constexpr auto parse_join()
method parse_from (line 1659) | static constexpr auto parse_from()
method recurse_types (line 1686) | static constexpr auto recurse_types()
method column_type (line 1702) | static constexpr auto column_type()
method next_column (line 1711) | static constexpr std::size_t next_column()
method parse_colinfo (line 1726) | static constexpr auto parse_colinfo()
method recurse_columns (line 1756) | static constexpr auto recurse_columns()
method parse_projection (line 1778) | static constexpr auto parse_projection()
method parse_rename (line 1791) | static constexpr auto parse_rename()
method has_rename (line 1803) | static constexpr bool has_rename()
method parse_root (line 1832) | static constexpr auto parse_root()
method query (line 1860) | query(Schemas const&... tables)
method iterator (line 1878) | inline iterator begin() const
method iterator (line 1883) | inline iterator end() const
type sql (line 183) | namespace sql
type column (line 174) | struct column
type void_row (line 186) | struct void_row
class row (line 192) | class row
method row (line 200) | row() = default;
method row (line 203) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 207) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 210) | inline constexpr next const& tail() const noexcept
method next (line 215) | inline constexpr next& tail() noexcept
type variadic_row (line 236) | struct variadic_row
method resolve (line 239) | static inline constexpr auto resolve() noexcept
function set (line 289) | constexpr void set(Row& r, Type const& value)
type index (line 325) | struct index
type comparator (line 328) | struct comparator
method compare (line 337) | bool compare(Row const& left, Row const& right) const noexcept
class schema (line 361) | class schema
method schema (line 375) | schema() = default;
method schema (line 378) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 384) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 390) | inline void emplace(Types const&... vals)
method emplace (line 403) | inline void emplace(Types&&... vals)
method insert (line 416) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 425) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 433) | void insert(row_type const& row)
method insert (line 445) | void insert(row_type&& row)
method const_iterator (line 457) | inline const_iterator begin() const noexcept
method const_iterator (line 462) | inline const_iterator end() const noexcept
function fill (line 475) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 500) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 523) | Schema load(std::string const& file, char delim)
function Schema (line 546) | inline Schema load(std::string const& file)
function store (line 553) | void store(Type const& data, std::string const& file, char delim)
function store (line 565) | inline void store(Type const& data, std::string const& file)
function whitespace (line 989) | constexpr bool whitespace(Char curr)
function syntax (line 995) | constexpr bool syntax(Char curr)
function Char (line 1002) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 1009) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 1037) | class tokens
method tokens (line 1042) | constexpr tokens() = default;
method tokens (line 1045) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 1076) | constexpr std::size_t count() const noexcept
method token_view (line 1081) | constexpr token_view* begin() noexcept
method token_view (line 1085) | constexpr const token_view* cbegin() const noexcept
method token_view (line 1090) | constexpr token_view* end() noexcept
method token_view (line 1094) | constexpr const token_view* cend() const noexcept
method token_view (line 1099) | constexpr token_view& operator[](std::size_t i)
method token_view (line 1103) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 1113) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
type value (line 1139) | struct value
method value (line 1141) | constexpr value(Type v) : val{ v }
type operation (line 1150) | struct operation
method eval (line 1152) | static constexpr bool eval(Row const& row) noexcept
type variable (line 1194) | struct variable
method eval (line 1196) | static constexpr auto eval(Row const& row) noexcept
type constant (line 1203) | struct constant
method eval (line 1205) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
type context (line 1221) | struct context
type colinfo (line 1228) | struct colinfo
function exists (line 1236) | constexpr bool exists() noexcept
function convert (line 1256) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 1289) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 1294) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 1299) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 1304) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 1309) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 1314) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 1319) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 1324) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 1329) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 1334) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 1339) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 1344) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 1356) | constexpr bool isdigit(char c) noexcept
function iscomp (line 1361) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 1366) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 1371) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 1380) | class query_iterator
method query_iterator (line 1386) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 1401) | inline row_type const& operator*() const noexcept
method query_iterator (line 1406) | query_iterator& operator++()
class query (line 1429) | class query
method parse_terms (line 1434) | static constexpr auto parse_terms()
method recurse_comparison (line 1478) | static constexpr auto recurse_comparison()
method parse_comparison (line 1498) | static constexpr auto parse_comparison()
method parse_negation (line 1507) | static constexpr auto parse_negation()
method recurse_and (line 1526) | static constexpr auto recurse_and()
method parse_and (line 1545) | static constexpr auto parse_and()
method recurse_or (line 1554) | static constexpr auto recurse_or()
method parse_or (line 1573) | static constexpr auto parse_or()
method recurse_schemas (line 1582) | static constexpr auto recurse_schemas()
method parse_schema (line 1598) | static constexpr auto parse_schema()
method choose_join (line 1622) | static constexpr auto choose_join()
method parse_join (line 1636) | static constexpr auto parse_join()
method parse_from (line 1659) | static constexpr auto parse_from()
method recurse_types (line 1686) | static constexpr auto recurse_types()
method column_type (line 1702) | static constexpr auto column_type()
method next_column (line 1711) | static constexpr std::size_t next_column()
method parse_colinfo (line 1726) | static constexpr auto parse_colinfo()
method recurse_columns (line 1756) | static constexpr auto recurse_columns()
method parse_projection (line 1778) | static constexpr auto parse_projection()
method parse_rename (line 1791) | static constexpr auto parse_rename()
method has_rename (line 1803) | static constexpr bool has_rename()
method parse_root (line 1832) | static constexpr auto parse_root()
method query (line 1860) | query(Schemas const&... tables)
method iterator (line 1878) | inline iterator begin() const
method iterator (line 1883) | inline iterator end() const
type std (line 306) | namespace std
class tuple_size<sql::row<Col, Next>> (line 310) | class tuple_size<sql::row<Col, Next>> : public integral_constant<size_...
type tuple_element<Index, sql::row<Col, Next>> (line 314) | struct tuple_element<Index, sql::row<Col, Next>>
type sql (line 321) | namespace sql
type column (line 174) | struct column
type void_row (line 186) | struct void_row
class row (line 192) | class row
method row (line 200) | row() = default;
method row (line 203) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 207) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 210) | inline constexpr next const& tail() const noexcept
method next (line 215) | inline constexpr next& tail() noexcept
type variadic_row (line 236) | struct variadic_row
method resolve (line 239) | static inline constexpr auto resolve() noexcept
function set (line 289) | constexpr void set(Row& r, Type const& value)
type index (line 325) | struct index
type comparator (line 328) | struct comparator
method compare (line 337) | bool compare(Row const& left, Row const& right) const noexcept
class schema (line 361) | class schema
method schema (line 375) | schema() = default;
method schema (line 378) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 384) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 390) | inline void emplace(Types const&... vals)
method emplace (line 403) | inline void emplace(Types&&... vals)
method insert (line 416) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 425) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 433) | void insert(row_type const& row)
method insert (line 445) | void insert(row_type&& row)
method const_iterator (line 457) | inline const_iterator begin() const noexcept
method const_iterator (line 462) | inline const_iterator end() const noexcept
function fill (line 475) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 500) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 523) | Schema load(std::string const& file, char delim)
function Schema (line 546) | inline Schema load(std::string const& file)
function store (line 553) | void store(Type const& data, std::string const& file, char delim)
function store (line 565) | inline void store(Type const& data, std::string const& file)
function whitespace (line 989) | constexpr bool whitespace(Char curr)
function syntax (line 995) | constexpr bool syntax(Char curr)
function Char (line 1002) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 1009) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 1037) | class tokens
method tokens (line 1042) | constexpr tokens() = default;
method tokens (line 1045) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 1076) | constexpr std::size_t count() const noexcept
method token_view (line 1081) | constexpr token_view* begin() noexcept
method token_view (line 1085) | constexpr const token_view* cbegin() const noexcept
method token_view (line 1090) | constexpr token_view* end() noexcept
method token_view (line 1094) | constexpr const token_view* cend() const noexcept
method token_view (line 1099) | constexpr token_view& operator[](std::size_t i)
method token_view (line 1103) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 1113) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
type value (line 1139) | struct value
method value (line 1141) | constexpr value(Type v) : val{ v }
type operation (line 1150) | struct operation
method eval (line 1152) | static constexpr bool eval(Row const& row) noexcept
type variable (line 1194) | struct variable
method eval (line 1196) | static constexpr auto eval(Row const& row) noexcept
type constant (line 1203) | struct constant
method eval (line 1205) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
type context (line 1221) | struct context
type colinfo (line 1228) | struct colinfo
function exists (line 1236) | constexpr bool exists() noexcept
function convert (line 1256) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 1289) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 1294) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 1299) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 1304) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 1309) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 1314) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 1319) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 1324) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 1329) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 1334) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 1339) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 1344) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 1356) | constexpr bool isdigit(char c) noexcept
function iscomp (line 1361) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 1366) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 1371) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 1380) | class query_iterator
method query_iterator (line 1386) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 1401) | inline row_type const& operator*() const noexcept
method query_iterator (line 1406) | query_iterator& operator++()
class query (line 1429) | class query
method parse_terms (line 1434) | static constexpr auto parse_terms()
method recurse_comparison (line 1478) | static constexpr auto recurse_comparison()
method parse_comparison (line 1498) | static constexpr auto parse_comparison()
method parse_negation (line 1507) | static constexpr auto parse_negation()
method recurse_and (line 1526) | static constexpr auto recurse_and()
method parse_and (line 1545) | static constexpr auto parse_and()
method recurse_or (line 1554) | static constexpr auto recurse_or()
method parse_or (line 1573) | static constexpr auto parse_or()
method recurse_schemas (line 1582) | static constexpr auto recurse_schemas()
method parse_schema (line 1598) | static constexpr auto parse_schema()
method choose_join (line 1622) | static constexpr auto choose_join()
method parse_join (line 1636) | static constexpr auto parse_join()
method parse_from (line 1659) | static constexpr auto parse_from()
method recurse_types (line 1686) | static constexpr auto recurse_types()
method column_type (line 1702) | static constexpr auto column_type()
method next_column (line 1711) | static constexpr std::size_t next_column()
method parse_colinfo (line 1726) | static constexpr auto parse_colinfo()
method recurse_columns (line 1756) | static constexpr auto recurse_columns()
method parse_projection (line 1778) | static constexpr auto parse_projection()
method parse_rename (line 1791) | static constexpr auto parse_rename()
method has_rename (line 1803) | static constexpr bool has_rename()
method parse_root (line 1832) | static constexpr auto parse_root()
method query (line 1860) | query(Schemas const&... tables)
method iterator (line 1878) | inline iterator begin() const
method iterator (line 1883) | inline iterator end() const
type sql (line 357) | namespace sql
type column (line 174) | struct column
type void_row (line 186) | struct void_row
class row (line 192) | class row
method row (line 200) | row() = default;
method row (line 203) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 207) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 210) | inline constexpr next const& tail() const noexcept
method next (line 215) | inline constexpr next& tail() noexcept
type variadic_row (line 236) | struct variadic_row
method resolve (line 239) | static inline constexpr auto resolve() noexcept
function set (line 289) | constexpr void set(Row& r, Type const& value)
type index (line 325) | struct index
type comparator (line 328) | struct comparator
method compare (line 337) | bool compare(Row const& left, Row const& right) const noexcept
class schema (line 361) | class schema
method schema (line 375) | schema() = default;
method schema (line 378) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 384) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 390) | inline void emplace(Types const&... vals)
method emplace (line 403) | inline void emplace(Types&&... vals)
method insert (line 416) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 425) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 433) | void insert(row_type const& row)
method insert (line 445) | void insert(row_type&& row)
method const_iterator (line 457) | inline const_iterator begin() const noexcept
method const_iterator (line 462) | inline const_iterator end() const noexcept
function fill (line 475) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 500) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 523) | Schema load(std::string const& file, char delim)
function Schema (line 546) | inline Schema load(std::string const& file)
function store (line 553) | void store(Type const& data, std::string const& file, char delim)
function store (line 565) | inline void store(Type const& data, std::string const& file)
function whitespace (line 989) | constexpr bool whitespace(Char curr)
function syntax (line 995) | constexpr bool syntax(Char curr)
function Char (line 1002) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 1009) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 1037) | class tokens
method tokens (line 1042) | constexpr tokens() = default;
method tokens (line 1045) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 1076) | constexpr std::size_t count() const noexcept
method token_view (line 1081) | constexpr token_view* begin() noexcept
method token_view (line 1085) | constexpr const token_view* cbegin() const noexcept
method token_view (line 1090) | constexpr token_view* end() noexcept
method token_view (line 1094) | constexpr const token_view* cend() const noexcept
method token_view (line 1099) | constexpr token_view& operator[](std::size_t i)
method token_view (line 1103) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 1113) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
type value (line 1139) | struct value
method value (line 1141) | constexpr value(Type v) : val{ v }
type operation (line 1150) | struct operation
method eval (line 1152) | static constexpr bool eval(Row const& row) noexcept
type variable (line 1194) | struct variable
method eval (line 1196) | static constexpr auto eval(Row const& row) noexcept
type constant (line 1203) | struct constant
method eval (line 1205) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
type context (line 1221) | struct context
type colinfo (line 1228) | struct colinfo
function exists (line 1236) | constexpr bool exists() noexcept
function convert (line 1256) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 1289) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 1294) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 1299) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 1304) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 1309) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 1314) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 1319) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 1324) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 1329) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 1334) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 1339) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 1344) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 1356) | constexpr bool isdigit(char c) noexcept
function iscomp (line 1361) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 1366) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 1371) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 1380) | class query_iterator
method query_iterator (line 1386) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 1401) | inline row_type const& operator*() const noexcept
method query_iterator (line 1406) | query_iterator& operator++()
class query (line 1429) | class query
method parse_terms (line 1434) | static constexpr auto parse_terms()
method recurse_comparison (line 1478) | static constexpr auto recurse_comparison()
method parse_comparison (line 1498) | static constexpr auto parse_comparison()
method parse_negation (line 1507) | static constexpr auto parse_negation()
method recurse_and (line 1526) | static constexpr auto recurse_and()
method parse_and (line 1545) | static constexpr auto parse_and()
method recurse_or (line 1554) | static constexpr auto recurse_or()
method parse_or (line 1573) | static constexpr auto parse_or()
method recurse_schemas (line 1582) | static constexpr auto recurse_schemas()
method parse_schema (line 1598) | static constexpr auto parse_schema()
method choose_join (line 1622) | static constexpr auto choose_join()
method parse_join (line 1636) | static constexpr auto parse_join()
method parse_from (line 1659) | static constexpr auto parse_from()
method recurse_types (line 1686) | static constexpr auto recurse_types()
method column_type (line 1702) | static constexpr auto column_type()
method next_column (line 1711) | static constexpr std::size_t next_column()
method parse_colinfo (line 1726) | static constexpr auto parse_colinfo()
method recurse_columns (line 1756) | static constexpr auto recurse_columns()
method parse_projection (line 1778) | static constexpr auto parse_projection()
method parse_rename (line 1791) | static constexpr auto parse_rename()
method has_rename (line 1803) | static constexpr bool has_rename()
method parse_root (line 1832) | static constexpr auto parse_root()
method query (line 1860) | query(Schemas const&... tables)
method iterator (line 1878) | inline iterator begin() const
method iterator (line 1883) | inline iterator end() const
type ra (line 572) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type ra (line 616) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type ra (line 709) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type ra (line 772) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type ra (line 801) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type ra (line 872) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type ra (line 912) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type ra (line 952) | namespace ra
class unary (line 576) | class unary
method seed (line 582) | static inline void seed(Inputs const&... rs)
method reset (line 587) | static inline void reset()
class binary (line 594) | class binary
method seed (line 601) | static inline void seed(Inputs const&... rs)
method reset (line 607) | static inline void reset()
function recr_merge (line 623) | constexpr auto recr_merge()
function merge (line 638) | inline constexpr auto merge()
function recr_copy (line 651) | constexpr void recr_copy(Dest& dest, Row const& src)
function copy (line 665) | inline constexpr void copy(Dest& dest, Row const& src)
class join (line 680) | class join : public ra::binary<LeftInput, RightInput>
method seed (line 689) | static inline void seed(Inputs const&... rs)
method reset (line 695) | static inline void reset()
type data_end (line 712) | struct data_end : std::exception
class relation (line 718) | class relation
method seed (line 736) | static void seed(Input const& r, Inputs const&... rs) noexcept
method reset (line 750) | static inline void reset() noexcept
class cross (line 776) | class cross : public ra::join<LeftInput, RightInput>
class natural (line 805) | class natural : public ra::join<LeftInput, RightInput>
method seed (line 815) | static void seed(Inputs const&... rs)
class projection (line 876) | class projection : public ra::unary<Input>
method fold (line 891) | static inline constexpr void fold(Dest& dest, input_type const& src)
class rename (line 916) | class rename : public ra::unary<Input>
method fold (line 931) | static inline constexpr void fold(Dest& dest, Src const& src)
class selection (line 956) | class selection : public ra::unary<Input>
type sql (line 983) | namespace sql
type column (line 174) | struct column
type void_row (line 186) | struct void_row
class row (line 192) | class row
method row (line 200) | row() = default;
method row (line 203) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 207) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 210) | inline constexpr next const& tail() const noexcept
method next (line 215) | inline constexpr next& tail() noexcept
type variadic_row (line 236) | struct variadic_row
method resolve (line 239) | static inline constexpr auto resolve() noexcept
function set (line 289) | constexpr void set(Row& r, Type const& value)
type index (line 325) | struct index
type comparator (line 328) | struct comparator
method compare (line 337) | bool compare(Row const& left, Row const& right) const noexcept
class schema (line 361) | class schema
method schema (line 375) | schema() = default;
method schema (line 378) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 384) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 390) | inline void emplace(Types const&... vals)
method emplace (line 403) | inline void emplace(Types&&... vals)
method insert (line 416) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 425) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 433) | void insert(row_type const& row)
method insert (line 445) | void insert(row_type&& row)
method const_iterator (line 457) | inline const_iterator begin() const noexcept
method const_iterator (line 462) | inline const_iterator end() const noexcept
function fill (line 475) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 500) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 523) | Schema load(std::string const& file, char delim)
function Schema (line 546) | inline Schema load(std::string const& file)
function store (line 553) | void store(Type const& data, std::string const& file, char delim)
function store (line 565) | inline void store(Type const& data, std::string const& file)
function whitespace (line 989) | constexpr bool whitespace(Char curr)
function syntax (line 995) | constexpr bool syntax(Char curr)
function Char (line 1002) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 1009) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 1037) | class tokens
method tokens (line 1042) | constexpr tokens() = default;
method tokens (line 1045) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 1076) | constexpr std::size_t count() const noexcept
method token_view (line 1081) | constexpr token_view* begin() noexcept
method token_view (line 1085) | constexpr const token_view* cbegin() const noexcept
method token_view (line 1090) | constexpr token_view* end() noexcept
method token_view (line 1094) | constexpr const token_view* cend() const noexcept
method token_view (line 1099) | constexpr token_view& operator[](std::size_t i)
method token_view (line 1103) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 1113) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
type value (line 1139) | struct value
method value (line 1141) | constexpr value(Type v) : val{ v }
type operation (line 1150) | struct operation
method eval (line 1152) | static constexpr bool eval(Row const& row) noexcept
type variable (line 1194) | struct variable
method eval (line 1196) | static constexpr auto eval(Row const& row) noexcept
type constant (line 1203) | struct constant
method eval (line 1205) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
type context (line 1221) | struct context
type colinfo (line 1228) | struct colinfo
function exists (line 1236) | constexpr bool exists() noexcept
function convert (line 1256) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 1289) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 1294) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 1299) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 1304) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 1309) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 1314) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 1319) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 1324) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 1329) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 1334) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 1339) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 1344) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 1356) | constexpr bool isdigit(char c) noexcept
function iscomp (line 1361) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 1366) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 1371) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 1380) | class query_iterator
method query_iterator (line 1386) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 1401) | inline row_type const& operator*() const noexcept
method query_iterator (line 1406) | query_iterator& operator++()
class query (line 1429) | class query
method parse_terms (line 1434) | static constexpr auto parse_terms()
method recurse_comparison (line 1478) | static constexpr auto recurse_comparison()
method parse_comparison (line 1498) | static constexpr auto parse_comparison()
method parse_negation (line 1507) | static constexpr auto parse_negation()
method recurse_and (line 1526) | static constexpr auto recurse_and()
method parse_and (line 1545) | static constexpr auto parse_and()
method recurse_or (line 1554) | static constexpr auto recurse_or()
method parse_or (line 1573) | static constexpr auto parse_or()
method recurse_schemas (line 1582) | static constexpr auto recurse_schemas()
method parse_schema (line 1598) | static constexpr auto parse_schema()
method choose_join (line 1622) | static constexpr auto choose_join()
method parse_join (line 1636) | static constexpr auto parse_join()
method parse_from (line 1659) | static constexpr auto parse_from()
method recurse_types (line 1686) | static constexpr auto recurse_types()
method column_type (line 1702) | static constexpr auto column_type()
method next_column (line 1711) | static constexpr std::size_t next_column()
method parse_colinfo (line 1726) | static constexpr auto parse_colinfo()
method recurse_columns (line 1756) | static constexpr auto recurse_columns()
method parse_projection (line 1778) | static constexpr auto parse_projection()
method parse_rename (line 1791) | static constexpr auto parse_rename()
method has_rename (line 1803) | static constexpr bool has_rename()
method parse_root (line 1832) | static constexpr auto parse_root()
method query (line 1860) | query(Schemas const&... tables)
method iterator (line 1878) | inline iterator begin() const
method iterator (line 1883) | inline iterator end() const
type sql (line 1131) | namespace sql
type column (line 174) | struct column
type void_row (line 186) | struct void_row
class row (line 192) | class row
method row (line 200) | row() = default;
method row (line 203) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 207) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 210) | inline constexpr next const& tail() const noexcept
method next (line 215) | inline constexpr next& tail() noexcept
type variadic_row (line 236) | struct variadic_row
method resolve (line 239) | static inline constexpr auto resolve() noexcept
function set (line 289) | constexpr void set(Row& r, Type const& value)
type index (line 325) | struct index
type comparator (line 328) | struct comparator
method compare (line 337) | bool compare(Row const& left, Row const& right) const noexcept
class schema (line 361) | class schema
method schema (line 375) | schema() = default;
method schema (line 378) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 384) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 390) | inline void emplace(Types const&... vals)
method emplace (line 403) | inline void emplace(Types&&... vals)
method insert (line 416) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 425) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 433) | void insert(row_type const& row)
method insert (line 445) | void insert(row_type&& row)
method const_iterator (line 457) | inline const_iterator begin() const noexcept
method const_iterator (line 462) | inline const_iterator end() const noexcept
function fill (line 475) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 500) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 523) | Schema load(std::string const& file, char delim)
function Schema (line 546) | inline Schema load(std::string const& file)
function store (line 553) | void store(Type const& data, std::string const& file, char delim)
function store (line 565) | inline void store(Type const& data, std::string const& file)
function whitespace (line 989) | constexpr bool whitespace(Char curr)
function syntax (line 995) | constexpr bool syntax(Char curr)
function Char (line 1002) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 1009) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 1037) | class tokens
method tokens (line 1042) | constexpr tokens() = default;
method tokens (line 1045) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 1076) | constexpr std::size_t count() const noexcept
method token_view (line 1081) | constexpr token_view* begin() noexcept
method token_view (line 1085) | constexpr const token_view* cbegin() const noexcept
method token_view (line 1090) | constexpr token_view* end() noexcept
method token_view (line 1094) | constexpr const token_view* cend() const noexcept
method token_view (line 1099) | constexpr token_view& operator[](std::size_t i)
method token_view (line 1103) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 1113) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
type value (line 1139) | struct value
method value (line 1141) | constexpr value(Type v) : val{ v }
type operation (line 1150) | struct operation
method eval (line 1152) | static constexpr bool eval(Row const& row) noexcept
type variable (line 1194) | struct variable
method eval (line 1196) | static constexpr auto eval(Row const& row) noexcept
type constant (line 1203) | struct constant
method eval (line 1205) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
type context (line 1221) | struct context
type colinfo (line 1228) | struct colinfo
function exists (line 1236) | constexpr bool exists() noexcept
function convert (line 1256) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 1289) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 1294) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 1299) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 1304) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 1309) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 1314) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 1319) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 1324) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 1329) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 1334) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 1339) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 1344) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 1356) | constexpr bool isdigit(char c) noexcept
function iscomp (line 1361) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 1366) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 1371) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 1380) | class query_iterator
method query_iterator (line 1386) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 1401) | inline row_type const& operator*() const noexcept
method query_iterator (line 1406) | query_iterator& operator++()
class query (line 1429) | class query
method parse_terms (line 1434) | static constexpr auto parse_terms()
method recurse_comparison (line 1478) | static constexpr auto recurse_comparison()
method parse_comparison (line 1498) | static constexpr auto parse_comparison()
method parse_negation (line 1507) | static constexpr auto parse_negation()
method recurse_and (line 1526) | static constexpr auto recurse_and()
method parse_and (line 1545) | static constexpr auto parse_and()
method recurse_or (line 1554) | static constexpr auto recurse_or()
method parse_or (line 1573) | static constexpr auto parse_or()
method recurse_schemas (line 1582) | static constexpr auto recurse_schemas()
method parse_schema (line 1598) | static constexpr auto parse_schema()
method choose_join (line 1622) | static constexpr auto choose_join()
method parse_join (line 1636) | static constexpr auto parse_join()
method parse_from (line 1659) | static constexpr auto parse_from()
method recurse_types (line 1686) | static constexpr auto recurse_types()
method column_type (line 1702) | static constexpr auto column_type()
method next_column (line 1711) | static constexpr std::size_t next_column()
method parse_colinfo (line 1726) | static constexpr auto parse_colinfo()
method recurse_columns (line 1756) | static constexpr auto recurse_columns()
method parse_projection (line 1778) | static constexpr auto parse_projection()
method parse_rename (line 1791) | static constexpr auto parse_rename()
method has_rename (line 1803) | static constexpr bool has_rename()
method parse_root (line 1832) | static constexpr auto parse_root()
method query (line 1860) | query(Schemas const&... tables)
method iterator (line 1878) | inline iterator begin() const
method iterator (line 1883) | inline iterator end() const
type sql (line 1213) | namespace sql
type column (line 174) | struct column
type void_row (line 186) | struct void_row
class row (line 192) | class row
method row (line 200) | row() = default;
method row (line 203) | row(column::type const& val, ColTs const&... vals) : value_{ val }, ...
method row (line 207) | row(column::type&& val, ColTs&&... vals) : value_{ std::forward<colu...
method next (line 210) | inline constexpr next const& tail() const noexcept
method next (line 215) | inline constexpr next& tail() noexcept
type variadic_row (line 236) | struct variadic_row
method resolve (line 239) | static inline constexpr auto resolve() noexcept
function set (line 289) | constexpr void set(Row& r, Type const& value)
type index (line 325) | struct index
type comparator (line 328) | struct comparator
method compare (line 337) | bool compare(Row const& left, Row const& right) const noexcept
class schema (line 361) | class schema
method schema (line 375) | schema() = default;
method schema (line 378) | schema(std::vector<Type> const& col, Types const&... cols) : schema{}
method schema (line 384) | schema(std::vector<Type>&& col, Types&&... cols) : schema{}
method emplace (line 390) | inline void emplace(Types const&... vals)
method emplace (line 403) | inline void emplace(Types&&... vals)
method insert (line 416) | void insert(std::vector<Type> const& col, Types const&... cols)
method insert (line 425) | void insert(std::vector<Type>&& col, Types&&... cols)
method insert (line 433) | void insert(row_type const& row)
method insert (line 445) | void insert(row_type&& row)
method const_iterator (line 457) | inline const_iterator begin() const noexcept
method const_iterator (line 462) | inline const_iterator end() const noexcept
function fill (line 475) | void fill(std::fstream& fstr, Row& row, [[maybe_unused]] char delim)
function fill (line 500) | void fill(std::fstream& fstr, Row const& row, char delim)
function Schema (line 523) | Schema load(std::string const& file, char delim)
function Schema (line 546) | inline Schema load(std::string const& file)
function store (line 553) | void store(Type const& data, std::string const& file, char delim)
function store (line 565) | inline void store(Type const& data, std::string const& file)
function whitespace (line 989) | constexpr bool whitespace(Char curr)
function syntax (line 995) | constexpr bool syntax(Char curr)
function Char (line 1002) | constexpr const Char* skip(const Char *curr, const Char *end)
function Char (line 1009) | constexpr const Char* next(const Char *curr, const Char *end)
class tokens (line 1037) | class tokens
method tokens (line 1042) | constexpr tokens() = default;
method tokens (line 1045) | constexpr tokens(cexpr::string<Char, N> const& cs) : tokens_{}
method count (line 1076) | constexpr std::size_t count() const noexcept
method token_view (line 1081) | constexpr token_view* begin() noexcept
method token_view (line 1085) | constexpr const token_view* cbegin() const noexcept
method token_view (line 1090) | constexpr token_view* end() noexcept
method token_view (line 1094) | constexpr const token_view* cend() const noexcept
method token_view (line 1099) | constexpr token_view& operator[](std::size_t i)
method token_view (line 1103) | constexpr token_view const& operator[](std::size_t i) const
function preprocess (line 1113) | constexpr std::size_t preprocess(cexpr::string<Char, N> const& cs) noe...
type value (line 1139) | struct value
method value (line 1141) | constexpr value(Type v) : val{ v }
type operation (line 1150) | struct operation
method eval (line 1152) | static constexpr bool eval(Row const& row) noexcept
type variable (line 1194) | struct variable
method eval (line 1196) | static constexpr auto eval(Row const& row) noexcept
type constant (line 1203) | struct constant
method eval (line 1205) | static constexpr auto eval([[maybe_unused]] Row const& row) noexcept
type context (line 1221) | struct context
type colinfo (line 1228) | struct colinfo
function exists (line 1236) | constexpr bool exists() noexcept
function convert (line 1256) | constexpr value<Type> convert(cexpr::string<Char, N> const& str) noexcept
function isquote (line 1289) | inline constexpr bool isquote(std::string_view const& tv) noexcept
function isor (line 1294) | inline constexpr bool isor(std::string_view const& tv) noexcept
function isand (line 1299) | inline constexpr bool isand(std::string_view const& tv) noexcept
function isnot (line 1304) | inline constexpr bool isnot(std::string_view const& tv) noexcept
function isnatural (line 1309) | inline constexpr bool isnatural(std::string_view const& tv) noexcept
function isjoin (line 1314) | inline constexpr bool isjoin(std::string_view const& tv) noexcept
function iswhere (line 1319) | inline constexpr bool iswhere(std::string_view const& tv) noexcept
function isfrom (line 1324) | inline constexpr bool isfrom(std::string_view const& tv) noexcept
function isas (line 1329) | inline constexpr bool isas(std::string_view const& tv) noexcept
function isselect (line 1334) | inline constexpr bool isselect(std::string_view const& tv) noexcept
function iscomma (line 1339) | inline constexpr bool iscomma(std::string_view const& tv) noexcept
function isintegral (line 1344) | constexpr bool isintegral(std::string_view const& tv) noexcept
function isdigit (line 1356) | constexpr bool isdigit(char c) noexcept
function iscomp (line 1361) | constexpr bool iscomp(char c) noexcept
function iscolumn (line 1366) | constexpr bool iscolumn(std::string_view const& tv) noexcept
function isseparator (line 1371) | constexpr bool isseparator(std::string_view const& tv) noexcept
class query_iterator (line 1380) | class query_iterator
method query_iterator (line 1386) | query_iterator(bool end) : end_{ end }, row_{}
method row_type (line 1401) | inline row_type const& operator*() const noexcept
method query_iterator (line 1406) | query_iterator& operator++()
class query (line 1429) | class query
method parse_terms (line 1434) | static constexpr auto parse_terms()
method recurse_comparison (line 1478) | static constexpr auto recurse_comparison()
method parse_comparison (line 1498) | static constexpr auto parse_comparison()
method parse_negation (line 1507) | static constexpr auto parse_negation()
method recurse_and (line 1526) | static constexpr auto recurse_and()
method parse_and (line 1545) | static constexpr auto parse_and()
method recurse_or (line 1554) | static constexpr auto recurse_or()
method parse_or (line 1573) | static constexpr auto parse_or()
method recurse_schemas (line 1582) | static constexpr auto recurse_schemas()
method parse_schema (line 1598) | static constexpr auto parse_schema()
method choose_join (line 1622) | static constexpr auto choose_join()
method parse_join (line 1636) | static constexpr auto parse_join()
method parse_from (line 1659) | static constexpr auto parse_from()
method recurse_types (line 1686) | static constexpr auto recurse_types()
method column_type (line 1702) | static constexpr auto column_type()
method next_column (line 1711) | static constexpr std::size_t next_column()
method parse_colinfo (line 1726) | static constexpr auto parse_colinfo()
method recurse_columns (line 1756) | static constexpr auto recurse_columns()
method parse_projection (line 1778) | static constexpr auto parse_projection()
method parse_rename (line 1791) | static constexpr auto parse_rename()
method has_rename (line 1803) | static constexpr bool has_rename()
method parse_root (line 1832) | static constexpr auto parse_root()
method query (line 1860) | query(Schemas const&... tables)
method iterator (line 1878) | inline iterator begin() const
method iterator (line 1883) | inline iterator end() const
FILE: tests/data.hpp
function books_type (line 68) | books_type books_load()
function stories_type (line 93) | stories_type stories_load()
function authored_type (line 117) | authored_type authored_load()
function collected_type (line 140) | collected_type collected_load()
FILE: tests/perf/queries/lib-query0.cpp
function main (line 12) | int main()
FILE: tests/perf/queries/lib-query1.cpp
function main (line 12) | int main()
FILE: tests/perf/queries/lib-query2.cpp
function main (line 13) | int main()
FILE: tests/perf/queries/lib-query3.cpp
function main (line 13) | int main()
FILE: tests/perf/queries/lib-query4.cpp
function main (line 13) | int main()
FILE: tests/perf/queries/lib-query5.cpp
function main (line 13) | int main()
FILE: tests/perf/queries/query0.cpp
function stories_type (line 10) | stories_type query(stories_type const& s)
function main (line 26) | int main()
FILE: tests/perf/queries/query1.cpp
function books_type (line 10) | books_type query(books_type const& b)
function main (line 26) | int main()
FILE: tests/perf/queries/query2.cpp
function authored_type (line 10) | authored_type query(books_type const& b, authored_type const& a)
function main (line 39) | int main()
FILE: tests/perf/queries/query3.cpp
function output_type (line 12) | output_type query(stories_type const& s, authored_type const& a)
function main (line 41) | int main()
FILE: tests/perf/queries/query4.cpp
function output_type (line 12) | output_type query(books_type const& b, authored_type const& a)
function main (line 31) | int main()
FILE: tests/perf/queries/query5.cpp
function output_type (line 12) | output_type query(stories_type const& s, collected_type const& c)
function main (line 31) | int main()
FILE: tests/perf/scripts/runner.py
function exe (line 5) | def exe(file, q):
function main (line 13) | def main():
FILE: tests/scripts/compose.py
function data (line 21) | def data(tokens):
function templ (line 37) | def templ(query, ts):
function func (line 43) | def func(ts, cs):
function main (line 59) | def main():
FILE: tests/scripts/generate.py
function col_list (line 41) | def col_list(cs):
function froms (line 60) | def froms(ts):
function compose (line 73) | def compose(ts, cs, pred):
function next (line 82) | def next(cs, ci):
function predicate (line 92) | def predicate(ts, cs, ci, pred):
function operation (line 103) | def operation(ts, cs, ci, pred):
function select (line 122) | def select(ts):
function root_query (line 135) | def root_query(left):
function main (line 140) | def main():
FILE: tests/scripts/runner.py
function main (line 3) | def main():
FILE: tests/scripts/select.py
function main (line 5) | def main():
Condensed preview — 59 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (266K chars).
[
{
"path": ".gitattributes",
"chars": 66,
"preview": "# Auto detect text files and perform LF normalization\n* text=auto\n"
},
{
"path": ".gitignore",
"chars": 82,
"preview": "tests/*.txt\ntests/test.cpp\ntests/test\ntests/queries/*\n.vscode/*\nexample\n.DS_STORE\n"
},
{
"path": "LICENSE",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2020 Michael Kitzan\n\nPermission is hereby granted, free of charge, to any person obtaining a "
},
{
"path": "README.md",
"chars": 18437,
"preview": "# Constexpr SQL\n\nA light weight single header alternative to DBMS\n\nThis library was developed during my honors project a"
},
{
"path": "example.cpp",
"chars": 973,
"preview": "#include <iostream>\n#include <string>\n\n#include \"sql.hpp\"\n\nusing books =\n\tsql::schema<\n\t\t\"books\", sql::index<\"title\">,\n\t"
},
{
"path": "generator.py",
"chars": 920,
"preview": "import os\n\ndef include(header, incs, root, included):\n\tfile = open(\"include/\" + root, \"r\")\n\n\tfor line in file:\n\t\tif line"
},
{
"path": "include/cexpr/string.hpp",
"chars": 3107,
"preview": "#pragma once\n\n#include <cstddef>\n#include <string>\n#include <string_view>\n\nnamespace cexpr\n{\n\n\ttemplate <typename Char, "
},
{
"path": "include/ra/cross.hpp",
"chars": 640,
"preview": "#pragma once\n\n#include \"ra/join.hpp\"\n#include \"ra/relation.hpp\"\n\nnamespace ra\n{\n\n\ttemplate <typename LeftInput, typename"
},
{
"path": "include/ra/join.hpp",
"chars": 2035,
"preview": "#pragma once\n\n#include <type_traits>\n\n#include \"ra/operation.hpp\"\n\n#include \"sql/row.hpp\"\n\nnamespace ra\n{\n\n\tnamespace\n\t{"
},
{
"path": "include/ra/natural.hpp",
"chars": 2018,
"preview": "#pragma once\n\n#include <type_traits>\n#include <vector>\n#include <unordered_map>\n\n#include \"ra/join.hpp\"\n#include \"ra/rel"
},
{
"path": "include/ra/operation.hpp",
"chars": 817,
"preview": "#pragma once\n\n#include <type_traits>\n\nnamespace ra\n{\n\n\ttemplate <typename Input>\n\tclass unary\n\t{\n\tpublic:\n\t\tusing input_"
},
{
"path": "include/ra/projection.hpp",
"chars": 879,
"preview": "#pragma once\n\n#include \"ra/operation.hpp\"\n\n#include \"sql/row.hpp\"\n\nnamespace ra\n{\n\n\ttemplate <typename Output, typename "
},
{
"path": "include/ra/relation.hpp",
"chars": 1307,
"preview": "#pragma once\n\n#include <exception>\n#include <type_traits>\n\nnamespace ra\n{\n\n\tstruct data_end : std::exception\n\t{};\n\n\t// I"
},
{
"path": "include/ra/rename.hpp",
"chars": 889,
"preview": "#pragma once\n\n#include \"ra/operation.hpp\"\n\n#include \"sql/row.hpp\"\n\nnamespace ra\n{\n\n\ttemplate <typename Output, typename "
},
{
"path": "include/ra/selection.hpp",
"chars": 636,
"preview": "#pragma once\n\n#include \"ra/operation.hpp\"\n\nnamespace ra\n{\n\n\ttemplate <typename Predicate, typename Input>\n\tclass selecti"
},
{
"path": "include/sql/column.hpp",
"chars": 210,
"preview": "#pragma once\n\n#include \"cexpr/string.hpp\"\n\nnamespace sql\n{\n\n\ttemplate <cexpr::string Name, typename Type>\n\tstruct column"
},
{
"path": "include/sql/index.hpp",
"chars": 751,
"preview": "#pragma once\n\n#include <type_traits>\n\n#include \"cexpr/string.hpp\"\n\n#include \"sql/row.hpp\"\n\nnamespace sql\n{\n\n\ttemplate <c"
},
{
"path": "include/sql/predicate.hpp",
"chars": 1645,
"preview": "#pragma once\n\n#include <cstddef>\n\n#include \"cexpr/string.hpp\"\n\nnamespace sql\n{\n\n\tnamespace\n\t{\n\n\t\t// shim to allow all va"
},
{
"path": "include/sql/query.hpp",
"chars": 16378,
"preview": "#pragma once\n\n#include <array>\n#include <string>\n#include <string_view>\n#include <type_traits>\n\n#include \"cexpr/string.h"
},
{
"path": "include/sql/row.hpp",
"chars": 2928,
"preview": "#pragma once\n\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"cexpr/string.hpp\"\n\nnamespace sql\n{\n"
},
{
"path": "include/sql/schema.hpp",
"chars": 4656,
"preview": "#pragma once\n\n#include <fstream>\n#include <set>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\n#include \"c"
},
{
"path": "include/sql/tokens.hpp",
"chars": 3079,
"preview": "#pragma once\n\n#include <array>\n#include <cstddef>\n#include <locale>\n#include <string_view>\n\n#include \"cexpr/string.hpp\"\n"
},
{
"path": "single-header/sql.hpp",
"chars": 40556,
"preview": "#pragma once\n\n#include <array>\n#include <cstddef>\n#include <exception>\n#include <fstream>\n#include <locale>\n#include <se"
},
{
"path": "tests/data/authored.tsv",
"chars": 38172,
"preview": "1984\tGeorge Orwell\n!!!The!!Teddy!Crazy!!Show!!!\tHarlan Ellison\n(Learning About) Machine Sex\tCandas Jane Dorsey\n...the Wo"
},
{
"path": "tests/data/books.tsv",
"chars": 14092,
"preview": "1984\tscience fiction\t1950\t328\n2001: A Space Odyssey\tscience fiction\t1968\t221\n20th Century Boys vol.1\tscience fiction\t201"
},
{
"path": "tests/data/collected.tsv",
"chars": 34720,
"preview": "!!!The!!Teddy!Crazy!!Show!!!\tStalking the Nightmare\t14\n(Learning About) Machine Sex\tThe Norton Book of Science Fiction\t1"
},
{
"path": "tests/data/stories.tsv",
"chars": 29242,
"preview": "!!!The!!Teddy!Crazy!!Show!!!\tscience fiction\t1968\n(Learning About) Machine Sex\tscience fiction\t1988\n...the World, as we "
},
{
"path": "tests/data.hpp",
"chars": 3314,
"preview": "#pragma once\n\n#include <string>\n#include <type_traits>\n\n#include \"sql.hpp\"\n\nusing books =\n\tsql::schema<\n\t\t\"books\", sql::"
},
{
"path": "tests/perf/data/lib-query0",
"chars": 10,
"preview": "6.81 user\n"
},
{
"path": "tests/perf/data/lib-query1",
"chars": 10,
"preview": "4.73 user\n"
},
{
"path": "tests/perf/data/lib-query2",
"chars": 10,
"preview": "3.70 user\n"
},
{
"path": "tests/perf/data/lib-query3",
"chars": 11,
"preview": "11.81 user\n"
},
{
"path": "tests/perf/data/lib-query4",
"chars": 10,
"preview": "1.54 user\n"
},
{
"path": "tests/perf/data/lib-query5",
"chars": 11,
"preview": "38.04 user\n"
},
{
"path": "tests/perf/data/query0",
"chars": 10,
"preview": "6.39 user\n"
},
{
"path": "tests/perf/data/query1",
"chars": 10,
"preview": "4.18 user\n"
},
{
"path": "tests/perf/data/query2",
"chars": 11,
"preview": "11.17 user\n"
},
{
"path": "tests/perf/data/query3",
"chars": 11,
"preview": "12.39 user\n"
},
{
"path": "tests/perf/data/query4",
"chars": 10,
"preview": "3.45 user\n"
},
{
"path": "tests/perf/data/query5",
"chars": 11,
"preview": "44.35 user\n"
},
{
"path": "tests/perf/queries/lib-query0.cpp",
"chars": 474,
"preview": "#include <iostream>\n#include \"../../data.hpp\"\n\nusing query =\n\tsql::query<\n\t\t\"SELECT title, genre AS type, year AS publis"
},
{
"path": "tests/perf/queries/lib-query1.cpp",
"chars": 502,
"preview": "#include <iostream>\n#include \"../../data.hpp\"\n\nusing query =\n\tsql::query<\n\t\t\"SELECT title, genre AS type, year AS publis"
},
{
"path": "tests/perf/queries/lib-query2.cpp",
"chars": 545,
"preview": "#include <iostream>\n#include \"../../data.hpp\"\n\nusing query =\n\tsql::query<\n\t\t\"SELECT genre AS type, name \"\n\t\t\"FROM books "
},
{
"path": "tests/perf/queries/lib-query3.cpp",
"chars": 624,
"preview": "#include <iostream>\n#include \"../../data.hpp\"\n\nusing query =\n\tsql::query<\n\t\t\"SELECT genre AS type, year AS published, ti"
},
{
"path": "tests/perf/queries/lib-query4.cpp",
"chars": 573,
"preview": "#include <iostream>\n#include \"../../data.hpp\"\n\nusing query =\n\tsql::query<\n\t\t\"SELECT book, genre AS type, year As publish"
},
{
"path": "tests/perf/queries/lib-query5.cpp",
"chars": 678,
"preview": "#include <iostream>\n#include \"../../data.hpp\"\n\nusing query =\n\tsql::query<\n\t\t\"SELECT story, genre AS type, year AS publis"
},
{
"path": "tests/perf/queries/query0.cpp",
"chars": 622,
"preview": "#include <iostream>\n#include <fstream>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <unordered_map>\n\n#i"
},
{
"path": "tests/perf/queries/query1.cpp",
"chars": 649,
"preview": "#include <iostream>\n#include <fstream>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <unordered_map>\n\n#i"
},
{
"path": "tests/perf/queries/query2.cpp",
"chars": 949,
"preview": "#include <iostream>\n#include <fstream>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <unordered_map>\n\n#i"
},
{
"path": "tests/perf/queries/query3.cpp",
"chars": 1124,
"preview": "#include <iostream>\n#include <fstream>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <unordered_map>\n\n#i"
},
{
"path": "tests/perf/queries/query4.cpp",
"chars": 858,
"preview": "#include <iostream>\n#include <fstream>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <unordered_map>\n\n#i"
},
{
"path": "tests/perf/queries/query5.cpp",
"chars": 1022,
"preview": "#include <iostream>\n#include <fstream>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <unordered_map>\n\n#i"
},
{
"path": "tests/perf/runner.sh",
"chars": 27,
"preview": "python3 scripts/runner.py\n\n"
},
{
"path": "tests/perf/scripts/runner.py",
"chars": 585,
"preview": "import os\n\nQUERIES = 6\n\ndef exe(file, q):\n\tif int(q) >= 4:\n\t\tos.system(\"g++ -std=c++2a -DCROSS -O3 -I../../single-header"
},
{
"path": "tests/runner.sh",
"chars": 68,
"preview": "mkdir queries\npython3 scripts/generate.py\npython3 scripts/runner.py\n"
},
{
"path": "tests/scripts/compose.py",
"chars": 1386,
"preview": "# Composes a test file\n\nbegin = \"\"\"#include <iostream>\n\n#include \"data.hpp\"\n\nusing query =\n\tsql::query<\n\"\"\"\nmiddle = \"\"\""
},
{
"path": "tests/scripts/generate.py",
"chars": 3428,
"preview": "# SQL query generator for test queries\n# Generates over 1.4 million unique queries\n\nimport itertools\nimport random\n\ntabl"
},
{
"path": "tests/scripts/runner.py",
"chars": 1115,
"preview": "import os\n\ndef main():\n\tprint(\"Test Runner\")\n\tos.system(\"python3 scripts/select.py\")\n\tprint(\"\\tTest queries selected\")\n\t"
},
{
"path": "tests/scripts/select.py",
"chars": 725,
"preview": "# Randomly selects ~500 queries to test from the 1.4mil query set\n\nimport random\n\ndef main():\n\toutfile = open(\"queries/t"
}
]
About this extraction
This page contains the full source code of the mkitzan/constexpr-sql GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 59 files (234.1 KB), approximately 70.0k tokens, and a symbol index with 370 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.