~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
1 by brian
clean slate
15
16
/**
17
  @file
18
19
  @brief
20
  Functions for easy reading of records, possible through a cache
21
*/
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
22
#include <config.h>
2148.7.12 by Brian Aker
Merge in header fixes.
23
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
24
#include <drizzled/drizzled.h>
25
#include <drizzled/error.h>
26
#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>
1237.9.2 by Padraig O'Sullivan
Moved opt_range.[cc,h] into the optimizer directory and namespace and renamed the files to
33
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
34
namespace drizzled
35
{
1 by brian
clean slate
36
1578.4.1 by Brian Aker
Static/contain the only function that was seen outside of records.cc
37
static int rr_sequential(ReadRecord *info);
1538 by Brian Aker
Code shuffle on ReadRecord
38
static int rr_quick(ReadRecord *info);
39
static int rr_from_tempfile(ReadRecord *info);
40
static int rr_unpack_from_tempfile(ReadRecord *info);
41
static int rr_unpack_from_buffer(ReadRecord *info);
42
static int rr_from_pointers(ReadRecord *info);
43
static int rr_from_cache(ReadRecord *info);
481 by Brian Aker
Remove all of uchar.
44
static int rr_cmp(unsigned char *a,unsigned char *b);
1538 by Brian Aker
Code shuffle on ReadRecord
45
static int rr_index_first(ReadRecord *info);
46
static int rr_index(ReadRecord *info);
1 by brian
clean slate
47
1578.4.1 by Brian Aker
Static/contain the only function that was seen outside of records.cc
48
void ReadRecord::init_reard_record_sequential()
49
{
50
  read_record= rr_sequential;
51
}
52
2049.2.7 by Stewart Smith
init_read_record_idx return result should be checked now that it checks startIndexScan result.
53
int ReadRecord::init_read_record_idx(Session *,
54
                                     Table *table_arg,
55
                                     bool print_error_arg,
56
                                     uint32_t idx)
1 by brian
clean slate
57
{
1539.1.3 by Brian Aker
Additional function -> method for readrecord
58
  table_arg->emptyRecord();
59
  table= table_arg;
60
  cursor=  table->cursor;
1672.3.6 by Brian Aker
First pass in encapsulating row
61
  record= table->getInsertRecord();
1539.1.3 by Brian Aker
Additional function -> method for readrecord
62
  print_error= print_error_arg;
1 by brian
clean slate
63
64
  table->status=0;			/* And it's always found */
1539.1.3 by Brian Aker
Additional function -> method for readrecord
65
  if (not table->cursor->inited)
2049.2.7 by Stewart Smith
init_read_record_idx return result should be checked now that it checks startIndexScan result.
66
  {
67
    int error= table->cursor->startIndexScan(idx, 1);
68
    if (error != 0)
69
      return error;
70
  }
1 by brian
clean slate
71
  /* read_record will be changed to rr_index in rr_index_first */
1539.1.3 by Brian Aker
Additional function -> method for readrecord
72
  read_record= rr_index_first;
2049.2.7 by Stewart Smith
init_read_record_idx return result should be checked now that it checks startIndexScan result.
73
74
  return 0;
1 by brian
clean slate
75
}
76
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
77
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
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)
1 by brian
clean slate
83
{
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
84
  internal::IO_CACHE *tempfile;
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
85
  int error= 0;
1 by brian
clean slate
86
1538 by Brian Aker
Code shuffle on ReadRecord
87
  session= session_arg;
88
  table= table_arg;
89
  cursor= table->cursor;
90
  forms= &table;		/* Only one table */
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
91
1 by brian
clean slate
92
  if (table->sort.addon_field)
93
  {
1538 by Brian Aker
Code shuffle on ReadRecord
94
    rec_buf= table->sort.addon_buf;
95
    ref_length= table->sort.addon_length;
1 by brian
clean slate
96
  }
97
  else
98
  {
997.5.1 by chris
Replace macros around unireg.h, store_record,restore_record,cmp_record,empty_record
99
    table->emptyRecord();
1672.3.6 by Brian Aker
First pass in encapsulating row
100
    record= table->getInsertRecord();
1538 by Brian Aker
Code shuffle on ReadRecord
101
    ref_length= table->cursor->ref_length;
1 by brian
clean slate
102
  }
1538 by Brian Aker
Code shuffle on ReadRecord
103
  select= select_arg;
104
  print_error= print_error_arg;
105
  ignore_not_found_rows= 0;
1 by brian
clean slate
106
  table->status=0;			/* And it's always found */
107
1241.9.48 by Monty Taylor
Made one of the drizzled instances of IO_CACHE a pointer.
108
  if (select && my_b_inited(select->file))
1538 by Brian Aker
Code shuffle on ReadRecord
109
  {
1241.9.48 by Monty Taylor
Made one of the drizzled instances of IO_CACHE a pointer.
110
    tempfile= select->file;
1538 by Brian Aker
Code shuffle on ReadRecord
111
  }
1 by brian
clean slate
112
  else
1538 by Brian Aker
Code shuffle on ReadRecord
113
  {
1 by brian
clean slate
114
    tempfile= table->sort.io_cache;
1538 by Brian Aker
Code shuffle on ReadRecord
115
  }
116
1 by brian
clean slate
117
  if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
118
  {
1538 by Brian Aker
Code shuffle on ReadRecord
119
    read_record= (table->sort.addon_field ?
1578.4.7 by Brian Aker
Small syntax update.
120
                  rr_unpack_from_tempfile : rr_from_tempfile);
121
1538 by Brian Aker
Code shuffle on ReadRecord
122
    io_cache=tempfile;
1909.1.1 by Brian Aker
Encapsulation of IO_CACHE.
123
    io_cache->reinit_io_cache(internal::READ_CACHE,0L,0,0);
1538 by Brian Aker
Code shuffle on ReadRecord
124
    ref_pos=table->cursor->ref;
1208.3.2 by brian
Update for Cursor renaming.
125
    if (!table->cursor->inited)
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
126
    {
127
      error= table->cursor->startTableScan(0);
128
      if (error != 0)
129
        return error;
130
    }
1 by brian
clean slate
131
132
    /*
133
      table->sort.addon_field is checked because if we use addon fields,
134
      it doesn't make sense to use cache - we don't read from the table
135
      and table->sort.io_cache is read sequentially
136
    */
137
    if (!table->sort.addon_field &&
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
138
        session->variables.read_rnd_buff_size &&
1233.1.5 by Brian Aker
More table_flags converted.
139
        !(table->cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) &&
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
140
        (table->db_stat & HA_READ_ONLY ||
141
        table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
1578.2.8 by Brian Aker
Encapsulate record length.
142
        (uint64_t) table->getShare()->getRecordLength() * (table->cursor->stats.records+
1208.3.2 by brian
Update for Cursor renaming.
143
                                                table->cursor->stats.deleted) >
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
144
        (uint64_t) MIN_FILE_LENGTH_TO_USE_ROW_CACHE &&
1578.2.8 by Brian Aker
Encapsulate record length.
145
        io_cache->end_of_file/ref_length * table->getShare()->getRecordLength() >
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
146
        (internal::my_off_t) MIN_ROWS_TO_USE_TABLE_CACHE &&
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
147
        !table->getShare()->blob_fields &&
1538 by Brian Aker
Code shuffle on ReadRecord
148
        ref_length <= MAX_REFLENGTH)
1 by brian
clean slate
149
    {
1539.1.4 by Brian Aker
More RR encapsulation.
150
      if (init_rr_cache())
1 by brian
clean slate
151
      {
1578.4.7 by Brian Aker
Small syntax update.
152
        read_record= rr_from_cache;
1 by brian
clean slate
153
      }
154
    }
155
  }
156
  else if (select && select->quick)
157
  {
1578.4.7 by Brian Aker
Small syntax update.
158
    read_record= rr_quick;
1 by brian
clean slate
159
  }
160
  else if (table->sort.record_pointers)
161
  {
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
162
    error= table->cursor->startTableScan(0);
163
    if (error != 0)
164
      return error;
165
1538 by Brian Aker
Code shuffle on ReadRecord
166
    cache_pos=table->sort.record_pointers;
167
    cache_end= cache_pos+ table->sort.found_records * ref_length;
168
    read_record= (table->sort.addon_field ?  rr_unpack_from_buffer : rr_from_pointers);
1 by brian
clean slate
169
  }
170
  else
171
  {
1538 by Brian Aker
Code shuffle on ReadRecord
172
    read_record= rr_sequential;
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
173
    error= table->cursor->startTableScan(1);
174
    if (error != 0)
175
      return error;
176
1 by brian
clean slate
177
    /* We can use record cache if we don't update dynamic length tables */
178
    if (!table->no_cache &&
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
179
        (use_record_cache > 0 ||
180
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS ||
1532.1.15 by Brian Aker
Partial encapsulation of TableShare from Table.
181
        !(table->getShare()->db_options_in_use & HA_OPTION_PACK_RECORD)))
1578.4.7 by Brian Aker
Small syntax update.
182
    {
1208.3.2 by brian
Update for Cursor renaming.
183
      table->cursor->extra_opt(HA_EXTRA_CACHE, session->variables.read_buff_size);
1578.4.7 by Brian Aker
Small syntax update.
184
    }
1 by brian
clean slate
185
  }
186
2049.2.1 by Stewart Smith
doStartTableScan() result not checked.
187
  return 0;
1 by brian
clean slate
188
} /* init_read_record */
189
1237.9.4 by Padraig O'Sullivan
Removed the inclusion of drizzled/field.h in the server_includes header file.
190
1538 by Brian Aker
Code shuffle on ReadRecord
191
void ReadRecord::end_read_record()
1 by brian
clean slate
192
{                   /* free cache if used */
1578.4.13 by Brian Aker
Revert records
193
  if (cache)
194
  {
1796.4.10 by Andrew Hutchings
Add global constraint for --read-rnd-buffer-size
195
    global_read_rnd_buffer.sub(session->variables.read_rnd_buff_size);
1578.4.13 by Brian Aker
Revert records
196
    free((char*) cache);
197
    cache= NULL;
198
  }
1538 by Brian Aker
Code shuffle on ReadRecord
199
  if (table)
1 by brian
clean slate
200
  {
1538 by Brian Aker
Code shuffle on ReadRecord
201
    table->filesort_free_buffers();
202
    (void) cursor->extra(HA_EXTRA_NO_CACHE);
203
    if (read_record != rr_quick) // otherwise quick_range does it
204
      (void) cursor->ha_index_or_rnd_end();
205
206
    table= NULL;
1 by brian
clean slate
207
  }
208
}
209
1538 by Brian Aker
Code shuffle on ReadRecord
210
static int rr_handle_error(ReadRecord *info, int error)
1 by brian
clean slate
211
{
212
  if (error == HA_ERR_END_OF_FILE)
213
    error= -1;
214
  else
215
  {
216
    if (info->print_error)
1216.1.1 by Brian Aker
Move print_error up to Engine.
217
      info->table->print_error(error, MYF(0));
1 by brian
clean slate
218
    if (error < 0)                            // Fix negative BDB errno
219
      error= 1;
220
  }
221
  return error;
222
}
223
224
/** Read a record from head-database. */
1538 by Brian Aker
Code shuffle on ReadRecord
225
static int rr_quick(ReadRecord *info)
1 by brian
clean slate
226
{
227
  int tmp;
228
  while ((tmp= info->select->quick->get_next()))
229
  {
1910.2.8 by Brian Aker
Enapsulate Kill.
230
    if (info->session->getKilled())
1 by brian
clean slate
231
    {
232
      my_error(ER_SERVER_SHUTDOWN, MYF(0));
233
      return 1;
234
    }
235
    if (tmp != HA_ERR_RECORD_DELETED)
236
    {
237
      tmp= rr_handle_error(info, tmp);
238
      break;
239
    }
240
  }
998.1.2 by Brian Aker
First pass on removing virt columns
241
1 by brian
clean slate
242
  return tmp;
243
}
244
245
/**
246
  Reads first row in an index scan.
247
248
  @param info  	Scan info
249
250
  @retval
251
    0   Ok
252
  @retval
253
    -1   End of records
254
  @retval
255
    1   Error
256
*/
1538 by Brian Aker
Code shuffle on ReadRecord
257
static int rr_index_first(ReadRecord *info)
1 by brian
clean slate
258
{
1208.3.2 by brian
Update for Cursor renaming.
259
  int tmp= info->cursor->index_first(info->record);
1 by brian
clean slate
260
  info->read_record= rr_index;
261
  if (tmp)
262
    tmp= rr_handle_error(info, tmp);
263
  return tmp;
264
}
265
266
/**
267
  Reads index sequentially after first row.
268
269
  Read the next index record (in forward direction) and translate return
270
  value.
271
272
  @param info  Scan info
273
274
  @retval
275
    0   Ok
276
  @retval
277
    -1   End of records
278
  @retval
279
    1   Error
280
*/
1538 by Brian Aker
Code shuffle on ReadRecord
281
static int rr_index(ReadRecord *info)
1 by brian
clean slate
282
{
1208.3.2 by brian
Update for Cursor renaming.
283
  int tmp= info->cursor->index_next(info->record);
1 by brian
clean slate
284
  if (tmp)
285
    tmp= rr_handle_error(info, tmp);
286
  return tmp;
287
}
288
1538 by Brian Aker
Code shuffle on ReadRecord
289
int rr_sequential(ReadRecord *info)
1 by brian
clean slate
290
{
291
  int tmp;
1208.3.2 by brian
Update for Cursor renaming.
292
  while ((tmp= info->cursor->rnd_next(info->record)))
1 by brian
clean slate
293
  {
1910.2.8 by Brian Aker
Enapsulate Kill.
294
    if (info->session->getKilled())
1 by brian
clean slate
295
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
296
      info->session->send_kill_message();
1 by brian
clean slate
297
      return 1;
298
    }
299
    /*
822 by Brian Aker
Merge from Stewart.
300
      TODO> Fix this so that engine knows how to behave on its own.
1 by brian
clean slate
301
      rnd_next can return RECORD_DELETED for MyISAM when one thread is
302
      reading and another deleting without locks.
303
    */
304
    if (tmp != HA_ERR_RECORD_DELETED)
305
    {
306
      tmp= rr_handle_error(info, tmp);
307
      break;
308
    }
309
  }
998.1.2 by Brian Aker
First pass on removing virt columns
310
1 by brian
clean slate
311
  return tmp;
312
}
313
1538 by Brian Aker
Code shuffle on ReadRecord
314
static int rr_from_tempfile(ReadRecord *info)
1 by brian
clean slate
315
{
316
  int tmp;
317
  for (;;)
318
  {
319
    if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
1208.3.2 by brian
Update for Cursor renaming.
320
      return -1;					/* End of cursor */
321
    if (!(tmp=info->cursor->rnd_pos(info->record,info->ref_pos)))
1 by brian
clean slate
322
      break;
323
    /* The following is extremely unlikely to happen */
324
    if (tmp == HA_ERR_RECORD_DELETED ||
325
        (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
326
      continue;
327
    tmp= rr_handle_error(info, tmp);
328
    break;
329
  }
330
  return tmp;
331
} /* rr_from_tempfile */
332
333
/**
1208.3.2 by brian
Update for Cursor renaming.
334
  Read a result set record from a temporary cursor after sorting.
1 by brian
clean slate
335
1208.3.2 by brian
Update for Cursor renaming.
336
  The function first reads the next sorted record from the temporary cursor.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
337
  into a buffer. If a success it calls a callback function that unpacks
1 by brian
clean slate
338
  the fields values use in the result set from this buffer into their
339
  positions in the regular record buffer.
340
341
  @param info          Reference to the context including record descriptors
342
343
  @retval
344
    0   Record successfully read.
345
  @retval
346
    -1   There is no record to be read anymore.
347
*/
1538 by Brian Aker
Code shuffle on ReadRecord
348
static int rr_unpack_from_tempfile(ReadRecord *info)
1 by brian
clean slate
349
{
350
  if (my_b_read(info->io_cache, info->rec_buf, info->ref_length))
351
    return -1;
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
352
  Table *table= info->table;
1 by brian
clean slate
353
  (*table->sort.unpack)(table->sort.addon_field, info->rec_buf);
354
355
  return 0;
356
}
357
1538 by Brian Aker
Code shuffle on ReadRecord
358
static int rr_from_pointers(ReadRecord *info)
1 by brian
clean slate
359
{
360
  int tmp;
481 by Brian Aker
Remove all of uchar.
361
  unsigned char *cache_pos;
1 by brian
clean slate
362
1578.4.7 by Brian Aker
Small syntax update.
363
1 by brian
clean slate
364
  for (;;)
365
  {
366
    if (info->cache_pos == info->cache_end)
1208.3.2 by brian
Update for Cursor renaming.
367
      return -1;					/* End of cursor */
1 by brian
clean slate
368
    cache_pos= info->cache_pos;
369
    info->cache_pos+= info->ref_length;
370
1208.3.2 by brian
Update for Cursor renaming.
371
    if (!(tmp=info->cursor->rnd_pos(info->record,cache_pos)))
1 by brian
clean slate
372
      break;
373
374
    /* The following is extremely unlikely to happen */
375
    if (tmp == HA_ERR_RECORD_DELETED ||
376
        (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows))
377
      continue;
378
    tmp= rr_handle_error(info, tmp);
379
    break;
380
  }
381
  return tmp;
382
}
383
384
/**
385
  Read a result set record from a buffer after sorting.
386
387
  The function first reads the next sorted record from the sort buffer.
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
388
  If a success it calls a callback function that unpacks
1 by brian
clean slate
389
  the fields values use in the result set from this buffer into their
390
  positions in the regular record buffer.
391
392
  @param info          Reference to the context including record descriptors
393
394
  @retval
395
    0   Record successfully read.
396
  @retval
397
    -1   There is no record to be read anymore.
398
*/
1538 by Brian Aker
Code shuffle on ReadRecord
399
static int rr_unpack_from_buffer(ReadRecord *info)
1 by brian
clean slate
400
{
401
  if (info->cache_pos == info->cache_end)
402
    return -1;                      /* End of buffer */
327.1.5 by Brian Aker
Refactor around classes. TABLE_LIST has been factored out of table.h
403
  Table *table= info->table;
1 by brian
clean slate
404
  (*table->sort.unpack)(table->sort.addon_field, info->cache_pos);
405
  info->cache_pos+= info->ref_length;
406
407
  return 0;
408
}
409
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
410
/* cacheing of records from a database */
1539.1.4 by Brian Aker
More RR encapsulation.
411
bool ReadRecord::init_rr_cache()
1 by brian
clean slate
412
{
1539.1.4 by Brian Aker
More RR encapsulation.
413
  uint32_t local_rec_cache_size;
414
415
  struct_length= 3 + MAX_REFLENGTH;
1578.2.8 by Brian Aker
Encapsulate record length.
416
  reclength= ALIGN_SIZE(table->getShare()->getRecordLength() + 1);
1539.1.4 by Brian Aker
More RR encapsulation.
417
  if (reclength < struct_length)
418
    reclength= ALIGN_SIZE(struct_length);
419
1578.2.8 by Brian Aker
Encapsulate record length.
420
  error_offset= table->getShare()->getRecordLength();
1539.1.4 by Brian Aker
More RR encapsulation.
421
  cache_records= (session->variables.read_rnd_buff_size /
1578.2.8 by Brian Aker
Encapsulate record length.
422
                        (reclength + struct_length));
1539.1.4 by Brian Aker
More RR encapsulation.
423
  local_rec_cache_size= cache_records * reclength;
424
  rec_cache_size= cache_records * ref_length;
1 by brian
clean slate
425
1796.4.10 by Andrew Hutchings
Add global constraint for --read-rnd-buffer-size
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
1 by brian
clean slate
432
  // We have to allocate one more byte to use uint3korr (see comments for it)
1578.4.13 by Brian Aker
Revert records
433
  if (cache_records <= 2 ||
434
      !(cache=(unsigned char*) malloc(local_rec_cache_size + cache_records * struct_length + 1)))
435
  {
1539.1.4 by Brian Aker
More RR encapsulation.
436
    return false;
1578.4.13 by Brian Aker
Revert records
437
  }
1859.2.14 by Brian Aker
Add support for --with-valgrind
438
#ifdef HAVE_VALGRIND
1578.4.13 by Brian Aker
Revert records
439
  // Avoid warnings in qsort
440
  memset(cache, 0, local_rec_cache_size + cache_records * struct_length + 1);
441
#endif
442
  read_positions= cache + local_rec_cache_size;
443
  cache_pos= cache_end= cache;
1539.1.4 by Brian Aker
More RR encapsulation.
444
445
  return true;
1 by brian
clean slate
446
} /* init_rr_cache */
447
1538 by Brian Aker
Code shuffle on ReadRecord
448
static int rr_from_cache(ReadRecord *info)
1 by brian
clean slate
449
{
308 by Brian Aker
ulong conversion
450
  uint32_t length;
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
451
  internal::my_off_t rest_of_file;
206 by Brian Aker
Removed final uint dead types.
452
  int16_t error;
481 by Brian Aker
Remove all of uchar.
453
  unsigned char *position,*ref_position,*record_pos;
308 by Brian Aker
ulong conversion
454
  uint32_t record;
1 by brian
clean slate
455
456
  for (;;)
457
  {
458
    if (info->cache_pos != info->cache_end)
459
    {
460
      if (info->cache_pos[info->error_offset])
461
      {
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
462
        shortget(error,info->cache_pos);
463
        if (info->print_error)
1216.1.1 by Brian Aker
Move print_error up to Engine.
464
          info->table->print_error(error,MYF(0));
1 by brian
clean slate
465
      }
466
      else
467
      {
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
468
        error=0;
1578.2.8 by Brian Aker
Encapsulate record length.
469
        memcpy(info->record,info->cache_pos, (size_t) info->table->getShare()->getRecordLength());
1 by brian
clean slate
470
      }
1578.2.8 by Brian Aker
Encapsulate record length.
471
      info->cache_pos+= info->reclength;
1 by brian
clean slate
472
      return ((int) error);
473
    }
474
    length=info->rec_cache_size;
1578.4.7 by Brian Aker
Small syntax update.
475
    rest_of_file= info->io_cache->end_of_file - my_b_tell(info->io_cache);
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
476
    if ((internal::my_off_t) length > rest_of_file)
1578.4.7 by Brian Aker
Small syntax update.
477
    {
308 by Brian Aker
ulong conversion
478
      length= (uint32_t) rest_of_file;
1578.4.7 by Brian Aker
Small syntax update.
479
    }
480
1578.4.6 by Brian Aker
Modify cache to be a vector.
481
    if (!length || my_b_read(info->io_cache, info->getCache(), length))
1 by brian
clean slate
482
    {
1208.3.2 by brian
Update for Cursor renaming.
483
      return -1;			/* End of cursor */
1 by brian
clean slate
484
    }
485
486
    length/=info->ref_length;
1578.4.6 by Brian Aker
Modify cache to be a vector.
487
    position=info->getCache();
1 by brian
clean slate
488
    ref_position=info->read_positions;
1749.3.12 by Brian Aker
Localize increment
489
    for (uint32_t i= 0 ; i < length ; i++,position+=info->ref_length)
1 by brian
clean slate
490
    {
491
      memcpy(ref_position,position,(size_t) info->ref_length);
492
      ref_position+=MAX_REFLENGTH;
493
      int3store(ref_position,(long) i);
494
      ref_position+=3;
495
    }
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
496
    internal::my_qsort(info->read_positions, length, info->struct_length,
497
                       (qsort_cmp) rr_cmp);
1 by brian
clean slate
498
499
    position=info->read_positions;
1749.3.12 by Brian Aker
Localize increment
500
    for (uint32_t i= 0 ; i < length ; i++)
1 by brian
clean slate
501
    {
1578.4.13 by Brian Aker
Revert records
502
      memcpy(info->ref_pos, position, (size_t)info->ref_length);
1 by brian
clean slate
503
      position+=MAX_REFLENGTH;
504
      record=uint3korr(position);
505
      position+=3;
1578.4.13 by Brian Aker
Revert records
506
      record_pos= info->getCache() + record * info->reclength;
1208.3.2 by brian
Update for Cursor renaming.
507
      if ((error=(int16_t) info->cursor->rnd_pos(record_pos,info->ref_pos)))
1 by brian
clean slate
508
      {
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
509
        record_pos[info->error_offset]=1;
510
        shortstore(record_pos,error);
1 by brian
clean slate
511
      }
512
      else
1039.2.8 by Jay Pipes
Yet more indentation and style cleanup
513
        record_pos[info->error_offset]=0;
1 by brian
clean slate
514
    }
1578.4.7 by Brian Aker
Small syntax update.
515
    info->cache_end= (info->cache_pos= info->getCache())+length*info->reclength;
1 by brian
clean slate
516
  }
517
} /* rr_from_cache */
518
481 by Brian Aker
Remove all of uchar.
519
static int rr_cmp(unsigned char *a,unsigned char *b)
1 by brian
clean slate
520
{
521
  if (a[0] != b[0])
522
    return (int) a[0] - (int) b[0];
523
  if (a[1] != b[1])
524
    return (int) a[1] - (int) b[1];
525
  if (a[2] != b[2])
526
    return (int) a[2] - (int) b[2];
527
#if MAX_REFLENGTH == 4
528
  return (int) a[3] - (int) b[3];
529
#else
530
  if (a[3] != b[3])
531
    return (int) a[3] - (int) b[3];
532
  if (a[4] != b[4])
533
    return (int) a[4] - (int) b[4];
534
  if (a[5] != b[5])
535
    return (int) a[1] - (int) b[5];
536
  if (a[6] != b[6])
537
    return (int) a[6] - (int) b[6];
538
  return (int) a[7] - (int) b[7];
539
#endif
540
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
541
542
} /* namespace drizzled */