~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

  • Committer: Brian Aker
  • Date: 2010-03-22 01:37:35 UTC
  • mfrom: (1372.1.3 build)
  • Revision ID: brian@gaz-20100322013735-upyu2zbhfqtuh0vr
Merge Brian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1281
1281
  return 0;
1282
1282
}
1283
1283
 
 
1284
static bool locked_create_event(Session *session,
 
1285
                                TableIdentifier &identifier,
 
1286
                                HA_CREATE_INFO *create_info,
 
1287
                                message::Table &table_proto,
 
1288
                                AlterInfo *alter_info,
 
1289
                                bool is_if_not_exists,
 
1290
                                bool lex_identified_temp_table,
 
1291
                                bool internal_tmp_table,
 
1292
                                uint db_options,
 
1293
                                uint key_count,
 
1294
                                KEY *key_info_buffer)
 
1295
{
 
1296
  bool error= true;
 
1297
 
 
1298
  {
 
1299
 
 
1300
    /*
 
1301
      @note if we are building a temp table we need to check to see if a temp table
 
1302
      already exists, otherwise we just need to find out if a normal table exists (aka it is fine
 
1303
      to create a table under a temporary table.
 
1304
    */
 
1305
    bool exists= 
 
1306
      plugin::StorageEngine::doesTableExist(*session, identifier, lex_identified_temp_table);
 
1307
 
 
1308
    if (exists)
 
1309
    {
 
1310
      if (is_if_not_exists)
 
1311
      {
 
1312
        error= false;
 
1313
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1314
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
 
1315
                            identifier.getTableName().c_str());
 
1316
        create_info->table_existed= 1;          // Mark that table existed
 
1317
        return error;
 
1318
      }
 
1319
 
 
1320
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
 
1321
      return error;
 
1322
    }
 
1323
 
 
1324
    if (not lex_identified_temp_table) // We have a real table
 
1325
    {
 
1326
      /*
 
1327
        We don't assert here, but check the result, because the table could be
 
1328
        in the table definition cache and in the same time the .frm could be
 
1329
        missing from the disk, in case of manual intervention which deletes
 
1330
        the .frm cursor. The user has to use FLUSH TABLES; to clear the cache.
 
1331
        Then she could create the table. This case is pretty obscure and
 
1332
        therefore we don't introduce a new error message only for it.
 
1333
      */
 
1334
      /*
 
1335
        @todo improve this error condition.
 
1336
      */
 
1337
      if (TableShare::getShare(identifier))
 
1338
      {
 
1339
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
 
1340
        return error;
 
1341
      }
 
1342
    }
 
1343
  }
 
1344
 
 
1345
  session->set_proc_info("creating table");
 
1346
  create_info->table_existed= 0;                // Mark that table is created
 
1347
 
 
1348
  create_info->table_options= db_options;
 
1349
 
 
1350
  if (not rea_create_table(session, identifier,
 
1351
                           table_proto,
 
1352
                           create_info, alter_info->create_list,
 
1353
                           key_count, key_info_buffer))
 
1354
  {
 
1355
    return error;
 
1356
  }
 
1357
 
 
1358
  if (lex_identified_temp_table)
 
1359
  {
 
1360
    /* Open table and put in temporary table list */
 
1361
    if (not (session->open_temporary_table(identifier)))
 
1362
    {
 
1363
      (void) session->rm_temporary_table(identifier);
 
1364
      return error;
 
1365
    }
 
1366
  }
 
1367
 
 
1368
  /* 
 
1369
    We keep this behind the lock to make sure ordering is correct for a table.
 
1370
    This is a very unlikely problem where before we would write out to the
 
1371
    trans log, someone would do a delete/create operation.
 
1372
  */
 
1373
 
 
1374
  if (table_proto.type() == message::Table::STANDARD && not internal_tmp_table)
 
1375
  {
 
1376
    TransactionServices &transaction_services= TransactionServices::singleton();
 
1377
    transaction_services.createTable(session, table_proto);
 
1378
  }
 
1379
 
 
1380
  return false;
 
1381
}
 
1382
 
1284
1383
 
1285
1384
/*
1286
1385
  Ignore the name of this function... it locks :(
1343
1442
 
1344
1443
  set_table_default_charset(create_info, identifier.getDBName().c_str());
1345
1444
 
1346
 
  /* Check if table exists */
