LCOV - code coverage report
Current view: top level - src/catalog - Schema.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 74 134 55.2 %
Date: 2025-03-25 01:19:55 Functions: 14 18 77.8 %
Branches: 87 356 24.4 %

           Branch data     Line data    Source code
       1                 :            : #include <mutable/catalog/Schema.hpp>
       2                 :            : 
       3                 :            : #include <algorithm>
       4                 :            : #include <cmath>
       5                 :            : #include <iostream>
       6                 :            : #include <iterator>
       7                 :            : #include <mutable/catalog/CardinalityEstimator.hpp>
       8                 :            : #include <mutable/catalog/Catalog.hpp>
       9                 :            : #include <mutable/catalog/CostFunction.hpp>
      10                 :            : #include <mutable/catalog/CostFunctionCout.hpp>
      11                 :            : #include <mutable/IR/Operator.hpp>
      12                 :            : #include <mutable/IR/PlanTable.hpp>
      13                 :            : #include <mutable/lex/Token.hpp>
      14                 :            : #include <mutable/Options.hpp>
      15                 :            : #include <mutable/parse/AST.hpp>
      16                 :            : #include <mutable/util/enum_ops.hpp>
      17                 :            : #include <mutable/util/fn.hpp>
      18                 :            : #include <stdexcept>
      19                 :            : 
      20                 :            : 
      21                 :            : using namespace m;
      22                 :            : 
      23                 :            : 
      24                 :            : /*======================================================================================================================
      25                 :            :  * Schema
      26                 :            :  *====================================================================================================================*/
      27                 :            : 
      28                 :        120 : Schema::Identifier Schema::Identifier::GetConstant()
      29                 :            : {
      30         [ +  - ]:        120 :     return Identifier(Catalog::Get().pool("$const"));
      31                 :          0 : }
      32                 :            : 
      33                 :       3622 : Schema::Identifier::Identifier(const ast::Expr &expr)
      34   [ +  -  +  - ]:       3622 :     : name(Catalog::Get().pool(""))
      35                 :            : {
      36   [ +  -  +  + ]:       3622 :     if (auto d = cast<const ast::Designator>(&expr)) {
      37   [ +  -  +  - ]:        292 :         prefix = d->table_name.text;
      38   [ +  -  +  - ]:        292 :         name = d->attr_name.text.assert_not_none();
      39                 :        292 :     } else {
      40         [ +  - ]:       3330 :         std::ostringstream oss;
      41         [ +  - ]:       3330 :         oss << expr;
      42         [ +  - ]:       3330 :         prefix = {};
      43   [ +  -  +  -  :       3330 :         name = Catalog::Get().pool(oss.str().c_str());
             +  -  -  + ]
      44                 :       3330 :     }
      45                 :       3622 : }
      46                 :            : 
      47         [ #  # ]:          0 : Schema::entry_type::entry_type() : id(Catalog::Get().pool("")) { }
      48                 :            : 
      49                 :            : M_LCOV_EXCL_START
      50                 :            : void Schema::dump(std::ostream &out) const { out << *this << std::endl; }
      51                 :            : void Schema::dump() const { dump(std::cerr); }
      52                 :            : M_LCOV_EXCL_STOP
      53                 :            : 
      54                 :            : 
      55                 :            : /*======================================================================================================================
      56                 :            :  * Attribute
      57                 :            :  *====================================================================================================================*/
      58                 :            : 
      59                 :       4223 : bool Attribute::is_unique() const {
      60                 :       4223 :     auto primary_key = table.primary_key();
      61                 :       7650 :     auto pred = [this](const auto &ref){ return *this == ref.get(); };
      62   [ -  +  +  + ]:       7650 :     return unique or (primary_key.size() == 1 and
      63         [ +  - ]:       3427 :                       std::find_if(primary_key.cbegin(), primary_key.cend(), pred) != primary_key.cend());
      64                 :       4223 : }
      65                 :            : 
      66                 :            : M_LCOV_EXCL_START
      67                 :            : void Attribute::dump(std::ostream &out) const
      68                 :            : {
      69                 :            :     out << "Attribute `" << table.name() << "`.`" << name << "`, "
      70                 :            :         << "id " << id << ", "
      71                 :            :         << "type " << *type
      72                 :            :         << std::endl;
      73                 :            : }
      74                 :            : 
      75                 :            : void Attribute::dump() const { dump(std::cerr); }
      76                 :            : M_LCOV_EXCL_STOP
      77                 :            : 
      78                 :            : 
      79                 :            : /*======================================================================================================================
      80                 :            :  * ConcreteTable
      81                 :            :  *====================================================================================================================*/
      82                 :            : 
      83                 :       1027 : Schema ConcreteTable::schema(const ThreadSafePooledOptionalString &alias) const
      84                 :            : {
      85                 :       1027 :     Schema S;
      86   [ +  -  +  -  :       5250 :     for (auto attr = this->begin_all(); attr != this->end_all(); ++attr) {
          +  -  +  +  +  
                      - ]
      87                 :       4223 :         Schema::entry_type::constraints_t constraints{0};
      88   [ +  -  -  + ]:       4223 :         if (attr->not_nullable)
      89         [ #  # ]:          0 :             constraints |= Schema::entry_type::NOT_NULLABLE;
      90   [ +  -  +  -  :       4223 :         if (attr->is_unique())
                   +  + ]
      91         [ +  - ]:        866 :             constraints |= Schema::entry_type::UNIQUE;
      92   [ +  -  -  +  :       4223 :         if (attr->reference and attr->reference->is_unique())
          #  #  #  #  #  
                      # ]
      93         [ #  # ]:          0 :             constraints |= Schema::entry_type::REFERENCES_UNIQUE;
      94   [ +  -  -  + ]:       4223 :         if (attr->is_hidden)
      95         [ #  # ]:          0 :             constraints |= Schema::entry_type::IS_HIDDEN;
      96   [ +  -  +  +  :       4223 :         S.add({alias.has_value() ? alias : this->name(), attr->name}, attr->type, constraints);
          +  -  +  -  +  
          -  +  -  +  -  
          -  +  +  -  +  
          -  +  +  +  +  
             #  #  #  # ]
      97                 :       4223 :     }
      98                 :       1027 :     return S;
      99         [ +  - ]:       1027 : }
     100                 :            : 
     101                 :        338 : void ConcreteTable::layout(const storage::DataLayoutFactory &factory) {
     102                 :       1244 :     view v(cbegin_all(), cend_all(), [](auto it) -> auto & { return it->type; });
     103   [ +  -  +  -  :        338 :     layout_ = factory.make(v.begin(), v.end());
                   +  - ]
     104                 :        338 : }
     105                 :            : 
     106                 :            : M_LCOV_EXCL_START
     107                 :            : void ConcreteTable::dump(std::ostream &out) const
     108                 :            : {
     109                 :            :     out << "Table `" << name_ << '`';
     110                 :            :     for (const auto &attr : attrs_)
     111                 :            :         out << "\n` " << attr.id << ": `" << attr.name << "` " << *attr.type;
     112                 :            :     out << std::endl;
     113                 :            : }
     114                 :            : 
     115                 :            : void ConcreteTable::dump() const { dump(std::cerr); }
     116                 :            : M_LCOV_EXCL_STOP
     117                 :            : 
     118                 :            : 
     119                 :            : /*======================================================================================================================
     120                 :            :  * MultiVersioningTable
     121                 :            :  *====================================================================================================================*/
     122                 :            : 
     123                 :         10 : MultiVersioningTable::MultiVersioningTable(std::unique_ptr<Table> table)
     124         [ +  - ]:         10 :     : TableDecorator(std::move(table))
     125                 :         10 : {
     126         [ +  - ]:         10 :     auto &C = Catalog::Get();
     127                 :            : 
     128                 :            :     /*----- Add hidden timestamp attributes. -----*/
     129         [ +  - ]:         10 :     auto i8 = Type::Get_Integer(Type::TY_Vector, 8);
     130         [ +  - ]:         10 :     auto ts_begin = C.pool("$ts_begin");
     131         [ -  + ]:         10 :     auto ts_end = C.pool("$ts_end");
     132   [ +  -  +  -  :         10 :     table_->push_back(ts_begin, i8);
                   +  - ]
     133   [ +  -  +  -  :         10 :     table_->push_back(ts_end, i8);
                   +  - ]
     134         [ +  - ]:         10 :     (*table_)[ts_begin].is_hidden = true;
     135         [ +  - ]:         10 :     (*table_)[ts_begin].not_nullable = true;
     136         [ +  - ]:         10 :     (*table_)[ts_end].is_hidden = true;
     137         [ +  - ]:         10 :     (*table_)[ts_end].not_nullable = true;
     138                 :         10 : }
     139                 :            : 
     140                 :            : M_LCOV_EXCL_START
     141                 :            : void MultiVersioningTable::dump(std::ostream &out) const
     142                 :            : {
     143                 :            :     out << "MultiVersioningTable Decorator" << std::endl;
     144                 :            :     table_->dump(out);
     145                 :            : }
     146                 :            : 
     147                 :            : void MultiVersioningTable::dump() const { dump(std::cerr); }
     148                 :            : M_LCOV_EXCL_STOP
     149                 :            : 
     150                 :            : 
     151                 :            : namespace {
     152                 :            : 
     153                 :            : 
     154                 :          0 : void apply_timestamp_filter(QueryGraph &G)
     155                 :            : {
     156                 :          0 :     Catalog &C = Catalog::Get();
     157                 :            : 
     158                 :          0 :     auto pos = Position(nullptr);
     159         [ #  # ]:          0 :     ast::Token ts_begin(pos, C.pool("$ts_begin"), TK_IDENTIFIER);
     160   [ #  #  #  # ]:          0 :     ast::Token ts_end(pos, C.pool("$ts_end"), TK_IDENTIFIER);
     161                 :            : 
     162   [ #  #  #  # ]:          0 :     for (auto &ds : G.sources()) {
     163   [ #  #  #  # ]:          0 :         if (auto bt = cast<const BaseTable>(ds.get())) {
     164                 :            :             /* Set timestamp filter */
     165   [ #  #  #  #  :          0 :             auto it = std::find_if(bt->table().cbegin_hidden(),
                   #  # ]
     166   [ #  #  #  # ]:          0 :                                    bt->table().end_hidden(),
     167                 :          0 :                                    [&](const Attribute & attr) {
     168                 :          0 :                                        return attr.name == C.pool("$ts_begin");
     169                 :            :                                    });
     170                 :            : 
     171   [ #  #  #  #  :          0 :             if (it != bt->table().end_hidden()) {
             #  #  #  # ]
     172   [ #  #  #  #  :          0 :                 ast::Token table_name(pos, bt->table().name(), TK_EOF);
             #  #  #  # ]
     173                 :            :                 /*----- Build AST -----*/
     174                 :            :                 // $ts_begin
     175         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_begin_designator = std::make_unique<ast::Designator>(
     176                 :            :                         ts_begin,
     177                 :            :                         table_name,
     178                 :            :                         ts_begin,
     179         [ #  # ]:          0 :                         Type::Get_Integer(Type::TY_Vector, 8),
     180         [ #  # ]:          0 :                         &*it
     181                 :            :                 );
     182                 :            : 
     183                 :            :                 // TST := transaction start time constant
     184   [ #  #  #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_begin_transaction_constant = std::make_unique<ast::Constant>(ast::Token(
     185                 :          0 :                         pos,
     186   [ #  #  #  #  :          0 :                         C.pool(std::to_string(G.transaction()->start_time()).c_str()),
             #  #  #  # ]
     187                 :            :                         m::TK_DEC_INT
     188                 :            :                 ));
     189   [ #  #  #  #  :          0 :                 ts_begin_transaction_constant->type(Type::Get_Integer(Type::TY_Vector, 8));
                   #  # ]
     190                 :            : 
     191                 :            :                 // $ts_begin <= TST
     192         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_begin_filter_clause = std::make_unique<ast::BinaryExpr>(
     193   [ #  #  #  # ]:          0 :                         ast::Token(pos, C.pool("<="), TK_LESS_EQUAL),
     194                 :            :                         std::move(ts_begin_designator),
     195                 :            :                         std::move(ts_begin_transaction_constant)
     196                 :            :                 );
     197   [ #  #  #  #  :          0 :                 ts_begin_filter_clause->type(Type::Get_Boolean(Type::TY_Vector));
                   #  # ]
     198                 :            : 
     199                 :            :                 // $ts_end
     200         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_end_designator = std::make_unique<ast::Designator>(
     201                 :            :                         ts_end,
     202                 :            :                         table_name,
     203                 :            :                         ts_end,
     204         [ #  # ]:          0 :                         Type::Get_Integer(Type::TY_Vector, 8),
     205   [ #  #  #  #  :          0 :                         &bt->table()[C.pool("$ts_end")]
                   #  # ]
     206                 :            :                 );
     207                 :            : 
     208                 :            :                 // TST := transaction start time constant
     209   [ #  #  #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_end_transaction_constant = std::make_unique<ast::Constant>(ast::Token(
     210                 :          0 :                         pos,
     211   [ #  #  #  #  :          0 :                         C.pool(std::to_string(G.transaction()->start_time()).c_str()),
             #  #  #  # ]
     212                 :            :                         m::TK_DEC_INT
     213                 :            :                 ));
     214   [ #  #  #  #  :          0 :                 ts_end_transaction_constant->type(Type::Get_Integer(Type::TY_Vector, 8));
                   #  # ]
     215                 :            : 
     216                 :            :                 // $ts_end > TST
     217         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_end_greater_transaction_expr = std::make_unique<ast::BinaryExpr>(
     218   [ #  #  #  # ]:          0 :                         ast::Token(pos, C.pool(">"), TK_GREATER),
     219                 :            :                         std::move(ts_end_designator),
     220                 :            :                         std::move(ts_end_transaction_constant)
     221                 :            :                 );
     222   [ #  #  #  #  :          0 :                 ts_end_greater_transaction_expr->type(Type::Get_Boolean(Type::TY_Vector));
                   #  # ]
     223                 :            : 
     224                 :            :                 // $ts_end
     225         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_end_designator_2 = std::make_unique<ast::Designator>(
     226                 :            :                         ts_end,
     227                 :            :                         table_name,
     228                 :            :                         ts_end,
     229         [ #  # ]:          0 :                         Type::Get_Integer(Type::TY_Vector, 8),
     230   [ #  #  #  #  :          0 :                         &bt->table()[C.pool("$ts_end")]
                   #  # ]
     231                 :            :                 );
     232                 :            : 
     233                 :            :                 // -1
     234   [ #  #  #  # ]:          0 :                 std::unique_ptr<ast::Expr> neg_one_constant = std::make_unique<ast::Constant>(ast::Token(
     235                 :          0 :                         pos,
     236         [ #  # ]:          0 :                         C.pool("-1"),
     237                 :            :                         m::TK_DEC_INT
     238                 :            :                 ));
     239   [ #  #  #  #  :          0 :                 neg_one_constant->type(Type::Get_Integer(Type::TY_Vector, 8));
                   #  # ]
     240                 :            : 
     241                 :            :                 // $ts_end = -1
     242         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_end_eq_zero = std::make_unique<ast::BinaryExpr>(
     243   [ #  #  #  # ]:          0 :                         ast::Token(pos, C.pool("="), TK_EQUAL),
     244                 :            :                         std::move(ts_end_designator_2),
     245                 :            :                         std::move(neg_one_constant)
     246                 :            :                 );
     247   [ #  #  #  #  :          0 :                 ts_end_eq_zero->type(Type::Get_Boolean(Type::TY_Vector));
                   #  # ]
     248                 :            : 
     249                 :            :                 // $ts_end > TST OR $ts_end = -1
     250         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> ts_end_filter_clause = std::make_unique<ast::BinaryExpr>(
     251   [ #  #  #  # ]:          0 :                         ast::Token(pos, C.pool("OR"), TK_Or),
     252                 :            :                         std::move(ts_end_greater_transaction_expr),
     253                 :            :                         std::move(ts_end_eq_zero)
     254                 :            :                 );
     255   [ #  #  #  #  :          0 :                 ts_end_filter_clause->type(Type::Get_Boolean(Type::TY_Vector));
                   #  # ]
     256                 :            : 
     257                 :            :                 // $ts_begin <= TST AND ($ts_end > TST OR $ts_end = 0)
     258         [ #  # ]:          0 :                 std::unique_ptr<ast::Expr> filter_expr = std::make_unique<ast::BinaryExpr>(
     259   [ #  #  #  # ]:          0 :                         ast::Token(pos, C.pool("AND"), TK_And),
     260                 :            :                         std::move(ts_begin_filter_clause),
     261                 :            :                         std::move(ts_end_filter_clause)
     262                 :            :                 );
     263   [ #  #  #  #  :          0 :                 filter_expr->type(Type::Get_Boolean(Type::TY_Vector));
                   #  # ]
     264                 :            : 
     265         [ #  # ]:          0 :                 G.add_custom_filter(std::move(filter_expr), *ds);
     266                 :          0 :             }
     267                 :          0 :         }
     268                 :            :     }
     269                 :          0 : }
     270                 :            : 
     271                 :            : __attribute__((constructor(202)))
     272                 :          1 : void register_pre_optimization()
     273                 :            : {
     274                 :          1 :     Catalog &C = Catalog::Get();
     275   [ +  -  +  - ]:          2 :     C.register_pre_optimization(C.pool("multi-versioning"),
     276                 :          1 :                                 apply_timestamp_filter,
     277                 :            :                                 "adds timestamp filters to the QueryGraph");
     278                 :          1 : }
     279                 :            : 
     280                 :            : 
     281                 :            : }
     282                 :            : 
     283                 :            : 
     284                 :            : /*======================================================================================================================
     285                 :            :  * Function
     286                 :            :  *====================================================================================================================*/
     287                 :            : 
     288                 :            : constexpr const char * Function::FNID_TO_STR_[];
     289                 :            : constexpr const char * Function::KIND_TO_STR_[];
     290                 :            : 
     291                 :            : M_LCOV_EXCL_START
     292                 :            : void Function::dump(std::ostream &out) const
     293                 :            : {
     294                 :            :     out << "Function{ name = \"" << name << "\", fnid = " << FNID_TO_STR_[fnid] << ", kind = " << KIND_TO_STR_[kind]
     295                 :            :         << "}" << std::endl;
     296                 :            : }
     297                 :            : M_LCOV_EXCL_STOP
     298                 :            : 
     299                 :            : 
     300                 :            : /*======================================================================================================================
     301                 :            :  * Database
     302                 :            :  *====================================================================================================================*/
     303                 :            : 
     304                 :        944 : Database::Database(ThreadSafePooledString name)
     305                 :        472 :     : name(name)
     306                 :            : {
     307   [ +  -  +  -  :        472 :     cardinality_estimator_ = Catalog::Get().create_cardinality_estimator(std::move(name));
                   -  + ]
     308                 :        472 : }
     309                 :            : 
     310                 :        472 : Database::~Database()
     311                 :            : {
     312         [ -  + ]:        472 :     for (auto &f : functions_)
     313         [ #  # ]:          0 :         delete f.second;
     314                 :        472 : }
     315                 :            : 
     316                 :        763 : Table & Database::add_table(ThreadSafePooledString name) {
     317                 :        763 :     auto it = tables_.find(name);
     318   [ +  -  #  # ]:        763 :     if (it != tables_.end()) throw std::invalid_argument("table with that name already exists");
     319   [ +  -  +  - ]:        763 :     it = tables_.emplace_hint(it, std::move(name), Catalog::Get().table_factory().make(name));
     320                 :        763 :     return *it->second;
     321                 :          0 : }
     322                 :            : 
     323                 :         78 : const Function * Database::get_function(const ThreadSafePooledString &name) const
     324                 :            : {
     325                 :            :     try {
     326         [ -  + ]:         78 :         return functions_.at(name);
     327         [ -  + ]:         79 :     } catch (std::out_of_range) {
     328                 :            :         /* not defined within the database; search the global catalog */
     329   [ +  -  +  + ]:         78 :         return Catalog::Get().get_function(name);
     330         [ -  + ]:         78 :     }
     331                 :        156 : }

Generated by: LCOV version 1.16