~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

  • Committer: Eric Day
  • Date: 2010-01-07 20:02:38 UTC
  • mfrom: (1259.4.2 staging)
  • mto: This revision was merged to the branch mainline in revision 1271.
  • Revision ID: eday@oddments.org-20100107200238-uqw8v6kv9pl7nny5
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 * @{
28
28
 */
29
29
 
30
 
#include "drizzled/server_includes.h"
 
30
#include "config.h"
 
31
 
 
32
#include <float.h>
 
33
#include <math.h>
 
34
 
31
35
#include "drizzled/item/cache.h"
32
36
#include "drizzled/item/cmpfunc.h"
33
37
#include "drizzled/item/copy_string.h"
46
50
#include "drizzled/optimizer/key_use.h"
47
51
#include "drizzled/optimizer/range.h"
48
52
#include "drizzled/optimizer/sum.h"
 
53
#include "drizzled/optimizer/explain_plan.h"
49
54
#include "drizzled/records.h"
50
 
#include "mysys/my_bit.h"
 
55
#include "drizzled/probes.h"
 
56
#include "drizzled/internal/my_bit.h"
 
57
#include "drizzled/internal/my_sys.h"
 
58
#include "drizzled/internal/iocache.h"
51
59
 
52
60
#include <algorithm>
53
61
 
54
62
using namespace std;
55
63
using namespace drizzled;
56
64
 
 
65
extern drizzled::plugin::StorageEngine *heap_engine;
 
66
extern std::bitset<12> test_flags;
 
67
 
57
68
/** Declarations of static functions used in this source file. */
58
69
static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
59
70
static void calc_group_buffer(JOIN *join,order_st *group);
84
95
static uint32_t determine_search_depth(JOIN* join);
85
96
static bool make_simple_join(JOIN *join,Table *tmp_table);
86
97
static void make_outerjoin_info(JOIN *join);
87
 
static bool make_join_select(JOIN *join, optimizer::SQL_SELECT *select,COND *item);
 
98
static bool make_join_select(JOIN *join, optimizer::SqlSelect *select,COND *item);
88
99
static bool make_join_readinfo(JOIN *join, uint64_t options, uint32_t no_jbuf_after);
89
100
static void update_depend_map(JOIN *join);
90
101
static void update_depend_map(JOIN *join, order_st *order);
621
632
  {
622
633
    conds=new Item_int((int64_t) 0,1);  // Always false
623
634
  }
 
635
 
624
636
  if (make_join_select(this, select, conds))
625
637
  {
626
638
    zero_result_cause=
660
672
     The FROM clause must contain a single non-constant table.
661
673
  */
662
674
  if (tables - const_tables == 1 && (group_list || select_distinct) &&
663
 
      !tmp_table_param.sum_func_count &&
664
 
      (!join_tab[const_tables].select ||
665
 
       !join_tab[const_tables].select->quick ||
 
675
      ! tmp_table_param.sum_func_count &&
 
676
      (! join_tab[const_tables].select ||
 
677
       ! join_tab[const_tables].select->quick ||
666
678
       join_tab[const_tables].select->quick->get_type() !=
667
 
       optimizer::QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
 
679
       optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))
668
680
  {
669
681
    if (group_list && list_contains_unique_index(join_tab[const_tables].table, find_field_in_order_list, (void *) group_list))
670
682
    {
683
695
          If GROUP BY is a prefix of order_st BY, then it is safe to leave
684
696
          'order' as is.
685
697
       */
686
 
      if (!order || test_if_subpart(group_list, order))
 
698
      if (! order || test_if_subpart(group_list, order))
687
699
          order= skip_sort_order ? 0 : group_list;
688
700
      /*
689
701
        If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
828
840
  if (setup_subquery_materialization())
829
841
    return 1;
830
842
 
 
843
  /* Cache constant expressions in WHERE, HAVING, ON clauses. */
 
844
  cache_const_exprs();
 
845
 
831
846
  /*
832
847
    is this simple IN subquery?
833
848
  */
1196
1211
  {                                           
1197
1212
    /* Only test of functions */
1198
1213
    if (select_options & SELECT_DESCRIBE)
1199
 
      select_describe(this, false, false, false, (zero_result_cause?zero_result_cause:"No tables used"));
 
1214
    {
 
1215
      optimizer::ExplainPlan planner(this, 
 
1216
                                     false,
 
1217
                                     false,
 
1218
                                     false,
 
1219
                                     (zero_result_cause ? zero_result_cause : "No tables used"));
 
1220
      planner.printPlan();
 
1221
    }
1200
1222
    else
1201
1223
    {
1202
1224
      result->send_fields(*columns_list);
1269
1291
      order= 0;
1270
1292
    }
1271
1293
    having= tmp_having;
1272
 
    select_describe(this, need_tmp, order != 0 && !skip_sort_order,  select_distinct, !tables ? "No tables used" : NULL);
 
1294
    optimizer::ExplainPlan planner(this,
 
1295
                                   need_tmp,
 
1296
                                   order != 0 && ! skip_sort_order,
 
1297
                                   select_distinct,
 
1298
                                   ! tables ? "No tables used" : NULL);
 
1299
    planner.printPlan();
1273
1300
    return;
1274
1301
  }
1275
1302
 
1551
1578
      if (sort_table_cond)
1552
1579
      {
1553
1580
        if (!curr_table->select)
1554
 
          if (!(curr_table->select= new optimizer::SQL_SELECT))
 
1581
          if (!(curr_table->select= new optimizer::SqlSelect))
1555
1582
            return;
1556
1583
        if (!curr_table->select->cond)
1557
1584
          curr_table->select->cond= sort_table_cond;
2379
2406
}
2380
2407
 
2381
2408
/**
 
2409
  Cache constant expressions in WHERE, HAVING, ON conditions.
 
2410
*/
 
2411
 
 
2412
void JOIN::cache_const_exprs()
 
2413
{
 
2414
  bool cache_flag= false;
 
2415
  bool *analyzer_arg= &cache_flag;
 
2416
 
 
2417
  /* No need in cache if all tables are constant. */
 
2418
  if (const_tables == tables)
 
2419
    return;
 
2420
 
 
2421
  if (conds)
 
2422
    conds->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
 
2423
                  &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
 
2424
  cache_flag= false;
 
2425
  if (having)
 
2426
    having->compile(&Item::cache_const_expr_analyzer, (unsigned char **)&analyzer_arg,
 
2427
                    &Item::cache_const_expr_transformer, (unsigned char *)&cache_flag);
 
2428
 
 
2429
  for (JoinTable *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
 
2430
  {
 
2431
    if (*tab->on_expr_ref)
 
2432
    {
 
2433
      cache_flag= false;
 
2434
      (*tab->on_expr_ref)->compile(&Item::cache_const_expr_analyzer,
 
2435
                                 (unsigned char **)&analyzer_arg,
 
2436
                                 &Item::cache_const_expr_transformer,
 
2437
                                 (unsigned char *)&cache_flag);
 
2438
    }
 
2439
  }
 
2440
}
 
2441
 
 
2442
/**
2382
2443
  @brief
2383
2444
  
2384
2445
  Process one record of the nested loop join.
2609
2670
      join->session->send_kill_message();
2610
2671
      return NESTED_LOOP_KILLED;
2611
2672
    }
2612
 
    optimizer::SQL_SELECT *select= join_tab->select;
 
2673
    optimizer::SqlSelect *select= join_tab->select;
2613
2674
    if (rc == NESTED_LOOP_OK &&
2614
2675
        (!join_tab->cache.select || !join_tab->cache.select->skip_record()))
2615
2676
    {
4427
4488
}
4428
4489
 
4429
4490
static bool make_join_select(JOIN *join,
4430
 
                             optimizer::SQL_SELECT *select,
 
4491
                             optimizer::SqlSelect *select,
4431
4492
                             COND *cond)
4432
4493
{
4433
4494
  Session *session= join->session;
4549
4610
      if (tmp || !cond || tab->type == AM_REF || tab->type == AM_REF_OR_NULL ||
4550
4611
          tab->type == AM_EQ_REF)
4551
4612
      {
4552
 
        optimizer::SQL_SELECT *sel= tab->select= ((optimizer::SQL_SELECT*)
 
4613
        optimizer::SqlSelect *sel= tab->select= ((optimizer::SqlSelect*)
4553
4614
            session->memdup((unsigned char*) select,
4554
4615
              sizeof(*select)));
4555
4616
        if (! sel)
4687
4748
                                         current_map,
4688
4749
                                         current_map, 0)))
4689
4750
            {
4690
 
              tab->cache.select= (optimizer::SQL_SELECT*)
4691
 
                session->memdup((unsigned char*) sel, sizeof(optimizer::SQL_SELECT));
 
4751
              tab->cache.select= (optimizer::SqlSelect*)
 
4752
                session->memdup((unsigned char*) sel, sizeof(optimizer::SqlSelect));
4692
4753
              tab->cache.select->cond= tmp;
4693
4754
              tab->cache.select->read_tables= join->const_table_map;
4694
4755
            }
5124
5185
{
5125
5186
  if (select_options & SELECT_DESCRIBE)
5126
5187
  {
5127
 
    select_describe(join, false, false, false, info);
5128
 
    return(0);
 
5188
    optimizer::ExplainPlan planner(join,
 
5189
                                   false,
 
5190
                                   false,
 
5191
                                   false,
 
5192
                                   info);
 
5193
    planner.printPlan();
 
5194
    return 0;
5129
5195
  }
5130
5196
 
5131
5197
  join->join_free();
5881
5947
        !s->table->pos_in_table_list->embedding)
5882
5948
    {
5883
5949
      ha_rows records;
5884
 
      optimizer::SQL_SELECT *select= NULL;
 
5950
      optimizer::SqlSelect *select= NULL;
5885
5951
      select= optimizer::make_select(s->table, found_const_table_map, found_const_table_map, *s->on_expr_ref ? *s->on_expr_ref : conds, 1, &error);
5886
5952
      if (! select)
5887
5953
        return 1;
5928
5994
  if (join->const_tables != join->tables)
5929
5995
  {
5930
5996
    optimize_keyuse(join, keyuse_array);
5931
 
    if (choose_plan(join, all_table_map & ~join->const_table_map))
5932
 
      return(true);
 
5997
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_START(join->session->query, join->session->thread_id);
 
5998
    bool res= choose_plan(join, all_table_map & ~join->const_table_map);
 
5999
    DRIZZLE_QUERY_OPT_CHOOSE_PLAN_DONE(res ? 1 : 0);
 
6000
    if (res)
 
6001
      return true;
5933
6002
  }
5934
6003
  else
5935
6004
  {