~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/table.cc

  • Committer: Brian Aker
  • Date: 2008-08-19 17:29:21 UTC
  • Revision ID: brian@tangent.org-20080819172921-bc3kpgsrzsdv338l
Moved Field iterator out to its own definition.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2646
2646
}
2647
2647
 
2648
2648
 
2649
 
const char *Field_iterator_table::name()
2650
 
{
2651
 
  return (*ptr)->field_name;
2652
 
}
2653
 
 
2654
 
 
2655
 
Item *Field_iterator_table::create_item(THD *thd)
2656
 
{
2657
 
  SELECT_LEX *select= thd->lex->current_select;
2658
 
 
2659
 
  Item_field *item= new Item_field(thd, &select->context, *ptr);
2660
 
  if (item && thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
2661
 
      !thd->lex->in_sum_func && select->cur_pos_in_select_list != UNDEF_POS)
2662
 
  {
2663
 
    select->non_agg_fields.push_back(item);
2664
 
    item->marker= select->cur_pos_in_select_list;
2665
 
  }
2666
 
  return item;
2667
 
}
2668
 
 
2669
 
 
2670
 
void Field_iterator_natural_join::set(TableList *table_ref)
2671
 
{
2672
 
  assert(table_ref->join_columns);
2673
 
  column_ref_it.init(*(table_ref->join_columns));
2674
 
  cur_column_ref= column_ref_it++;
2675
 
}
2676
 
 
2677
 
 
2678
 
void Field_iterator_natural_join::next()
2679
 
{
2680
 
  cur_column_ref= column_ref_it++;
2681
 
  assert(!cur_column_ref || ! cur_column_ref->table_field ||
2682
 
              cur_column_ref->table_ref->table ==
2683
 
              cur_column_ref->table_field->table);
2684
 
}
2685
 
 
2686
 
 
2687
 
void Field_iterator_table_ref::set_field_iterator()
2688
 
{
2689
 
  /*
2690
 
    If the table reference we are iterating over is a natural join, or it is
2691
 
    an operand of a natural join, and TableList::join_columns contains all
2692
 
    the columns of the join operand, then we pick the columns from
2693
 
    TableList::join_columns, instead of the  orginial container of the
2694
 
    columns of the join operator.
2695
 
  */
2696
 
  if (table_ref->is_join_columns_complete)
2697
 
  {
2698
 
    /* Necesary, but insufficient conditions. */
2699
 
    assert(table_ref->is_natural_join ||
2700
 
                table_ref->nested_join ||
2701
 
                ((table_ref->join_columns && /* This is a merge view. */ (table_ref->field_translation && table_ref->join_columns->elements == (ulong)(table_ref->field_translation_end - table_ref->field_translation))) ||
2702
 
                 /* This is stored table or a tmptable view. */
2703
 
                 (!table_ref->field_translation && table_ref->join_columns->elements == table_ref->table->s->fields)));
2704
 
    field_it= &natural_join_it;
2705
 
  }
2706
 
  /* This is a base table or stored view. */
2707
 
  else
2708
 
  {
2709
 
    assert(table_ref->table);
2710
 
    field_it= &table_field_it;
2711
 
  }
2712
 
  field_it->set(table_ref);
2713
 
  return;
2714
 
}
2715
 
 
2716
 
 
2717
 
void Field_iterator_table_ref::set(TableList *table)
2718
 
{
2719
 
  assert(table);
2720
 
  first_leaf= table->first_leaf_for_name_resolution();
2721
 
  last_leaf=  table->last_leaf_for_name_resolution();
2722
 
  assert(first_leaf && last_leaf);
2723
 
  table_ref= first_leaf;
2724
 
  set_field_iterator();
2725
 
}
2726
 
 
2727
 
 
2728
 
void Field_iterator_table_ref::next()
2729
 
{
2730
 
  /* Move to the next field in the current table reference. */
2731
 
  field_it->next();
2732
 
  /*
2733
 
    If all fields of the current table reference are exhausted, move to
2734
 
    the next leaf table reference.
2735
 
  */
2736
 
  if (field_it->end_of_fields() && table_ref != last_leaf)
2737
 
  {
2738
 
    table_ref= table_ref->next_name_resolution_table;
2739
 
    assert(table_ref);
2740
 
    set_field_iterator();
2741
 
  }
2742
 
}
2743
 
 
2744
 
 
2745
 
const char *Field_iterator_table_ref::table_name()
2746
 
{
2747
 
  if (table_ref->is_natural_join)
2748
 
    return natural_join_it.column_ref()->table_name();
2749
 
 
2750
 
  assert(!strcmp(table_ref->table_name,
2751
 
                      table_ref->table->s->table_name.str));
2752
 
  return table_ref->table_name;
2753
 
}
2754
 
 
2755
 
 
2756
 
const char *Field_iterator_table_ref::db_name()
2757
 
{
2758
 
  if (table_ref->is_natural_join)
2759
 
    return natural_join_it.column_ref()->db_name();
2760
 
 
2761
 
  /*
2762
 
    Test that TableList::db is the same as st_table_share::db to
2763
 
    ensure consistency. An exception are I_S schema tables, which
2764
 
    are inconsistent in this respect.
2765
 
  */
2766
 
  assert(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
2767
 
              (table_ref->schema_table &&
2768
 
               table_ref->table->s->db.str[0] == 0));
2769
 
 
2770
 
  return table_ref->db;
2771
 
}
2772
 
 
2773
 
 
2774
 
