@@ -1787,60 +1787,104 @@ class FlatbuffersJoinExprEvaluator {
17871787 }
17881788
17891789 const tuix::JoinExpr* join_expr = flatbuffers::GetRoot<tuix::JoinExpr>(buf);
1790- join_type = join_expr->join_type ();
17911790
1792- if (join_expr->left_keys ()->size () != join_expr->right_keys ()->size ()) {
1793- throw std::runtime_error (" Mismatched join key lengths" );
1794- }
1795- for (auto key_it = join_expr->left_keys ()->begin ();
1796- key_it != join_expr->left_keys ()->end (); ++key_it) {
1797- left_key_evaluators.emplace_back (
1798- std::unique_ptr<FlatbuffersExpressionEvaluator>(
1799- new FlatbuffersExpressionEvaluator (*key_it)));
1791+ join_type = join_expr->join_type ();
1792+ if (join_expr->condition () != NULL ) {
1793+ condition_eval = std::unique_ptr<FlatbuffersExpressionEvaluator>(
1794+ new FlatbuffersExpressionEvaluator (join_expr->condition ()));
18001795 }
1801- for (auto key_it = join_expr->right_keys ()->begin ();
1802- key_it != join_expr->right_keys ()->end (); ++key_it) {
1803- right_key_evaluators.emplace_back (
1804- std::unique_ptr<FlatbuffersExpressionEvaluator>(
1805- new FlatbuffersExpressionEvaluator (*key_it)));
1796+ is_equi_join = false ;
1797+
1798+ if (join_expr->left_keys () != NULL && join_expr->right_keys () != NULL ) {
1799+ is_equi_join = true ;
1800+ if (join_expr->condition () != NULL ) {
1801+ throw std::runtime_error (" Equi join cannot have condition" );
1802+ }
1803+ if (join_expr->left_keys ()->size () != join_expr->right_keys ()->size ()) {
1804+ throw std::runtime_error (" Mismatched join key lengths" );
1805+ }
1806+ for (auto key_it = join_expr->left_keys ()->begin ();
1807+ key_it != join_expr->left_keys ()->end (); ++key_it) {
1808+ left_key_evaluators.emplace_back (
1809+ std::unique_ptr<FlatbuffersExpressionEvaluator>(
1810+ new FlatbuffersExpressionEvaluator (*key_it)));
1811+ }
1812+ for (auto key_it = join_expr->right_keys ()->begin ();
1813+ key_it != join_expr->right_keys ()->end (); ++key_it) {
1814+ right_key_evaluators.emplace_back (
1815+ std::unique_ptr<FlatbuffersExpressionEvaluator>(
1816+ new FlatbuffersExpressionEvaluator (*key_it)));
1817+ }
18061818 }
18071819 }
18081820
1809- /* *
1810- * Return true if the given row is from the primary table, indicated by its first field, which
1811- * must be an IntegerField .
1821+ /* * Return true if the given row is from the primary table, indicated by its first field, which
1822+ * must be an IntegerField.
1823+ * Rows MUST have been tagged in Scala .
18121824 */
18131825 bool is_primary (const tuix::Row *row) {
18141826 return static_cast <const tuix::IntegerField *>(
18151827 row->field_values ()->Get (0 )->value ())->value () == 0 ;
18161828 }
18171829
1818- /* * Return true if the two rows are from the same join group. */
1819- bool is_same_group (const tuix::Row *row1, const tuix::Row *row2) {
1820- auto &row1_evaluators = is_primary (row1) ? left_key_evaluators : right_key_evaluators;
1821- auto &row2_evaluators = is_primary (row2) ? left_key_evaluators : right_key_evaluators;
1830+ /* * Returns the row evaluator corresponding to the primary row
1831+ * Rows MUST have been tagged in Scala.
1832+ */
1833+ const tuix::Row *get_primary_row (
1834+ const tuix::Row *row1, const tuix::Row *row2) {
1835+ return is_primary (row1) ? row1 : row2;
1836+ }
18221837
1838+ /* * Return true if the two rows satisfy the join condition. */
1839+ bool eval_condition (const tuix::Row *row1, const tuix::Row *row2) {
18231840 builder.Clear ();
1841+ bool row1_equals_row2;
1842+
1843+ /* * Check equality for equi joins. If it is a non-equi join,
1844+ * the key evaluators will be empty, so the code never enters the for loop.
1845+ */
1846+ auto &row1_evaluators = is_primary (row1) ? left_key_evaluators : right_key_evaluators;
1847+ auto &row2_evaluators = is_primary (row2) ? left_key_evaluators : right_key_evaluators;
18241848 for (uint32_t i = 0 ; i < row1_evaluators.size (); i++) {
18251849 const tuix::Field *row1_eval_tmp = row1_evaluators[i]->eval (row1);
18261850 auto row1_eval_offset = flatbuffers_copy (row1_eval_tmp, builder);
1851+ auto row1_field = flatbuffers::GetTemporaryPointer<tuix::Field>(builder, row1_eval_offset);
1852+
18271853 const tuix::Field *row2_eval_tmp = row2_evaluators[i]->eval (row2);
18281854 auto row2_eval_offset = flatbuffers_copy (row2_eval_tmp, builder);
1855+ auto row2_field = flatbuffers::GetTemporaryPointer<tuix::Field>(builder, row2_eval_offset);
18291856
1830- bool row1_equals_row2 =
1857+ flatbuffers::Offset<tuix::Field> comparison = eval_binary_comparison<tuix::EqualTo, std::equal_to>(
1858+ builder,
1859+ row1_field,
1860+ row2_field);
1861+ row1_equals_row2 =
18311862 static_cast <const tuix::BooleanField *>(
18321863 flatbuffers::GetTemporaryPointer<tuix::Field>(
18331864 builder,
1834- eval_binary_comparison<tuix::EqualTo, std::equal_to>(
1835- builder,
1836- flatbuffers::GetTemporaryPointer<tuix::Field>(builder, row1_eval_offset),
1837- flatbuffers::GetTemporaryPointer<tuix::Field>(builder, row2_eval_offset)))
1838- ->value ())->value ();
1865+ comparison)->value ())->value ();
18391866
18401867 if (!row1_equals_row2) {
18411868 return false ;
18421869 }
18431870 }
1871+
1872+ /* Check condition for non-equi joins */
1873+ if (!is_equi_join) {
1874+ std::vector<flatbuffers::Offset<tuix::Field>> concat_fields;
1875+ for (auto field : *row1->field_values ()) {
1876+ concat_fields.push_back (flatbuffers_copy<tuix::Field>(field, builder));
1877+ }
1878+ for (auto field : *row2->field_values ()) {
1879+ concat_fields.push_back (flatbuffers_copy<tuix::Field>(field, builder));
1880+ }
1881+ flatbuffers::Offset<tuix::Row> concat = tuix::CreateRowDirect (builder, &concat_fields);
1882+ const tuix::Row *concat_ptr = flatbuffers::GetTemporaryPointer<tuix::Row>(builder, concat);
1883+
1884+ const tuix::Field *condition_result = condition_eval->eval (concat_ptr);
1885+
1886+ return static_cast <const tuix::BooleanField *>(condition_result->value ())->value ();
1887+ }
18441888 return true ;
18451889 }
18461890
@@ -1853,6 +1897,8 @@ class FlatbuffersJoinExprEvaluator {
18531897 tuix::JoinType join_type;
18541898 std::vector<std::unique_ptr<FlatbuffersExpressionEvaluator>> left_key_evaluators;
18551899 std::vector<std::unique_ptr<FlatbuffersExpressionEvaluator>> right_key_evaluators;
1900+ bool is_equi_join;
1901+ std::unique_ptr<FlatbuffersExpressionEvaluator> condition_eval;
18561902};
18571903
18581904class AggregateExpressionEvaluator {
0 commit comments