~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/csv/ha_tina.cc

  • Committer: Prafulla Tekawade
  • Date: 2010-08-06 11:21:12 UTC
  • mto: (1711.1.21 build) (1725.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1714.
  • Revision ID: prafulla_t@users.sourceforge.net-20100806112112-7w5u0s3nx9u67nzt
Fix for Bug 586051

1. test_if_ref method which checks whether predicate is already evaluated
   due to ref/eq_ref access or not was incorrectly removing a predicate 
   that was not implicitly evaluated due to ref access (due to presence of filesort ?)
   It was field=NULL predicate.
   Such predicate should be kept and execution engine will filter out rows
   correctly. Removal of such predicate led to returning of rows which had
   NULL for join/predicate columns.
2. field COMP_OP NULL will always false for all fields except when COMP_OP
   is NULL-safe equality operator. Modified range optimizer to return zero
   row count in such cases.
   Query now does not even run. It returns zero result. As such Fix(1) is not
   required but we might hit that case in some other query (I have not tried it
   yet)
3. Fixed Field::val_str to print "NULL" for literal NULL instead of "0". It
   added lot of confusion while debugging.

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
  Make sure to look at ha_tina.h for more details.
112
112
    pthread_mutex_destroy(&tina_mutex);
113
113
  }
114
114
 
115
 
  virtual Cursor *create(Table &table)
 
115
  virtual Cursor *create(TableShare &table)
116
116
  {
117
117
    return new ha_tina(*this, table);
118
118
  }
130
130
                           const drizzled::TableIdentifier &identifier,
131
131
                           drizzled::message::Table &table_message);
132
132
 
 
133
  /* Temp only engine, so do not return values. */
 
134
  void doGetTableNames(drizzled::CachedDirectory &, const SchemaIdentifier&, set<string>&) { };
 
135
 
133
136
  int doDropTable(Session&, const drizzled::TableIdentifier &identifier);
134
137
  TinaShare *findOpenTable(const string table_name);
135
138
  void addOpenTable(const string &table_name, TinaShare *);
144
147
 
145
148
  void doGetTableIdentifiers(drizzled::CachedDirectory &directory,
146
149
                             const drizzled::SchemaIdentifier &schema_identifier,
147
 
                             drizzled::TableIdentifier::vector &set_of_identifiers);
 
150
                             drizzled::TableIdentifiers &set_of_identifiers);
148
151
};
149
152
 
150
153
void Tina::doGetTableIdentifiers(drizzled::CachedDirectory&,
151
154
                                 const drizzled::SchemaIdentifier&,
152
 
                                 drizzled::TableIdentifier::vector&)
 
155
                                 drizzled::TableIdentifiers&)
153
156
{
154
157
}
155
158
 
167
170
    }
168
171
  }
169
172
 
170
 
  session.getMessageCache().renameTableMessage(from, to);
 
173
  session.renameTableMessage(from, to);
171
174
 
172
175
  return error;
173
176
}
174
177
 
175
178
bool Tina::doDoesTableExist(Session &session, const drizzled::TableIdentifier &identifier)
176
179
{
177
 
  return session.getMessageCache().doesTableMessageExist(identifier);
 
180
  return session.doesTableMessageExist(identifier);
178
181
}
179
182
 
180
183
 
183
186
{
184
187
  int error= 0;
185
188
  int enoent_or_zero= ENOENT;                   // Error if no file was deleted
 
189
  char buff[FN_REFLEN];
186
190
 
187
191
  for (const char **ext= bas_ext(); *ext ; ext++)
188
192
  {
189
 
    std::string full_name= identifier.getPath();
190
 
    full_name.append(*ext);
191
 
 
192
 
    if (internal::my_delete_with_symlink(full_name.c_str(), MYF(0)))
 
193
    internal::fn_format(buff, identifier.getPath().c_str(), "", *ext,
 
194
                        MY_UNPACK_FILENAME|MY_APPEND_EXT);
 
195
    if (internal::my_delete_with_symlink(buff, MYF(0)))
193
196
    {
194
197
      if ((error= errno) != ENOENT)
195
198
        break;
196
199
    }
197
200
    else
198
 
    {
199
201
      enoent_or_zero= 0;                        // No error for ENOENT
200
 
    }
201
202
    error= enoent_or_zero;
202
203
  }
203
204
 
204
 
  session.getMessageCache().removeTableMessage(identifier);
 
205
  session.removeTableMessage(identifier);
205
206
 
206
207
  return error;
207
208
}
232
233
                               const drizzled::TableIdentifier &identifier,
233
234
                               drizzled::message::Table &table_message)
