~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/records.cc

Merge Joe, plus I updated the tests.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/**
17
17
  @file
20
20
  Functions for easy reading of records, possible through a cache
21
21
*/
22
22
#include "config.h"
23
 
 
24
 
#include "drizzled/drizzled.h"
25
23
#include "drizzled/error.h"
 
24
#include "drizzled/table.h"
 
25
#include "drizzled/session.h"
 
26
#include "drizzled/records.h"
 
27
#include "drizzled/optimizer/range.h"
 
28
#include "drizzled/internal/my_sys.h"
26
29
#include "drizzled/internal/iocache.h"
27
 
#include "drizzled/internal/my_sys.h"
28
 
#include "drizzled/optimizer/range.h"
29
 
#include "drizzled/plugin/storage_engine.h"
30
 
#include "drizzled/records.h"
31
 
#include "drizzled/session.h"
32
 
#include "drizzled/table.h"
33
30
 
34
31
namespace drizzled
35
32
{
50
47
  read_record= rr_sequential;
51
48
}
52
49
 
53
 
int ReadRecord::init_read_record_idx(Session *,
54
 
                                     Table *table_arg,
55
 
                                     bool print_error_arg,
56
 
                                     uint32_t idx)
 
50
void ReadRecord::init_read_record_idx(Session *, 
 
51
                                      Table *table_arg,
 
52
                                      bool print_error_arg, 
 
53
                                      uint32_t idx)
57
54
{
58
55
  table_arg->emptyRecord();
 
56
  memset(this, 0, sizeof(*this));
59
57
  table= table_arg;
60
58
  cursor=  table->cursor;
61
 
  record= table->getInsertRecord();
 
59
  record= table->record[0];
62
60
  print_error= print_error_arg;
63
61
 
64
62
  table->status=0;                      /* And it's always found */
65
63
  if (not table->cursor->inited)
66
 
  {
67
 
    int error= table->cursor->startIndexScan(idx, 1);
68
 
    if (error != 0)
69
 
      return error;
70
 
  }
 
64
    table->cursor->startIndexScan(idx, 1);
71
65
  /* read_record will be changed to rr_index in rr_index_first */
72
66
  read_record= rr_index_first;
73
 
 
74
 
  return 0;
75
67
}
76
68
 
77
69
 
78
 
int ReadRecord::init_read_record(Session *session_arg,
79
 
                                 Table *table_arg,
80
 
                                 optimizer::SqlSelect *select_arg,
81
 
                                 int use_record_cache,
82
 
                                 bool print_error_arg)
 
70
void ReadRecord::init_read_record(Session *session_arg, 
 
71
                                  Table *table_arg,
 
72
                                  optimizer::SqlSelect *select_arg,
 
73
                                  int use_record_cache, 
 
74
                                  bool print_error_arg)
83
75
{
84
76
  internal::IO_CACHE *tempfile;
85
 
  int error= 0;
86
77
 
 
78
  memset(this, 0, sizeof(*this));
87
79
  session= session_arg;
88
80
  table= table_arg;
89
81
  cursor= table->cursor;
97
89
  else
98
90
  {
99
91
    table->emptyRecord();
100
 
    record= table->getInsertRecord();
 
92
    record= table->record[0];
101
93
    ref_length= table->cursor->ref_length;
102
94
  }
103
95
  select= select_arg;
120
112
                  rr_unpack_from_tempfile : rr_from_tempfile);
121
113
 
122
114
    io_cache=tempfile;
123
 
    io_cache->reinit_io_cache(internal::READ_CACHE,0L,0,0);
 
115
    reinit_io_cache(io_cache,internal::READ_CACHE,0L,0,0);
124
116
    ref_pos=table->cursor->ref;
125
117
    if (!table->cursor->inited)
126
 
    {
127
 
      error= table->cursor->startTableScan(0);
128
 
      if (error != 0)
129
 
        return error;
130
 
    }
 
118
      table->cursor->startTableScan(0);
131
119
 
