Skip to content

Bug: SQL logic error in MySQL Storage due to missing parentheses in WHERE clause #677

@xiluoduyu

Description

@xiluoduyu

Steps to reproduce

When using watermill-sql with MySQL and a custom GenerateWhereClause that contains an OR condition (e.g., for delayed messages), the final SQL query logic becomes corrupted because AND has higher precedence than OR.

Example Scenario:

  • Base condition: acked = 0
  • Dynamic condition: delayed_until <= NOW() OR delayed_until IS NULL

The generated SQL currently looks like:

SELECT ... WHERE acked = 0 AND delayed_until <= NOW() OR delayed_until IS NULL

Expected behavior

The dynamic condition should be wrapped in parentheses to maintain logical integrity:

SELECT ... WHERE acked = 0 AND (delayed_until <= NOW() OR delayed_until IS NULL)

Actual behavior

The SQL is interpreted as (acked = 0 AND delayed_until <= NOW()) OR (delayed_until IS NULL).

This causes messages where delayed_until IS NULL to be picked up even if they are already acked (acked = 1). This leads to infinite message duplication and high database load, as the same message is processed over and over again.

Possible solution

I have already submitted a fix here: ThreeDotsLabs/watermill-sql/pull/58.

This is a critical logic bug affecting data consistency in MySQL-based queues. Please consider reviewing the linked PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions