1. Summary
  2. Files
  3. Support
  4. Report Spam
  5. Create account
  6. Log in

Changeset 11089

Show
Ignore:
Timestamp:
05/22/13 04:50:45 (11 months ago)
Author:
svn-sync
Message:

Synchronized with https://dev.naver.com/svn/cubrid/branches/RB-9.2.0
Source Revision: 8375, Author: xkyu, Msg:
[CUBRIDSUS-11129][CR] fix rewrite outer join issue

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • cubrid/branches/RB-9.2.0/src/optimizer/query_rewrite.c

    r10750 r11089  
    9191  bool found_outerjoin; 
    9292}; 
     93 
     94static PT_NODE *qo_reset_location (PARSER_CONTEXT * parser, PT_NODE * node, 
     95                                   void *arg, int *continue_walk); 
    9396 
    9497/* 
     
    56055608  PT_NODE *spec, *prev_spec, *expr, *ns; 
    56065609  SPEC_ID_INFO info; 
     5610  RESET_LOCATION_INFO locate_info; 
    56075611  int nullable_cnt;             /* nullable terms count */ 
     5612  bool rewrite_again; 
    56085613 
    56095614  if (node->node_type != PT_SELECT) 
     
    56215626    } 
    56225627 
    5623   /* traverse spec list */ 
    5624   prev_spec = NULL; 
    5625   for (spec = node->info.query.q.select.from; 
    5626        spec; prev_spec = spec, spec = spec->next) 
    5627     { 
    5628       if (spec->info.spec.join_type == PT_JOIN_LEFT_OUTER 
    5629           || spec->info.spec.join_type == PT_JOIN_RIGHT_OUTER) 
    5630         { 
    5631           if (spec->info.spec.join_type == PT_JOIN_LEFT_OUTER) 
    5632             { 
    5633               info.id = spec->info.spec.id; 
    5634             } 
    5635           else if (prev_spec != NULL) 
    5636             { 
    5637               info.id = prev_spec->info.spec.id; 
    5638             } 
    5639  
    5640           info.appears = false; 
    5641           nullable_cnt = 0; 
    5642  
    5643           /* search where list */ 
    5644           for (expr = node->info.query.q.select.where; 
    5645                expr; expr = expr->next) 
    5646             { 
    5647  
    5648               /* skip out non-null RANGE sarg term only used for index scan; 
    5649                * 'attr RANGE ( Min ge_inf )' 
    5650                */ 
    5651               if (PT_EXPR_INFO_IS_FLAGED (expr, PT_EXPR_INFO_FULL_RANGE)) 
    5652                 { 
    5653                   continue; 
    5654                 } 
    5655  
    5656               if (expr->node_type == PT_EXPR 
    5657                   && expr->info.expr.location == 0 
    5658                   && expr->info.expr.op != PT_IS_NULL 
    5659                   && expr->or_next == NULL) 
    5660                 { 
    5661                   (void) parser_walk_leaves (parser, expr, 
    5662                                              qo_get_name_by_spec_id, &info, 
    5663                                              qo_check_nullable_expr, 
    5664                                              &nullable_cnt); 
    5665                   /* have found a term which makes outer join to inner */ 
    5666                   if (info.appears && nullable_cnt == 0) 
     5628  do 
     5629    { 
     5630      rewrite_again = false; 
     5631      /* traverse spec list */ 
     5632      prev_spec = NULL; 
     5633      for (spec = node->info.query.q.select.from; 
     5634           spec; prev_spec = spec, spec = spec->next) 
     5635        { 
     5636          if (spec->info.spec.join_type == PT_JOIN_LEFT_OUTER 
     5637              || spec->info.spec.join_type == PT_JOIN_RIGHT_OUTER) 
     5638            { 
     5639              if (spec->info.spec.join_type == PT_JOIN_LEFT_OUTER) 
     5640                { 
     5641                  info.id = spec->info.spec.id; 
     5642                } 
     5643              else if (prev_spec != NULL) 
     5644                { 
     5645                  info.id = prev_spec->info.spec.id; 
     5646                } 
     5647 
     5648              info.appears = false; 
     5649              nullable_cnt = 0; 
     5650 
     5651              /* search where list */ 
     5652              for (expr = node->info.query.q.select.where; 
     5653                   expr; expr = expr->next) 
     5654                { 
     5655 
     5656                  /* skip out non-null RANGE sarg term only used for index scan; 
     5657                   * 'attr RANGE ( Min ge_inf )' 
     5658                   */ 
     5659                  if (PT_EXPR_INFO_IS_FLAGED (expr, PT_EXPR_INFO_FULL_RANGE)) 
    56675660                    { 
    5668                       spec->info.spec.join_type = PT_JOIN_INNER; 
    5669                       /* rewrite the following connected right outer join 
    5670                        * to inner join */ 
    5671                       for (ns = spec->next;     /* traverse next spec */ 
    5672                            ns && ns->info.spec.join_type != PT_JOIN_NONE; 
    5673                            ns = ns->next) 
     5661                      continue; 
     5662                    } 
     5663 
     5664                  if (expr->node_type == PT_EXPR 
     5665                      && expr->info.expr.location == 0 
     5666                      && expr->info.expr.op != PT_IS_NULL 
     5667                      && expr->or_next == NULL) 
     5668                    { 
     5669                      (void) parser_walk_leaves (parser, expr, 
     5670                                                 qo_get_name_by_spec_id, 
     5671                                                 &info, 
     5672                                                 qo_check_nullable_expr, 
     5673                                                 &nullable_cnt); 
     5674                      /* have found a term which makes outer join to inner */ 
     5675                      if (info.appears && nullable_cnt == 0) 
    56745676                        { 
    5675                           if (ns->info.spec.join_type == PT_JOIN_RIGHT_OUTER) 
    5676                             ns->info.spec.join_type = PT_JOIN_INNER; 
     5677                          rewrite_again = true; 
     5678                          spec->info.spec.join_type = PT_JOIN_INNER; 
     5679 
     5680                          locate_info.start = spec->info.spec.location; 
     5681                          locate_info.end = locate_info.start; 
     5682                          (void) parser_walk_tree (parser, 
     5683                                                   node->info.query.q.select. 
     5684                                                   where, qo_reset_location, 
     5685                                                   &locate_info, NULL, NULL); 
     5686 
     5687                          /* rewrite the following connected right outer join 
     5688                           * to inner join */ 
     5689                          for (ns = spec->next; /* traverse next spec */ 
     5690                               ns && ns->info.spec.join_type != PT_JOIN_NONE; 
     5691                               ns = ns->next) 
     5692                            { 
     5693                              if (ns->info.spec.join_type == 
     5694                                  PT_JOIN_RIGHT_OUTER) 
     5695                                { 
     5696                                  ns->info.spec.join_type = PT_JOIN_INNER; 
     5697                                  locate_info.start = ns->info.spec.location; 
     5698                                  locate_info.end = locate_info.start; 
     5699                                  (void) parser_walk_tree (parser, 
     5700                                                           node->info.query.q. 
     5701                                                           select.where, 
     5702                                                           qo_reset_location, 
     5703                                                           &locate_info, NULL, 
     5704                                                           NULL); 
     5705                                } 
     5706                            } 
     5707                          break; 
    56775708                        } 
    5678                       break; 
    56795709                    } 
    56805710                } 
    56815711            } 
    5682         } 
    5683  
    5684       if (spec->info.spec.derived_table 
    5685           && spec->info.spec.derived_table_type == PT_IS_SUBQUERY) 
    5686         { 
    5687           /* apply qo_rewrite_outerjoin() to derived table's subquery */ 
    5688           (void) parser_walk_tree (parser, spec->info.spec.derived_table, 
    5689                                    qo_rewrite_outerjoin, NULL, NULL, NULL); 
    5690         } 
    5691     } 
     5712 
     5713          if (spec->info.spec.derived_table 
     5714              && spec->info.spec.derived_table_type == PT_IS_SUBQUERY) 
     5715            { 
     5716              /* apply qo_rewrite_outerjoin() to derived table's subquery */ 
     5717              (void) parser_walk_tree (parser, spec->info.spec.derived_table, 
     5718                                       qo_rewrite_outerjoin, NULL, NULL, 
     5719                                       NULL); 
     5720            } 
     5721        } 
     5722    } 
     5723  while (rewrite_again); 
    56925724 
    56935725  *continue_walk = PT_LIST_WALK;