132
120
    /*
133
121
      table->sort.addon_field is checked because if we use addon fields,
159
147
  }
160
148
  else if (table->sort.record_pointers)
161
149
  {
162
 
    error= table->cursor->startTableScan(0);
163
 
    if (error != 0)
164
 
      return error;
165
 
 
 
150
    table->cursor->startTableScan(0);
166
151
    cache_pos=table->sort.record_pointers;
167
152
    cache_end= cache_pos+ table->sort.found_records * ref_length;
168
153
    read_record= (table->sort.addon_field ?  rr_unpack_from_buffer : rr_from_pointers);
170
155
  else
171
156
  {
172
157
    read_record= rr_sequential;
173
 
    error= table->cursor->startTableScan(1);
174
 
    if (error != 0)
175
 
      return error;
176
 
 
 
158
    table->cursor->startTableScan(1);
177
159
    /* We can use record cache if we don't update dynamic length tables */
178
160
    if (!table->no_cache &&
179
161
        (use_record_cache > 0 ||
184
166
    }
185
167
  }
186
168
 
187
 
  return 0;
 
169
  return;
188
170
} /* init_read_record */
189
171
 
190
172
 
192
174
{                   /* free cache if used */
193
175
  if (cache)
194
176
  {
195
 
    global_read_rnd_buffer.sub(session->variables.read_rnd_buff_size);
196
177
    free((char*) cache);
197
178
    cache= NULL;
198
179
  }
227
208
  int tmp;
228
209
  while ((tmp= info->select->quick->get_next()))
229
210
  {
230
 
    if (info->session->getKilled())
 
211
    if (info->session->killed)
231
212
    {
232
213
      my_error(ER_SERVER_SHUTDOWN, MYF(0));
233
214
      return 1;
291
272
  int tmp;
292
273
  while ((tmp= info->cursor->rnd_next(info->record)))
293
274
  {
294
 
    if (info->session->getKilled())
 
275
    if (info->session->killed)
295
276
    {
296
277
      info->session->send_kill_message();
297
278
      return 1;
423
404
  local_rec_cache_size= cache_records * reclength;
424
405
  rec_cache_size= cache_records * ref_length;
425
406
 
426
 
  if (not global_read_rnd_buffer.add(session->variables.read_rnd_buff_size))
427
 
  {
428
 
    my_error(ER_OUT_OF_GLOBAL_READRNDMEMORY, MYF(ME_ERROR+ME_WAITTANG));
429
 
    return false;
430
 
  }
431
 
 
432
407
  // We have to allocate one more byte to use uint3korr (see comments for it)
433
408
  if (cache_records <= 2 ||
434
409
      !(cache=(unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1)))
435
410
  {
436
411
    return false;
437
412
  }
438
 
#ifdef HAVE_VALGRIND
 
413
#ifdef HAVE_purify
439
414
  // Avoid warnings in qsort
440
415
  memset(cache, 0, local_rec_cache_size + cache_records * struct_length + 1);
441
416
#endif
447
422
 
448
423
static int rr_from_cache(ReadRecord *info)
449
424
{
 
425
  register uint32_t i;
450
426
  uint32_t length;
451
427
  internal::my_off_t rest_of_file;
452
428
  int16_t error;
486
462
    length/=info->ref_length;
487
463
    position=info->getCache();
488
464
    ref_position=info->read_positions;
489
 
    for (uint32_t i= 0 ; i < length ; i++,position+=info->ref_length)
 
465
    for (i=0 ; i < length ; i++,position+=info->ref_length)
490
466
    {
491
467
      memcpy(ref_position,position,(size_t) info->ref_length);
492
468
      ref_position+=MAX_REFLENGTH;
497
473
                       (qsort_cmp) rr_cmp);
498
474
 
499
475
    position=info->read_positions;
500
 
    for (uint32_t i= 0 ; i < length ; i++)
 
476
    for (i=0 ; i < length ; i++)
501
477
    {
502
478
      memcpy(info->ref_pos, position, (size_t)info->ref_length);
503
479
      position+=MAX_REFLENGTH;