1347
 
  if (mysql_prepare_create_table(session, create_info, table_proto, alter_info,
 
1445
  /* Build a Table object to pass down to the engine, and the do the actual create. */
 
1446
  if (not mysql_prepare_create_table(session, create_info, table_proto, alter_info,
1348
1447
                                 internal_tmp_table,
1349
1448
                                 &db_options,
1350
1449
                                 &key_info_buffer, &key_count,
1351
1450
                                 select_field_count))
1352
 
    goto err;
1353
 
 
1354
 
  /* Check if table already exists */
1355
 
  if (lex_identified_temp_table && session->find_temporary_table(identifier))
 
1451
  {
 
1452
    pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
 
1453
    error= locked_create_event(session,
 
1454
                               identifier,
 
1455
                               create_info,
 
1456
                               table_proto,
 
1457
                               alter_info,
 
1458
                               is_if_not_exists,
 
1459
                               lex_identified_temp_table,
 
1460
                               internal_tmp_table,
 
1461
                               db_options, key_count,
 
1462
                               key_info_buffer);
 
1463
    pthread_mutex_unlock(&LOCK_open);
 
1464
  }
 
1465
 
 
1466
  session->set_proc_info("After create");
 
1467
 
 
1468
  return(error);
 
1469
}
 
1470
 
 
1471
/**
 
1472
  @note the following two methods implement create [temporary] table.
 
1473
*/
 
1474
static bool drizzle_create_table(Session *session,
 
1475
                                 TableIdentifier &identifier,
 
1476
                                 HA_CREATE_INFO *create_info,
 
1477
                                 message::Table &table_proto,
 
1478
                                 AlterInfo *alter_info,
 
1479
                                 bool internal_tmp_table,
 
1480
                                 uint32_t select_field_count,
 
1481
                                 bool is_if_not_exists)
 
1482
{
 
1483
  Table *name_lock= NULL;
 
1484
  bool result;
 
1485
 
 
1486
  if (session->lock_table_name_if_not_cached(identifier, &name_lock))
 
1487
  {
 
1488
    result= true;
 
1489
  }
 
1490
  else if (name_lock == NULL)
1356
1491
  {
1357
1492
    if (is_if_not_exists)
1358
1493
    {
1359
 
      create_info->table_existed= 1;            // Mark that table existed
1360
1494
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1361
1495
                          ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1362
1496
                          identifier.getTableName().c_str());
1363
 
      error= 0;
1364
 
      goto err;
1365
 
    }
1366
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
1367
 
    goto err;
1368
 
  }
1369
 
 
1370
 
  pthread_mutex_lock(&LOCK_open); /* CREATE TABLE (some confussion on naming, double check) */
1371
 
  if (not internal_tmp_table && not lex_identified_temp_table)
1372
 
  {
1373
 
    if (plugin::StorageEngine::doesTableExist(*session, identifier, false))
1374
 
    {
1375
 
      if (is_if_not_exists)
1376
 
      {
1377
 
        error= false;
1378
 
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1379
 
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1380
 
                            identifier.getTableName().c_str());
1381
 
        create_info->table_existed= 1;          // Mark that table existed
1382
 
      }
1383
 
      else 
1384
 
      {
1385
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
1386
 
      }
1387
 
 
1388
 
      goto unlock_and_end;
1389
 
    }
1390
 
    /*
1391
 
      We don't assert here, but check the result, because the table could be
1392
 
      in the table definition cache and in the same time the .frm could be
1393
 
      missing from the disk, in case of manual intervention which deletes
1394
 
      the .frm cursor. The user has to use FLUSH TABLES; to clear the cache.
1395
 
      Then she could create the table. This case is pretty obscure and
1396
 
      therefore we don't introduce a new error message only for it.
1397
 
    */
1398
 
    if (TableShare::getShare(identifier))
1399
 
    {
1400
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
1401
 
      goto unlock_and_end;
1402
 
    }
1403
 
  }
1404
 
 
1405
 
  /*
1406
 
    Check that table with given name does not already
1407
 
    exist in any storage engine. In such a case it should
1408
 
    be discovered and the error ER_TABLE_EXISTS_ERROR be returned
1409
 
    unless user specified CREATE TABLE IF EXISTS
1410
 
    The LOCK_open mutex has been locked to make sure no
1411
 
    one else is attempting to discover the table. Since
1412
 
    it's not on disk as a frm cursor, no one could be using it!
1413
 
  */
1414
 
  if (not lex_identified_temp_table)
1415
 
  {
1416
 
    bool exists= plugin::StorageEngine::doesTableExist(*session, identifier, false);
1417
 
 
1418
 
    if (exists)
1419
 
    {
1420
 
      if (is_if_not_exists)
1421
 
      {
1422
 
        error= false;
1423
 
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1424
 
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1425
 
                            identifier.getTableName().c_str());
1426
 
        create_info->table_existed= 1;          // Mark that table existed
1427
 
        goto unlock_and_end;
1428
 
      }
1429
 
 
1430
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
1431
 
      goto unlock_and_end;
1432
 
    }
1433
 
  }
1434
 
 
1435
 
  session->set_proc_info("creating table");
1436
 
  create_info->table_existed= 0;                // Mark that table is created
1437
 
 
1438
 
  create_info->table_options= db_options;
1439
 
 
1440
 
  if (rea_create_table(session, identifier,
1441
 
                       table_proto,
1442
 
                       create_info, alter_info->create_list,
1443
 
                       key_count, key_info_buffer))
1444
 
  {
1445
 
    goto unlock_and_end;
1446
 
  }