/*
2775
 
  Create new or return existing column reference to a column of a
2776
 
  natural/using join.
2777
 
 
2778
 
  SYNOPSIS
2779
 
    Field_iterator_table_ref::get_or_create_column_ref()
2780
 
    parent_table_ref  the parent table reference over which the
2781
 
                      iterator is iterating
2782
 
 
2783
 
  DESCRIPTION
2784
 
    Create a new natural join column for the current field of the
2785
 
    iterator if no such column was created, or return an already
2786
 
    created natural join column. The former happens for base tables or
2787
 
    views, and the latter for natural/using joins. If a new field is
2788
 
    created, then the field is added to 'parent_table_ref' if it is
2789
 
    given, or to the original table referene of the field if
2790
 
    parent_table_ref == NULL.
2791
 
 
2792
 
  NOTES
2793
 
    This method is designed so that when a Field_iterator_table_ref
2794
 
    walks through the fields of a table reference, all its fields
2795
 
    are created and stored as follows:
2796
 
    - If the table reference being iterated is a stored table, view or
2797
 
      natural/using join, store all natural join columns in a list
2798
 
      attached to that table reference.
2799
 
    - If the table reference being iterated is a nested join that is
2800
 
      not natural/using join, then do not materialize its result
2801
 
      fields. This is OK because for such table references
2802
 
      Field_iterator_table_ref iterates over the fields of the nested
2803
 
      table references (recursively). In this way we avoid the storage
2804
 
      of unnecessay copies of result columns of nested joins.
2805
 
 
2806
 
  RETURN
2807
 
    #     Pointer to a column of a natural join (or its operand)
2808
 
    NULL  No memory to allocate the column
2809
 
*/
2810
 
 
2811
 
Natural_join_column *
2812
 
Field_iterator_table_ref::get_or_create_column_ref(TableList *parent_table_ref)
2813
 
{
2814
 
  Natural_join_column *nj_col;
2815
 
  bool is_created= true;
2816
 
  uint field_count=0;
2817
 
  TableList *add_table_ref= parent_table_ref ?
2818
 
                             parent_table_ref : table_ref;
2819
 
 
2820
 
  if (field_it == &table_field_it)
2821
 
  {
2822
 
    /* The field belongs to a stored table. */
2823
 
    Field *tmp_field= table_field_it.field();
2824
 
    nj_col= new Natural_join_column(tmp_field, table_ref);
2825
 
    field_count= table_ref->table->s->fields;
2826
 
  }
2827
 
  else
2828
 
  {
2829
 
    /*
2830
 
      The field belongs to a NATURAL join, therefore the column reference was
2831
 
      already created via one of the two constructor calls above. In this case
2832
 
      we just return the already created column reference.
2833
 
    */
2834
 
    assert(table_ref->is_join_columns_complete);
2835
 
    is_created= false;
2836
 
    nj_col= natural_join_it.column_ref();
2837
 
    assert(nj_col);
2838
 
  }
2839
 
  assert(!nj_col->table_field ||
2840
 
              nj_col->table_ref->table == nj_col->table_field->table);
2841
 
 
2842
 
  /*
2843
 
    If the natural join column was just created add it to the list of
2844
 
    natural join columns of either 'parent_table_ref' or to the table
2845
 
    reference that directly contains the original field.
2846
 
  */
2847
 
  if (is_created)
2848
 
  {
2849
 
    /* Make sure not all columns were materialized. */
2850
 
    assert(!add_table_ref->is_join_columns_complete);
2851
 
    if (!add_table_ref->join_columns)
2852
 
    {
2853
 
      /* Create a list of natural join columns on demand. */
2854
 
      if (!(add_table_ref->join_columns= new List<Natural_join_column>))
2855
 
        return NULL;
2856
 
      add_table_ref->is_join_columns_complete= false;
2857
 
    }
2858
 
    add_table_ref->join_columns->push_back(nj_col);
2859
 
    /*
2860
 
      If new fields are added to their original table reference, mark if
2861
 
      all fields were added. We do it here as the caller has no easy way
2862
 
      of knowing when to do it.
2863
 
      If the fields are being added to parent_table_ref, then the caller
2864
 
      must take care to mark when all fields are created/added.
2865
 
    */
2866
 
    if (!parent_table_ref &&
2867
 
        add_table_ref->join_columns->elements == field_count)
2868
 
      add_table_ref->is_join_columns_complete= true;
2869
 
  }
2870
 
 
2871
 
  return nj_col;
2872
 
}
2873
 
 
2874
 
 
2875
 
/*
2876
 
  Return an existing reference to a column of a natural/using join.
2877
 
 
2878
 
  SYNOPSIS
2879
 
    Field_iterator_table_ref::get_natural_column_ref()
2880
 
 
2881
 
  DESCRIPTION
2882
 
    The method should be called in contexts where it is expected that
2883
 
    all natural join columns are already created, and that the column
2884
 
    being retrieved is a Natural_join_column.
2885
 
 
2886
 
  RETURN
2887
 
    #     Pointer to a column of a natural join (or its operand)
2888
 
    NULL  No memory to allocate the column
2889
 
*/
2890
 
 
2891
 
Natural_join_column *
2892
 
Field_iterator_table_ref::get_natural_column_ref()
2893
 
{
2894
 
  Natural_join_column *nj_col;
2895
 
 
2896
 
  assert(field_it == &natural_join_it);
2897
 
  /*
2898
 
    The field belongs to a NATURAL join, therefore the column reference was
2899
 
    already created via one of the two constructor calls above. In this case
2900
 
    we just return the already created column reference.
2901
 
  */
2902
 
  nj_col= natural_join_it.column_ref();
2903
 
  assert(nj_col &&
2904
 
              (!nj_col->table_field ||
2905
 
               nj_col->table_ref->table == nj_col->table_field->table));
2906
 
  return nj_col;
2907
 
}
2908
 
 
2909
2649
/*****************************************************************************
2910
2650
  Functions to handle column usage bitmaps (read_set, write_set etc...)
2911
2651
*****************************************************************************/