234
235
{
235
 
  if (session.getMessageCache().getTableMessage(identifier, table_message))
 
236
  if (session.getTableMessage(identifier, table_message))
236
237
    return EEXIST;
237
238
 
238
239
  return ENOENT;
253
254
 
254
255
 
255
256
 
256
 
TinaShare::TinaShare(const std::string &table_name_arg) : 
257
 
  table_name(table_name_arg),
258
 
  data_file_name(table_name_arg),
259
 
  use_count(0),
260
 
  saved_data_file_length(0),
261
 
  update_file_opened(false),
262
 
  tina_write_opened(false),
263
 
  crashed(false),
264
 
  rows_recorded(0),
265
 
  data_file_version(0)
 
257
TinaShare::TinaShare(const char *table_name_arg)
 
258
  : table_name(table_name_arg), use_count(0), saved_data_file_length(0),
 
259
    update_file_opened(false), tina_write_opened(false),
 
260
    crashed(false), rows_recorded(0), data_file_version(0)
266
261
{
267
 
  data_file_name.append(CSV_EXT);
 
262
  thr_lock_init(&lock);
 
263
  internal::fn_format(data_file_name, table_name_arg, "", CSV_EXT,
 
264
            MY_REPLACE_EXT|MY_UNPACK_FILENAME);
268
265
}
269
266
 
270
267
TinaShare::~TinaShare()
271
268
{
 
269
  thr_lock_delete(&lock);
272
270
  pthread_mutex_destroy(&mutex);
273
271
}
274
272
 
275
273
/*
276
274
  Simple lock controls.
277
275
*/
278
 
TinaShare *ha_tina::get_share(const std::string &table_name)
 
276
TinaShare *ha_tina::get_share(const char *table_name)
279
277
{
280
278
  pthread_mutex_lock(&tina_mutex);
281
279
 
282
 
  Tina *a_tina= static_cast<Tina *>(getEngine());
 
280
  Tina *a_tina= static_cast<Tina *>(engine);
283
281
  share= a_tina->findOpenTable(table_name);
284
282
 
285
 
  std::string meta_file_name;
 
283
  char meta_file_name[FN_REFLEN];
286
284
  struct stat file_stat;
287
285
 
288
286
  /*
299
297
      return NULL;
300
298
    }
301
299
 
302
 
    meta_file_name.assign(table_name);
303
 
    meta_file_name.append(CSM_EXT);
 
300
    internal::fn_format(meta_file_name, table_name, "", CSM_EXT,
 
301
              MY_REPLACE_EXT|MY_UNPACK_FILENAME);
304
302
 
305
 
    if (stat(share->data_file_name.c_str(), &file_stat))
 
303
    if (stat(share->data_file_name, &file_stat))
306
304
    {
307
305
      pthread_mutex_unlock(&tina_mutex);
308
306
      delete share;
321
319
      Usually this will result in auto-repair, and we will get a good
322
320
      meta-file in the end.
323
321
    */
324
 
    if ((share->meta_file= internal::my_open(meta_file_name.c_str(),
 
322
    if ((share->meta_file= internal::my_open(meta_file_name,
325
323
                                             O_RDWR|O_CREAT, MYF(0))) == -1)
326
324
      share->crashed= true;
327
325
 
450
448
  (void)write_meta_file(share->meta_file, share->rows_recorded, true);
451
449
 
452
450
  if ((share->tina_write_filedes=
453
 
        internal::my_open(share->data_file_name.c_str(), O_RDWR|O_APPEND, MYF(0))) == -1)
 
451
        internal::my_open(share->data_file_name, O_RDWR|O_APPEND, MYF(0))) == -1)
454
452
  {
455
453
    share->crashed= true;
456
454
    return(1);
481
479
      share->tina_write_opened= false;
482
480
    }
483
481
 
484
 
    Tina *a_tina= static_cast<Tina *>(getEngine());
 
482
    Tina *a_tina= static_cast<Tina *>(engine);
485
483
    a_tina->deleteOpenTable(share->table_name);
486
484
    delete share;
487
485
  }
530
528
 
531
529
 
532
530
 
533
 
ha_tina::ha_tina(drizzled::plugin::StorageEngine &engine_arg, Table &table_arg)
 
531
ha_tina::ha_tina(drizzled::plugin::StorageEngine &engine_arg, TableShare &table_arg)
534
532
  :Cursor(engine_arg, table_arg),
535
533
  /*
536
534
    These definitions are found in Cursor.h
557
555
 
558
556
  buffer.length(0);
559
557
 
560
 
  for (Field **field= getTable()->getFields() ; *field ; field++)
 
558
  for (Field **field= table->getFields() ; *field ; field++)
561
559
  {
562
560
    const char *ptr;
563
561
    const char *end_ptr;
597
595
        {
598
596
          buffer.append('\\');
599
597
          buffer.append('"');
600
 
          (void) *ptr++;
 
598
          *ptr++;
601
599
        }
602
600
        else if (*ptr == '\r')
603
601
        {
604
602
          buffer.append('\\');
605
603
          buffer.append('r');
606
 
          (void) *ptr++;
 
604
          *ptr++;
607
605
        }
608
606
        else if (*ptr == '\\')
609
607
        {
610
608
          buffer.append('\\');
611
609
          buffer.append('\\');
612
 
          (void) *ptr++;
 
610
          *ptr++;
613
611
        }
614
612
        else if (*ptr == '\n')
615
613
        {
616
614
          buffer.append('\\');
617
615
          buffer.append('n');
618
 
          (void) *ptr++;
 
616
          *ptr++;
619
617
        }
620
618
        else
621
619
          buffer.append(*ptr++);
675
673
 
676
674
  error= HA_ERR_CRASHED_ON_USAGE;
677
675
 
678
 
  memset(buf, 0, getTable()->getShare()->null_bytes);
 
676
  memset(buf, 0, table->getShare()->null_bytes);
679
677
 
680
 
  for (Field **field= getTable()->getFields() ; *field ; field++)
 
678
  for (Field **field=table->getFields() ; *field ; field++)
681
679
  {
682
680
    char curr_char;
683
681
 
746
744
    {
747
745
      /* This masks a bug in the logic for a SELECT * */
748
746
      (*field)->setWriteSet();
749
 
      if ((*field)->store_and_check(CHECK_FIELD_WARN, buffer.c_ptr(), buffer.length(), buffer.charset()))
750
 
      {
 
747
      if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(),
 
748
                          CHECK_FIELD_WARN))
751
749
        goto err;
752
 
      }