1447
 
 
1448
 
  if (lex_identified_temp_table)
1449
 
  {
1450
 
    /* Open table and put in temporary table list */
1451
 
    if (not (session->open_temporary_table(identifier)))
1452
 
    {
1453
 
      (void) session->rm_temporary_table(identifier);
1454
 
      goto unlock_and_end;
1455
 
    }
1456
 
  }
1457
 
 
1458
 
  if (not internal_tmp_table && not lex_identified_temp_table)
1459
 
  {
1460
 
    TransactionServices &transaction_services= TransactionServices::singleton();
1461
 
    transaction_services.createTable(session, table_proto);
1462
 
  }
1463
 
  error= false;
1464
 
unlock_and_end:
1465
 
  pthread_mutex_unlock(&LOCK_open);
1466
 
 
1467
 
err:
1468
 
  session->set_proc_info("After create");
1469
 
 
1470
 
  return(error);
 
1497
      create_info->table_existed= 1;
 
1498
      result= false;
 
1499
    }
 
1500
    else
 
1501
    {
 
1502
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
 
1503
      result= true;
 
1504
    }
 
1505
  }
 
1506
  else
 
1507
  {
 
1508
    result= mysql_create_table_no_lock(session,
 
1509
                                       identifier,
 
1510
                                       create_info,
 
1511
                                       table_proto,
 
1512
                                       alter_info,
 
1513
                                       internal_tmp_table,
 
1514
                                       select_field_count,
 
1515
                                       is_if_not_exists);
 
1516
  }
 
1517
 
 
1518
  if (name_lock)
 
1519
  {
 
1520
    pthread_mutex_lock(&LOCK_open); /* Lock for removing name_lock during table create */
 
1521
    session->unlink_open_table(name_lock);
 
1522
    pthread_mutex_unlock(&LOCK_open);
 
1523
  }
 
1524
 
 
1525
  return(result);
1471
1526
}
1472
1527
 
1473
1528
 
1474
1529
/*
1475
1530
  Database locking aware wrapper for mysql_create_table_no_lock(),
1476
1531
*/
1477
 
 
1478
1532
bool mysql_create_table(Session *session,
1479
1533
                        TableIdentifier &identifier,
1480
1534
                        HA_CREATE_INFO *create_info,
1484
1538
                        uint32_t select_field_count,
1485
1539
                        bool is_if_not_exists)
1486
1540
{
1487
 
  Table *name_lock= NULL;
1488
 
  bool result;
1489
1541
  bool lex_identified_temp_table=
1490
1542
    (table_proto.type() == message::Table::TEMPORARY);
1491
1543
 
1492
 
  if (not lex_identified_temp_table)
1493
 
  {
1494
 
    if (session->lock_table_name_if_not_cached(identifier, &name_lock))
1495
 
    {
1496
 
      result= true;
1497
 
      goto unlock;
1498
 
    }
1499
 
    if (name_lock == NULL)
1500
 
    {
1501
 
      if (is_if_not_exists)
1502
 
      {
1503
 
        push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1504
 
                            ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1505
 
                            identifier.getTableName().c_str());
1506
 
        create_info->table_existed= 1;
1507
 
        result= false;
1508
 
      }
1509
 
      else
1510
 
      {
1511
 
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), identifier.getTableName().c_str());
1512
 
        result= true;
1513
 
      }
1514
 
      goto unlock;
1515
 
    }
1516
 
  }
1517
 
 
1518
 
  result= mysql_create_table_no_lock(session,
1519
 
                                     identifier,
1520
 
                                     create_info,
1521
 
                                     table_proto,
1522
 
                                     alter_info,
1523
 
                                     internal_tmp_table,
1524
 
                                     select_field_count,
1525
 
                                     is_if_not_exists);
1526
 
 
1527
 
unlock:
1528
 
  if (name_lock)
1529
 
  {
1530
 
    pthread_mutex_lock(&LOCK_open); /* Lock for removing name_lock during table create */
1531
 
    session->unlink_open_table(name_lock);
1532
 
    pthread_mutex_unlock(&LOCK_open);
1533
 
  }
1534
 
 
1535
 
  return(result);
 
1544
  if (lex_identified_temp_table)
 
1545
  {
 
1546
    return mysql_create_table_no_lock(session,
 
1547
                                      identifier,
 
1548
                                      create_info,
 
1549
                                      table_proto,
 
1550
                                      alter_info,
 
1551
                                      internal_tmp_table,
 
1552
                                      select_field_count,
 
1553
                                      is_if_not_exists);
 
1554
  }
 
1555
  else
 
1556
  {
 
1557
    return drizzle_create_table(session,
 
1558
                                identifier,
 
1559
                                create_info,
 
1560
                                table_proto,
 
1561
                                alter_info,
 
1562
                                internal_tmp_table,
 
1563
                                select_field_count,
 
1564
                                is_if_not_exists);
 
1565
  }
1536
1566
}
1537
1567
 
1538
1568