Skip to content
  • Roy Lyseng's avatar
    34a9bad0
    Bug#25526439: Assertion failed: is_fixed_or_outer_ref(this) · 34a9bad0
    Roy Lyseng authored
    Bug#25071305: Assertion failed: first_execution || !tl->is_view_or_derived() ...
    Bug#24716127: Incorrect behavior by insert statement with "on duplicate ..."
    
    This is a combined fix for three regression bugs in INSERT resolving
    that came after WL#5094 refactoring.
    
    The main problem here is about bad sequence of resolver actions, as
    WL#5094 introduced one sequence for all INSERT syntax that proved to
    be insufficient. The problem was that apply_local_transforms() was
    sometimes not performed for subqueries in the INSERT ... ON DUPLICATE KEY
    UPDATE clause.
    
    It is necessary to know one implementation detail in order to grasp the
    full problem: Subqueries on INSERT ... VALUES clauses and subqueries in
    ON DUPLICATE KEY UPDATE clauses are attached to the last query block of
    the query expression of the INSERT statement, even though they are not
    actually referenced from this query block. And apply_local_transforms()
    will only be applied to subquery objects when called from an outermost
    query block.
    
    The solution is to identify three distinct cases for ON DUPLICATE KEY
    UPDATE resolving, with their required resolver sequences:
    
    1. INSERT INTO t ... VALUES ... ON DUPLICATE KEY UPDATE ...
       - Resolve VALUES expressions.
       - Resolve ON DUPLICATE KEY UPDATE expressions.
       - Call apply_local_transforms() on outer-most query block, which
         will include any subqueries in VALUES expressions.
    
    2. INSERT INTO t ... SELECT <non-union> ON DUPLICATE KEY UPDATE ...
       - Resolve SELECT query block, but do not call apply_local_transforms().
       - Combine context for SELECT query block and INSERT table
         (if the query block is non-grouped).
       - Resolve ON DUPLICATE KEY UPDATE expressions.
       - Call apply_local_transforms() on outer-most query block.
    
    3. INSERT INTO t ... SELECT ... UNION ... ON DUPLICATE KEY UPDATE ...
       - Resolve ON DUPLICATE KEY UPDATE expressions.
         (the outer query block may stay unresolved because there are no
          references into it).
       - Resolve the query expression, include calling apply_local_transforms()
         which will also include any subqueries in ON DUPLICATE KEY UPDATE
         clauses.
    
    In addition, we have extended with two new subquery context types:
    CTX_INSERT_VALUES and CTX_INSERT_UPDATE. They are used to generally
    provide more information about the parsing process, and in particular
    make it possible to build AST without outer references from subqueries
    in INSERT ... VALUES statements and in INSERT ... ON DUPLICATE KEY UPDATE
    statements.
    34a9bad0
    Bug#25526439: Assertion failed: is_fixed_or_outer_ref(this)
    Roy Lyseng authored
    Bug#25071305: Assertion failed: first_execution || !tl->is_view_or_derived() ...
    Bug#24716127: Incorrect behavior by insert statement with "on duplicate ..."
    
    This is a combined fix for three regression bugs in INSERT resolving
    that came after WL#5094 refactoring.
    
    The main problem here is about bad sequence of resolver actions, as
    WL#5094 introduced one sequence for all INSERT syntax that proved to
    be insufficient. The problem was that apply_local_transforms() was
    sometimes not performed for subqueries in the INSERT ... ON DUPLICATE KEY
    UPDATE clause.
    
    It is necessary to know one implementation detail in order to grasp the
    full problem: Subqueries on INSERT ... VALUES clauses and subqueries in
    ON DUPLICATE KEY UPDATE clauses are attached to the last query block of
    the query expression of the INSERT statement, even though they are not
    actually referenced from this query block. And apply_local_transforms()
    will only be applied to subquery objects when called from an outermost
    query block.
    
    The solution is to identify three distinct cases for ON DUPLICATE KEY
    UPDATE resolving, with their required resolver sequences:
    
    1. INSERT INTO t ... VALUES ... ON DUPLICATE KEY UPDATE ...
       - Resolve VALUES expressions.
       - Resolve ON DUPLICATE KEY UPDATE expressions.
       - Call apply_local_transforms() on outer-most query block, which
         will include any subqueries in VALUES expressions.
    
    2. INSERT INTO t ... SELECT <non-union> ON DUPLICATE KEY UPDATE ...
       - Resolve SELECT query block, but do not call apply_local_transforms().
       - Combine context for SELECT query block and INSERT table
         (if the query block is non-grouped).
       - Resolve ON DUPLICATE KEY UPDATE expressions.
       - Call apply_local_transforms() on outer-most query block.
    
    3. INSERT INTO t ... SELECT ... UNION ... ON DUPLICATE KEY UPDATE ...
       - Resolve ON DUPLICATE KEY UPDATE expressions.
         (the outer query block may stay unresolved because there are no
          references into it).
       - Resolve the query expression, include calling apply_local_transforms()
         which will also include any subqueries in ON DUPLICATE KEY UPDATE
         clauses.
    
    In addition, we have extended with two new subquery context types:
    CTX_INSERT_VALUES and CTX_INSERT_UPDATE. They are used to generally
    provide more information about the parsing process, and in particular
    make it possible to build AST without outer references from subqueries
    in INSERT ... VALUES statements and in INSERT ... ON DUPLICATE KEY UPDATE
    statements.
Loading