753
750
 
754
751
      if ((*field)->flags & BLOB_FLAG)
755
752
      {
784
781
*/
785
782
int ha_tina::doOpen(const TableIdentifier &identifier, int , uint32_t )
786
783
{
787
 
  if (not (share= get_share(identifier.getPath().c_str())))
 
784
  if (!(share= get_share(identifier.getPath().c_str())))
788
785
    return(ENOENT);
789
786
 
790
787
  if (share->crashed)
794
791
  }
795
792
 
796
793
  local_data_file_version= share->data_file_version;
797
 
  if ((data_file= internal::my_open(share->data_file_name.c_str(), O_RDONLY, MYF(0))) == -1)
 
794
  if ((data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
798
795
    return(0);
799
796
 
800
797
  /*
802
799
    so that they could save/update local_saved_data_file_length value
803
800
    during locking. This is needed to enable concurrent inserts.
804
801
  */
 
802
  thr_lock_data_init(&share->lock, &lock);
805
803
  ref_length=sizeof(off_t);
806
804
 
807
805
  return(0);
957
955
  {
958
956
    local_data_file_version= share->data_file_version;
959
957
    if (internal::my_close(data_file, MYF(0)) ||
960
 
        (data_file= internal::my_open(share->data_file_name.c_str(), O_RDONLY, MYF(0))) == -1)
 
958
        (data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1)
961
959
      return 1;
962
960
  }
963
961
  file_buff->init_buff(data_file);
1110
1108
*/
1111
1109
int ha_tina::doEndTableScan()
1112
1110
{
 
1111
  char updated_fname[FN_REFLEN];
1113
1112
  off_t file_buffer_start= 0;
1114
1113
 
1115
1114
  blobroot.free_root(MYF(0));
1194
1193
      Close opened fildes's. Then move updated file in place
1195
1194
      of the old datafile.
1196
1195
    */
1197
 
    std::string rename_file= share->table_name;
1198
 
    rename_file.append(CSN_EXT);
1199
1196
    if (internal::my_close(data_file, MYF(0)) ||
1200
 
        internal::my_rename(rename_file.c_str(),
1201
 
                            share->data_file_name.c_str(), MYF(0)))
 
1197
        internal::my_rename(internal::fn_format(updated_fname,
 
1198
                                                share->table_name.c_str(),
 
1199
                                                "", CSN_EXT,
 
1200
                                                MY_REPLACE_EXT | MY_UNPACK_FILENAME),
 
1201
                            share->data_file_name, MYF(0)))
1202
1202
      return(-1);
1203
1203
 
1204
1204
    /* Open the file again */
1205
 
    if (((data_file= internal::my_open(share->data_file_name.c_str(), O_RDONLY, MYF(0))) == -1))
 
1205
    if (((data_file= internal::my_open(share->data_file_name, O_RDONLY, MYF(0))) == -1))
1206
1206
      return(-1);
1207
1207
    /*
1208
1208
      As we reopened the data file, increase share->data_file_version
1309
1309
 
1310
1310
  internal::my_close(create_file, MYF(0));
1311
1311
 
1312
 
  session.getMessageCache().storeTableMessage(identifier, create_proto);
 
1312
  session.storeTableMessage(identifier, create_proto);
1313
1313
 
1314
1314
  return 0;
1315
1315
}