Drizzled Public API Documentation

join_table.cc
1 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008-2009 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <config.h>
22 
23 #include <drizzled/field/blob.h>
24 #include <drizzled/join_table.h>
25 #include <drizzled/sql_lex.h>
26 #include <drizzled/sql_select.h>
27 #include <drizzled/table.h>
28 #include <drizzled/util/test.h>
29 
30 namespace drizzled
31 {
32 
33 int JoinTable::joinReadConstTable(optimizer::Position *pos)
34 {
35  int error;
36  Table *Table= this->table;
37  Table->const_table=1;
38  Table->null_row=0;
39  Table->status=STATUS_NO_RECORD;
40 
41  if (this->type == AM_SYSTEM)
42  {
43  if ((error= this->joinReadSystem()))
44  { // Info for DESCRIBE
45  this->info="const row not found";
46  /* Mark for EXPLAIN that the row was not found */
47  pos->setFanout(0.0);
48  pos->clearRefDependMap();
49  if (! Table->maybe_null || error > 0)
50  return(error);
51  }
52  }
53  else
54  {
55  if (! Table->key_read &&
56  Table->covering_keys.test(this->ref.key) &&
57  ! Table->no_keyread &&
58  (int) Table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
59  {
60  Table->key_read=1;
61  Table->cursor->extra(HA_EXTRA_KEYREAD);
62  this->index= this->ref.key;
63  }
64  error=join_read_const(this);
65  if (Table->key_read)
66  {
67  Table->key_read=0;
68  Table->cursor->extra(HA_EXTRA_NO_KEYREAD);
69  }
70  if (error)
71  {
72  this->info="unique row not found";
73  /* Mark for EXPLAIN that the row was not found */
74  pos->setFanout(0.0);
75  pos->clearRefDependMap();
76  if (!Table->maybe_null || error > 0)
77  return(error);
78  }
79  }
80  if (*this->on_expr_ref && !Table->null_row)
81  {
82  if ((Table->null_row= test((*this->on_expr_ref)->val_int() == 0)))
83  Table->mark_as_null_row();
84  }
85  if (!Table->null_row)
86  Table->maybe_null=0;
87 
88  /* Check appearance of new constant items in Item_equal objects */
89  Join *Join= this->join;
90  if (Join->conds)
91  update_const_equal_items(Join->conds, this);
92  TableList *tbl;
93  for (tbl= Join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
94  {
95  TableList *embedded;
96  TableList *embedding= tbl;
97  do
98  {
99  embedded= embedding;
100  if (embedded->on_expr)
101  update_const_equal_items(embedded->on_expr, this);
102  embedding= embedded->getEmbedding();
103  }
104  while (embedding &&
105  &embedding->getNestedJoin()->join_list.front() == embedded);
106  }
107 
108  return 0;
109 }
110 
111 void JoinTable::readCachedRecord()
112 {
113  unsigned char *pos;
114  uint32_t length;
115  bool last_record;
116  CacheField *copy,*end_field;
117 
118  last_record= this->cache.record_nr++ == this->cache.ptr_record;
119  pos= this->cache.pos;
120  for (copy= this->cache.field, end_field= copy+this->cache.fields;
121  copy < end_field;
122  copy++)
123  {
124  if (copy->blob_field)
125  {
126  if (last_record)
127  {
128  copy->blob_field->set_image(pos, copy->length+sizeof(char*),
129  copy->blob_field->charset());
130  pos+=copy->length+sizeof(char*);
131  }
132  else
133  {
134  copy->blob_field->set_ptr(pos, pos+copy->length);
135  pos+=copy->length+copy->blob_field->get_length();
136  }
137  }
138  else
139  {
140  if (copy->strip)
141  {
142  length= uint2korr(pos);
143  memcpy(copy->str, pos+2, length);
144  memset(copy->str+length, ' ', copy->length-length);
145  pos+= 2 + length;
146  }
147  else
148  {
149  memcpy(copy->str,pos,copy->length);
150  pos+=copy->length;
151  }
152  }
153  }
154  this->cache.pos=pos;
155 }
156 
157 int join_read_system(JoinTable *tab)
158 {
159  Table *table= tab->table;
160  int error;
161 
162  if (table->status & STATUS_GARBAGE) // If first read
163  {
164  if ((error= table->cursor->read_first_row(table->getInsertRecord(),
165  table->getShare()->getPrimaryKey())))
166  {
167  if (error != HA_ERR_END_OF_FILE)
168  {
169  return table->report_error(error);
170  }
171 
172  tab->table->mark_as_null_row();
173  table->emptyRecord(); // Make empty record
174  return -1;
175  }
176  table->storeRecord();
177  }
178  else if (table->status == 0) // Only happens with left join
179  {
180  table->restoreRecord(); // restore old record
181  }
182  table->null_row=0;
183 
184  return table->status ? -1 : 0;
185 }
186 
187 int JoinTable::joinReadSystem()
188 {
189  return join_read_system(this);
190 }
191 
192 } /* namespace drizzled */
enum access_method type
Definition: join_table.h:185
int join_read_const(JoinTable *tab)
Definition: sql_select.cc:3579
void update_const_equal_items(COND *cond, JoinTable *tab)
Definition: sql_select.cc:2442