Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

job-iteration can cause infinite loop when using multi-column cursor in different tables with the same attribute #457

Open
pedropb opened this issue Feb 2, 2024 · 1 comment

Comments

@pedropb
Copy link
Contributor

pedropb commented Feb 2, 2024

Reproduction steps:

  • Run dev test on branch pb-bug-multi-cursor-different-tables
  • See commit for more details: ec50219

Expected behaviour:

  • Cursor should always move forward

Other notes

@pedropb
Copy link
Contributor Author

pedropb commented Feb 2, 2024

My initial investigation points to cursor_value not considering the table names when updating the cursor value.

These are the queries logged:

Product Load (0.9ms)  SELECT `products`.* FROM `products` INNER JOIN `comments` ON `comments`.`product_id` = `products`.`id` ORDER BY products.id,comments.id LIMIT 2
Product Load (1.0ms)  SELECT `products`.* FROM `products` INNER JOIN `comments` ON `comments`.`product_id` = `products`.`id` WHERE (products.id > '2' OR (products.id = '2' AND (comments.id > '2'))) ORDER BY products.id,comments.id LIMIT 2
Product Load (1.0ms)  SELECT `products`.* FROM `products` INNER JOIN `comments` ON `comments`.`product_id` = `products`.`id` WHERE (products.id > '3' OR (products.id = '3' AND (comments.id > '3'))) ORDER BY products.id,comments.id LIMIT 2

vs the expected positions:

# [ product.id, comment.id ]
[[1, 1], [2, 2], [2, 3], [3, 4], [3, 5], [3, 6]]

Once the cursor hits product.id = 3 it gets stuck, because the queries always returns [3, 4], [3, 5], and cursor_value does not use the table_name (iow: column.to_s.split(".").first) on @columns to update the value on the cursor:

def cursor_value(record)
positions = @columns.map do |column|
attribute_name = column.to_s.split(".").last
column_value(record, attribute_name)
end
return positions.first if positions.size == 1
positions
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant