• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / github_pull_request_319175

19 May 2025 08:16PM UTC coverage: 91.119% (-0.02%) from 91.143%
github_pull_request_319175

Pull #8082

Evergreen

web-flow
Bump setuptools from 70.0.0 to 78.1.1 in /evergreen/hang_analyzer

Bumps [setuptools](https://github.com/pypa/setuptools) from 70.0.0 to 78.1.1.
- [Release notes](https://github.com/pypa/setuptools/releases)
- [Changelog](https://github.com/pypa/setuptools/blob/main/NEWS.rst)
- [Commits](https://github.com/pypa/setuptools/compare/v70.0.0...v78.1.1)

---
updated-dependencies:
- dependency-name: setuptools
  dependency-version: 78.1.1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #8082: Bump setuptools from 70.0.0 to 78.1.1 in /evergreen/hang_analyzer

102788 of 181548 branches covered (56.62%)

217441 of 238634 relevant lines covered (91.12%)

5497200.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.99
/src/realm/table_view.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2016 Realm Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 **************************************************************************/
18

19
#include <realm/table_view.hpp>
20
#include <realm/column_integer.hpp>
21
#include <realm/index_string.hpp>
22
#include <realm/transaction.hpp>
23

24
#include <unordered_set>
25

26
using namespace realm;
27

28
TableView::TableView(TableView& src, Transaction* tr, PayloadPolicy policy_mode)
29
    : m_source_column_key(src.m_source_column_key)
31,467✔
30
{
68,274✔
31
    bool was_in_sync = src.is_in_sync();
68,274✔
32
    if (src.m_query)
68,274✔
33
        m_query = Query(*src.m_query, tr, policy_mode);
67,668✔
34
    m_table = tr->import_copy_of(src.m_table);
68,274✔
35

36
    if (policy_mode == PayloadPolicy::Stay)
68,274✔
37
        was_in_sync = false;
96✔
38

39
    VersionID src_version =
68,274✔
40
        dynamic_cast<Transaction*>(src.m_table->get_parent_group())->get_version_of_current_transaction();
68,274✔
41
    if (src_version != tr->get_version_of_current_transaction())
68,274✔
42
        was_in_sync = false;
18✔
43

44
    m_table = tr->import_copy_of(src.m_table);
68,274✔
45
    m_collection_source = tr->import_copy_of(src.m_collection_source);
68,274✔
46
    if (src.m_source_column_key) {
68,274✔
47
        m_linked_obj = tr->import_copy_of(src.m_linked_obj);
606✔
48
    }
606✔
49

50
    if (was_in_sync)
68,274✔
51
        get_dependencies(m_last_seen_versions);
68,154✔
52

53
    // don't use methods which throw after this point...or m_table_view_key_values will leak
54
    if (policy_mode == PayloadPolicy::Copy && src.m_key_values.is_attached()) {
68,274✔
55
        m_key_values = src.m_key_values;
702✔
56
    }
702✔
57
    else if (policy_mode == PayloadPolicy::Move && src.m_key_values.is_attached())
67,572✔
58
        // Requires that 'src' is a writable object
59
        m_key_values = std::move(src.m_key_values);
67,476✔
60
    else {
96✔
61
        m_key_values.create();
96✔
62
    }
96✔
63
    if (policy_mode == PayloadPolicy::Move) {
68,274✔
64
        src.m_last_seen_versions.clear();
67,476✔
65
    }
67,476✔
66
    m_descriptor_ordering = src.m_descriptor_ordering;
68,274✔
67
    m_limit = src.m_limit;
68,274✔
68
}
68,274✔
69

70
// Aggregates ----------------------------------------------------
71

72
template <typename T, Action AggregateOpType>
73
struct Aggregator {};
74

75
template <typename T>
76
struct Aggregator<T, act_Sum> {
77
    using AggType = typename aggregate_operations::Sum<typename util::RemoveOptional<T>::type>;
78
};
79

80
template <typename T>
81
struct Aggregator<T, act_Average> {
82
    using AggType = typename aggregate_operations::Average<typename util::RemoveOptional<T>::type>;
83
};
84

85
template <typename T>
86
struct Aggregator<T, act_Min> {
87
    using AggType = typename aggregate_operations::Minimum<typename util::RemoveOptional<T>::type>;
88
};
89

90
template <typename T>
91
struct Aggregator<T, act_Max> {
92
    using AggType = typename aggregate_operations::Maximum<typename util::RemoveOptional<T>::type>;
93
};
94

95
template <Action action, typename T>
96
Mixed TableView::aggregate(ColKey column_key, size_t* result_count, ObjKey* return_key) const
97
{
4,230✔
98
    static_assert(action == act_Sum || action == act_Max || action == act_Min || action == act_Average);
4,230✔
99
    REALM_ASSERT(m_table->valid_column(column_key));
4,230!
100

101
    size_t non_nulls = 0;
4,230✔
102
    typename Aggregator<T, action>::AggType agg;
4,230✔
103
    ObjKey last_accumulated_key = null_key;
4,230✔
104
    for (size_t tv_index = 0; tv_index < m_key_values.size(); ++tv_index) {
57,528!
105
        ObjKey key(get_key(tv_index));
53,298✔
106

107
        // skip detached references:
108
        if (key == realm::null_key)
53,298!
109
            continue;
×
110

111
        const Obj obj = m_table->try_get_object(key);
53,298✔
112
        // aggregation must be robust in the face of stale keys:
113
        if (!obj.is_valid())
53,298!
114
            continue;
24✔
115

116
        if (obj.is_null(column_key))
53,274!
117
            continue;
7,788✔
118

119
        auto v = obj.get<T>(column_key);
45,486✔
120
        if (agg.accumulate(v)) {
45,486!
121
            ++non_nulls;
30,792✔
122
            if constexpr (action == act_Min || action == act_Max) {
30,792✔
123
                last_accumulated_key = key;
14,988✔
124
            }
14,988✔
125
        }
30,792✔
126
    }
45,486✔
127

128
    if (result_count)
4,230!
129
        *result_count = non_nulls;
696✔
130

131
    if constexpr (action == act_Max || action == act_Min) {
4,230✔
132
        if (return_key) {
2,532!
133
            *return_key = last_accumulated_key;
2,040✔
134
        }
2,040✔
135
    }
1,266✔
136
    else {
1,698✔
137
        static_cast<void>(last_accumulated_key);
1,698✔
138
        static_cast<void>(return_key);
1,698✔
139
    }
1,698✔
140

141
    if (!agg.is_null()) {
4,230!
142
        return agg.result();
3,138✔
143
    }
3,138✔
144
    if (action == act_Sum) {
1,092✔
145
        if (std::is_same_v<T, Mixed>) {
×
146
            return Decimal128{0};
×
147
        }
×
148
        return T{};
×
149
    }
×
150
    return Mixed();
1,092✔
151
}
1,092✔
152

153
template <typename T>
154
size_t TableView::aggregate_count(ColKey column_key, T count_target) const
155
{
48✔
156
    REALM_ASSERT(m_table->valid_column(column_key));
48!
157

158
    if ((m_key_values.size()) == 0) {
48!
159
        return {};
×
160
    }
×
161

162
    size_t cnt = 0;
48✔
163
    for (size_t tv_index = 0; tv_index < m_key_values.size(); ++tv_index) {
240!
164
        ObjKey key(get_key(tv_index));
192✔
165

166
        // skip detached references:
167
        if (key == realm::null_key)
192!
168
            continue;
×
169

170
        const Obj obj = m_table->try_get_object(key);
192✔
171
        if (!obj.is_valid())
192!
172
            continue;
×
173

174
        auto v = obj.get<T>(column_key);
192✔
175
        if (v == count_target) {
192!
176
            cnt++;
102✔
177
        }
102✔
178
    }
192✔
179

180
    return cnt;
48✔
181
}
48✔
182

183
// Count
184
size_t TableView::count_int(ColKey column_key, int64_t target) const
185
{
12✔
186
    if (m_table->is_nullable(column_key))
12✔
187
        return aggregate_count<util::Optional<int64_t>>(column_key, target);
×
188
    else
12✔
189
        return aggregate_count<int64_t>(column_key, target);
12✔
190
}
12✔
191
size_t TableView::count_float(ColKey column_key, float target) const
192
{
12✔
193
    return aggregate_count<float>(column_key, target);
12✔
194
}
12✔
195
size_t TableView::count_double(ColKey column_key, double target) const
196
{
12✔
197
    return aggregate_count<double>(column_key, target);
12✔
198
}
12✔
199
size_t TableView::count_timestamp(ColKey column_key, Timestamp target) const
200
{
12✔
201
    return aggregate_count<Timestamp>(column_key, target);
12✔
202
}
12✔
203
size_t TableView::count_decimal(ColKey column_key, Decimal128 target) const
204
{
×
205
    return aggregate_count<Decimal128>(column_key, target);
×
206
}
×
207
size_t TableView::count_mixed(ColKey column_key, Mixed target) const
208
{
×
209
    return aggregate_count<Mixed>(column_key, target);
×
210
}
×
211

212
template <Action action>
213
std::optional<Mixed> TableView::aggregate(ColKey column_key, size_t* count, ObjKey* return_key) const
214
{
4,422✔
215
    static_assert(action == act_Sum || action == act_Max || action == act_Min || action == act_Average);
4,422✔
216
    m_table->check_column(column_key);
4,422✔
217
    if (column_key.is_collection()) {
4,422✔
218
        return std::nullopt;
48✔
219
    }
48✔
220

221
    switch (column_key.get_type()) {
4,374✔
222
        case col_type_Int:
1,596✔
223
            if (m_table->is_nullable(column_key))
1,596✔
224
                return aggregate<action, util::Optional<int64_t>>(column_key, count, return_key);
1,470✔
225
            return aggregate<action, int64_t>(column_key, count, return_key);
126✔
226
        case col_type_Float:
1,506✔
227
            return aggregate<action, float>(column_key, count, return_key);
1,506✔
228
        case col_type_Double:
342✔
229
            return aggregate<action, double>(column_key, count, return_key);
342✔
230
        case col_type_Timestamp:
465✔
231
            if constexpr (action == act_Min || action == act_Max) {
858✔
232
                return aggregate<action, Timestamp>(column_key, count, return_key);
786✔
233
            }
786✔
234
            break;
×
235
        case col_type_Decimal:
✔
236
            return aggregate<action, Decimal128>(column_key, count, return_key);
×
237
        case col_type_Mixed:
✔
238
            return aggregate<action, Mixed>(column_key, count, return_key);
×
239
        default:
✔
240
            break;
×
241
    }
4,374✔
242
    return util::none;
72✔
243
}
4,374✔
244

245
util::Optional<Mixed> TableView::min(ColKey column_key, ObjKey* return_key) const
246
{
1,290✔
247
    return aggregate<act_Min>(column_key, nullptr, return_key);
1,290✔
248
}
1,290✔
249

250
util::Optional<Mixed> TableView::max(ColKey column_key, ObjKey* return_key) const
251
{
1,302✔
252
    return aggregate<act_Max>(column_key, nullptr, return_key);
1,302✔
253
}
1,302✔
254

255
util::Optional<Mixed> TableView::sum(ColKey column_key) const
256
{
900✔
257
    return aggregate<act_Sum>(column_key, nullptr, nullptr);
900✔
258
}
900✔
259

260
util::Optional<Mixed> TableView::avg(ColKey column_key, size_t* value_count) const
261
{
930✔
262
    return aggregate<act_Average>(column_key, value_count, nullptr);
930✔
263
}
930✔
264

265
void TableView::to_json(std::ostream& out, JSONOutputMode mode) const
266
{
36✔
267
    // Represent table as list of objects
268
    out << "[";
36✔
269

270
    const size_t row_count = size();
36✔
271
    bool first = true;
36✔
272
    for (size_t r = 0; r < row_count; ++r) {
468✔
273
        if (ObjKey key = get_key(r)) {
432✔
274
            if (first) {
432✔
275
                first = false;
36✔
276
            }
36✔
277
            else {
396✔
278
                out << ",";
396✔
279
            }
396✔
280
            m_table->get_object(key).to_json(out, mode);
432✔
281
        }
432✔
282
    }
432✔
283

284
    out << "]";
36✔
285
}
36✔
286

287
bool TableView::depends_on_deleted_object() const
288
{
42✔
289
    if (m_collection_source) {
42✔
290
        return !m_collection_source->get_owning_obj().is_valid();
12✔
291
    }
12✔
292

293
    if (m_source_column_key && !m_linked_obj.is_valid()) {
30✔
294
        return true;
12✔
295
    }
12✔
296
    else if (m_query && m_query->m_source_table_view) {
18✔
297
        return m_query->m_source_table_view->depends_on_deleted_object();
6✔
298
    }
6✔
299
    return false;
12✔
300
}
30✔
301

302
void TableView::get_dependencies(TableVersions& ret) const
303
{
2,022,510✔
304
    auto table = m_table ? m_table.unchecked_ptr() : nullptr;
2,148,556,870✔
305
    if (m_source_column_key && m_linked_obj) {
2,022,510✔
306
        // m_source_column_key is set when this TableView was created by Table::get_backlink_view().
307
        if (auto linked_table = m_linked_obj.get_table()) {
2,112✔
308
            ret.emplace_back(linked_table->get_key(), linked_table->get_content_version());
2,112✔
309
        }
2,112✔
310
    }
2,112✔
311
    else if (m_query) {
2,114,130✔
312
        m_query->get_outside_versions(ret);
2,102,928✔
313
    }
2,102,928✔
314
    else {
2,147,494,849✔
315
        // This TableView was created by Table::get_distinct_view() or get_sorted_view() on collections
316
        ret.emplace_back(table->get_key(), table->get_content_version());
2,147,494,849✔
317
    }
2,147,494,849✔
318

319
    // Finally add dependencies from sort/distinct
320
    if (table) {
2,121,321✔
321
        m_descriptor_ordering.get_versions(table->get_parent_group(), ret);
2,121,321✔
322
    }
2,121,321✔
323
}
2,022,510✔
324

325
bool TableView::is_in_sync() const
326
{
396,393✔
327
    return m_table && !has_changed();
396,393✔
328
}
396,393✔
329

330
void TableView::sync_if_needed() const
331
{
250,443✔
332
    if (!is_in_sync()) {
250,443✔
333
        // FIXME: Is this a reasonable handling of constness?
334
        const_cast<TableView*>(this)->do_sync();
61,842✔
335
    }
61,842✔
336
}
250,443✔
337

338
void TableView::update_query(const Query& q)
339
{
12✔
340
    REALM_ASSERT(m_query);
12✔
341
    REALM_ASSERT(m_query->m_table);
12✔
342
    REALM_ASSERT(m_query->m_table == q.m_table);
12✔
343

344
    m_query = q;
12✔
345
    do_sync();
12✔
346
}
12✔
347

348
void TableView::clear()
349
{
9,804✔
350
    m_table.check();
9,804✔
351

352
    // If distinct is applied then removing an object may leave us out of sync
353
    // if there's another object with the same value in the distinct column
354
    // as the removed object
355
    bool sync_to_keep =
9,804✔
356
        m_last_seen_versions == get_dependency_versions() && !m_descriptor_ordering.will_apply_distinct();
9,804✔
357

358
    // Remove all invalid keys
359
    auto it = std::remove_if(m_key_values.begin(), m_key_values.end(), [this](const ObjKey& key) {
2,512,044✔
360
        return !m_table->is_valid(key);
2,512,044✔
361
    });
2,512,044✔
362
    m_key_values.erase(it, m_key_values.end());
9,804✔
363

364
    _impl::TableFriend::batch_erase_objects(*get_parent(), m_key_values); // Throws
9,804✔
365

366
    // It is important to not accidentally bring us in sync, if we were
367
    // not in sync to start with:
368
    if (sync_to_keep)
9,804✔
369
        m_last_seen_versions = get_dependency_versions();
9,786✔
370
}
9,804✔
371

372
void TableView::distinct(ColKey column)
373
{
144✔
374
    distinct(DistinctDescriptor({{column}}));
144✔
375
}
144✔
376

377
/// Remove rows that are duplicated with respect to the column set passed as argument.
378
/// Will keep original sorting order so that you can both have a distinct and sorted view.
379
void TableView::distinct(DistinctDescriptor columns)
380
{
432✔
381
    m_descriptor_ordering.append_distinct(std::move(columns));
432✔
382
    m_descriptor_ordering.collect_dependencies(m_table.unchecked_ptr());
432✔
383

384
    do_sync();
432✔
385
}
432✔
386

387
void TableView::limit(LimitDescriptor lim)
388
{
12✔
389
    m_descriptor_ordering.append_limit(std::move(lim));
12✔
390
    do_sync();
12✔
391
}
12✔
392

393
void TableView::filter(FilterDescriptor filter)
394
{
12✔
395
    m_descriptor_ordering.append_filter(std::move(filter));
12✔
396
    do_sync();
12✔
397
}
12✔
398

399
void TableView::apply_descriptor_ordering(const DescriptorOrdering& new_ordering)
400
{
21,864✔
401
    m_descriptor_ordering = new_ordering;
21,864✔
402
    m_descriptor_ordering.collect_dependencies(m_table.unchecked_ptr());
21,864✔
403

404
    do_sync();
21,864✔
405
}
21,864✔
406

407
std::string TableView::get_descriptor_ordering_description() const
408
{
18✔
409
    return m_descriptor_ordering.get_description(m_table);
18✔
410
}
18✔
411

412
// Sort according to one column
413
void TableView::sort(ColKey column, bool ascending)
414
{
438✔
415
    sort(SortDescriptor({{column}}, {ascending}));
438✔
416
}
438✔
417

418
// Sort according to multiple columns, user specified order on each column
419
void TableView::sort(SortDescriptor order)
420
{
1,008✔
421
    m_descriptor_ordering.append_sort(std::move(order), SortDescriptor::MergeMode::prepend);
1,008✔
422
    m_descriptor_ordering.collect_dependencies(m_table.unchecked_ptr());
1,008✔
423

424
    apply_descriptors(m_descriptor_ordering);
1,008✔
425
}
1,008✔
426

427

428
void TableView::do_sync()
429
{
1,542,033✔
430
    util::CriticalSection cs(m_race_detector);
1,542,033✔
431
    // This TableView can be "born" from 4 different sources:
432
    // - LinkView
433
    // - Query::find_all()
434
    // - Table::get_distinct_view()
435
    // - Table::get_backlink_view()
436
    // Here we sync with the respective source.
437
    m_last_seen_versions.clear();
1,542,033✔
438

439
    if (m_collection_source) {
1,542,033✔
440
        m_key_values.clear();
102✔
441
        auto sz = m_collection_source->size();
102✔
442
        for (size_t i = 0; i < sz; i++) {
330✔
443
            m_key_values.add(m_collection_source->get_key(i));
228✔
444
        }
228✔
445
    }
102✔
446
    else if (m_source_column_key) {
1,541,931✔
447
        m_key_values.clear();
756✔
448
        if (m_table && m_linked_obj.is_valid()) {
756✔
449
            if (m_table->valid_column(m_source_column_key)) { // return empty result, if column has been removed
744✔
450
                ColKey backlink_col = m_table->get_opposite_column(m_source_column_key);
738✔
451
                REALM_ASSERT(backlink_col);
738✔
452
                auto backlinks = m_linked_obj.get_all_backlinks(backlink_col);
738✔
453
                for (auto k : backlinks) {
738✔
454
                    m_key_values.add(k);
708✔
455
                }
708✔
456
            }
738✔
457
        }
744✔
458
    }
756✔
459
    // FIXME: Unimplemented for link to a column
460
    else {
1,541,175✔
461
        REALM_ASSERT(m_query);
1,541,175✔
462
        m_query->m_table.check();
1,541,175✔
463

464
        // valid query, so clear earlier results and reexecute it.
465
        if (m_key_values.is_attached())
1,541,175✔
466
            m_key_values.clear();
1,567,284✔
467
        else
2,147,487,373✔
468
            m_key_values.create();
2,147,487,373✔
469

470
        if (m_query->m_view)
1,541,175✔
471
            m_query->m_view->sync_if_needed();
1,101✔
472
        size_t limit = m_limit;
1,541,175✔
473
        if (!m_descriptor_ordering.is_empty()) {
1,541,175✔
474
            auto type = m_descriptor_ordering[0]->get_type();
13,650✔
475
            if (type == DescriptorType::Limit) {
13,650✔
476
                size_t l = static_cast<const LimitDescriptor*>(m_descriptor_ordering[0])->get_limit();
138✔
477
                if (l < limit)
138✔
478
                    limit = l;
138✔
479
            }
138✔
480
        }
13,650✔
481
        QueryStateFindAll<std::vector<ObjKey>> st(m_key_values, limit);
1,541,175✔
482
        m_query->do_find_all(st);
1,541,175✔
483
    }
1,541,175✔
484

485
    apply_descriptors(m_descriptor_ordering);
1,542,033✔
486

487
    get_dependencies(m_last_seen_versions);
1,542,033✔
488
}
1,542,033✔
489

490
void TableView::apply_descriptors(const DescriptorOrdering& ordering)
491
{
1,604,457✔
492
    if (ordering.is_empty())
1,604,457✔
493
        return;
1,633,719✔
494
    size_t sz = size();
2,147,499,064✔
495
    if (sz == 0)
2,147,499,064✔
496
        return;
198✔
497

498
    // Gather the current rows into a container we can use std algorithms on
499
    size_t detached_ref_count = 0;
2,147,498,965✔
500
    BaseDescriptor::IndexPairs index_pairs;
2,147,498,965✔
501
    bool using_indexpairs = false;
2,147,498,965✔
502

503
    auto apply_indexpairs = [&] {
2,147,498,965✔
504
        m_key_values.clear();
14,316✔
505
        for (auto& pair : index_pairs) {
176,319✔
506
            m_key_values.add(pair.key_for_object);
176,319✔
507
        }
176,319✔
508
        for (size_t t = 0; t < detached_ref_count; ++t)
14,316✔
509
            m_key_values.add(null_key);
×
510
        using_indexpairs = false;
14,316✔
511
    };
14,316✔
512

513
    auto use_indexpairs = [&] {
2,147,498,965✔
514
        index_pairs.reserve(sz);
14,340✔
515
        index_pairs.clear();
14,340✔
516
        // always put any detached refs at the end of the sort
517
        // FIXME: reconsider if this is the right thing to do
518
        // FIXME: consider specialized implementations in derived classes
519
        // (handling detached refs is not required in linkviews)
520
        for (size_t t = 0; t < sz; t++) {
252,972✔
521
            ObjKey key = get_key(t);
238,632✔
522
            if (m_table->is_valid(key)) {
238,632✔
523
                index_pairs.emplace_back(key, t);
238,632✔
524
            }
238,632✔
525
            else
×
526
                ++detached_ref_count;
×
527
        }
238,632✔
528
        using_indexpairs = true;
14,340✔
529
    };
14,340✔
530

531
    const int num_descriptors = int(ordering.size());
2,147,498,965✔
532
    for (int desc_ndx = 0; desc_ndx < num_descriptors; ++desc_ndx) {
2,147,506,789✔
533
        const BaseDescriptor* base_descr = ordering[desc_ndx];
15,648✔
534
        const BaseDescriptor* next = ((desc_ndx + 1) < num_descriptors) ? ordering[desc_ndx + 1] : nullptr;
15,648✔
535

536
        // Some descriptors, like Sort and Distinct, needs us to gather the current rows
537
        // into a container we can use std algorithms on
538
        if (base_descr->need_indexpair()) {
15,648✔
539
            if (!using_indexpairs) {
14,970✔
540
                use_indexpairs();
14,340✔
541
            }
14,340✔
542

543
            BaseDescriptor::Sorter predicate = base_descr->sorter(*m_table, index_pairs);
14,970✔
544

545
            // Sorting can be specified by multiple columns, so that if two entries in the first column are
546
            // identical, then the rows are ordered according to the second column, and so forth. For the
547
            // first column, we cache all the payload of fields of the view in a std::vector<Mixed>
548
            predicate.cache_first_column(index_pairs);
14,970✔
549

550
            base_descr->execute(index_pairs, predicate, next);
14,970✔
551
        }
14,970✔
552
        else {
678✔
553
            if (using_indexpairs) {
678✔
554
                apply_indexpairs();
450✔
555
            }
450✔
556
            base_descr->execute(*m_table, m_key_values, next);
678✔
557
            sz = size();
678✔
558
        }
678✔
559
    }
15,648✔
560
    // Apply the results
561
    if (using_indexpairs) {
2,147,498,965✔
562
        apply_indexpairs();
13,866✔
563
    }
13,866✔
564
}
2,147,498,965✔
565

566
bool TableView::is_in_table_order() const
567
{
3,342✔
568
    if (!m_table) {
3,342✔
569
        return false;
6✔
570
    }
6✔
571
    else if (m_collection_source) {
3,336✔
572
        return false;
6✔
573
    }
6✔
574
    else if (m_source_column_key) {
3,330✔
575
        return false;
6✔
576
    }
6✔
577
    else if (!m_query) {
3,324✔
578
        return false;
66✔
579
    }
66✔
580
    else {
3,258✔
581
        m_query->m_table.check();
3,258✔
582
        return m_query->produces_results_in_table_order() && !m_descriptor_ordering.will_apply_sort();
3,258✔
583
    }
3,258✔
584
}
3,342✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc