~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/message/statement_transform.cc

  • Committer: Brian Aker
  • Date: 2011-02-03 18:12:09 UTC
  • mfrom: (2134.1.9 timestamp)
  • mto: This revision was merged to the branch mainline in revision 2140.
  • Revision ID: brian@tangent.org-20110203181209-xr7i2079pdmu33hd
Merge in table tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 * Statement messages to other formats, including SQL strings.
30
30
 */
31
31
 
32
 
#include <config.h>
 
32
#include "config.h"
33
33
 
34
34
#include <boost/lexical_cast.hpp>
35
 
#include <drizzled/message/statement_transform.h>
36
 
#include <drizzled/message/transaction.pb.h>
37
 
#include <drizzled/message/table.pb.h>
38
 
#include <drizzled/charset.h>
39
 
#include <drizzled/charset_info.h>
40
 
#include <drizzled/global_charset_info.h>
 
35
#include "drizzled/message/statement_transform.h"
 
36
#include "drizzled/message/transaction.pb.h"
 
37
#include "drizzled/message/table.pb.h"
 
38
#include "drizzled/charset.h"
 
39
#include "drizzled/charset_info.h"
 
40
#include "drizzled/global_charset_info.h"
41
41
 
42
42
#include <string>
43
43
#include <vector>
152
152
      const InsertHeader &insert_header= source.insert_header();
153
153
      const InsertData &insert_data= source.insert_data();
154
154
      size_t num_keys= insert_data.record_size();
 
155
      size_t x;
155
156
 
156
157
      if (num_keys > 1 && ! already_in_transaction)
157
158
        sql_strings.push_back("START TRANSACTION");
158
159
 
159
 
      for (size_t x= 0; x < num_keys; ++x)
 
160
      for (x= 0; x < num_keys; ++x)
160
161
      {
161
162
        string destination;
162
163
 
873
874
 
874
875
  const Schema &schema= statement.schema();
875
876
 
876
 
  destination.append("CREATE SCHEMA ");
 
877
  destination.append("CREATE SCHEMA ", 14);
877
878
  destination.push_back(quoted_identifier);
878
879
  destination.append(schema.name());
879
880
  destination.push_back(quoted_identifier);
880
881
 
881
882
  if (schema.has_collation())
882
883
  {
883
 
    destination.append(" COLLATE ");
 
884
    destination.append(" COLLATE ", 9);
884
885
    destination.append(schema.collation());
885
886
  }
886
887
 
887
 
  if (schema.has_replication_options() and schema.replication_options().has_dont_replicate() and schema.replication_options().dont_replicate())
888
 
  {
889
 
    destination.append(" REPLICATION = FALSE");
890
 
  }
891
 
 
892
888
  return NONE;
893
889
}
894
890
 
903
899
 
904
900
  const TableMetadata &table_metadata= statement.table_metadata();
905
901
 
906
 
  destination.append("DROP TABLE ");
 
902
  destination.append("DROP TABLE ", 11);
907
903
 
908
904
  /* Add the IF EXISTS clause if necessary */
909
905
  if (statement.has_if_exists_clause() &&
910
906
      statement.if_exists_clause() == true)
911
907
  {
912
 
    destination.append("IF EXISTS ");
 
908
    destination.append("IF EXISTS ", 10);
913
909
  }
914
910
 
915
911
  destination.push_back(quoted_identifier);
934
930
 
935
931
  const TableMetadata &table_metadata= statement.table_metadata();
936
932
 
937
 
  destination.append("TRUNCATE TABLE ");
 
933
  destination.append("TRUNCATE TABLE ", 15);
938
934
  destination.push_back(quoted_identifier);
939
935
  destination.append(table_metadata.schema_name());
940
936
  destination.push_back(quoted_identifier);
955
951
  const FieldMetadata &variable_metadata= statement.variable_metadata();
956
952
  bool should_quote_field_value= shouldQuoteFieldValue(variable_metadata.type());
957
953
 
958
 
  destination.append("SET GLOBAL "); /* Only global variables are replicated */
 
954
  destination.append("SET GLOBAL ", 11); /* Only global variables are replicated */
959
955
  destination.append(variable_metadata.name());
960
956
  destination.push_back('=');
961
957
 
987
983
  if (sql_variant == ANSI)
988
984
    quoted_identifier= '"';
989
985
 
990
 
  destination.append("CREATE ");
 
986
  destination.append("CREATE ", 7);
991
987
 
992
988
  if (table.type() == Table::TEMPORARY)
993
 
    destination.append("TEMPORARY ");
 
989
    destination.append("TEMPORARY ", 10);
994
990
  
995
 
  destination.append("TABLE ");
 
991
  destination.append("TABLE ", 6);
996
992
  if (with_schema)
997
993
  {
998
994
    append_escaped_string(&destination, table.schema(), quoted_identifier);
999
995
    destination.push_back('.');
1000
996
  }
1001
997
  append_escaped_string(&destination, table.name(), quoted_identifier);
1002
 
  destination.append(" (\n");
 
998
  destination.append(" (\n", 3);
1003
999
 
1004
1000
  enum TransformSqlError result= NONE;
1005
1001
  size_t num_fields= table.field_size();
1008
1004
    const Table::Field &field= table.field(x);
1009
1005
 
1010
1006
    if (x != 0)
1011
 
      destination.append(",\n");
 
1007
      destination.append(",\n", 2);
1012
1008
 
1013
1009
    destination.append("  ");
1014
1010
 
1021
1017
  size_t num_indexes= table.indexes_size();
1022
1018
  
1023
1019
  if (num_indexes > 0)
1024
 
    destination.append(",\n");
 
1020
    destination.append(",\n", 2);
1025
1021
 
1026
1022
  for (size_t x= 0; x < num_indexes; ++x)
1027
1023
  {
1028
1024
    const message::Table::Index &index= table.indexes(x);
1029
1025
 
1030
1026
    if (x != 0)
1031
 
      destination.append(",\n");
 
1027
      destination.append(",\n", 2);
1032
1028
 
1033
1029
    result= transformIndexDefinitionToSql(index, table, destination, sql_variant);
1034
1030
    
1039
1035
  size_t num_foreign_keys= table.fk_constraint_size();
1040
1036
 
1041
1037
  if (num_foreign_keys > 0)
1042
 
    destination.append(",\n");
 
1038
    destination.append(",\n", 2);
1043
1039
 
1044
1040
  for (size_t x= 0; x < num_foreign_keys; ++x)
1045
1041
  {
1046
1042
    const message::Table::ForeignKeyConstraint &fkey= table.fk_constraint(x);
1047
1043
 
1048
1044
    if (x != 0)
1049
 
      destination.append(",\n");
 
1045
      destination.append(",\n", 2);
1050
1046
 
1051
1047
    result= transformForeignKeyConstraintDefinitionToSql(fkey, table, destination, sql_variant);
1052
1048
 
1054
1050
      return result;
1055
1051
  }
1056
1052
 
1057
 
  destination.append("\n)");
 
1053
  destination.append("\n)", 2);
1058
1054
 
1059
1055
  /* Add ENGINE = " clause */
1060
1056
  if (table.has_engine())
1061
1057
  {
1062
 
    destination.append(" ENGINE=");
 
1058
    destination.append(" ENGINE=", 8);
1063
1059
    destination.append(table.engine().name());
1064
1060
 
1065
1061
    size_t num_engine_options= table.engine().options_size();
1069
1065
    {
1070
1066
      const Engine::Option &option= table.engine().options(x);
1071
1067
      destination.append(option.name());
1072
 
      destination.append("='");
 
1068
      destination.append("='", 2);
1073
1069
      destination.append(option.state());
1074
 
      destination.append("'");
1075
 
      if (x != num_engine_options-1)
1076
 
      {
1077
 
        destination.append(", ");
1078
 
      }
 
1070
      destination.append("'", 1);
 
1071
      if(x != num_engine_options-1)
 
1072
        destination.append(", ", 2);
1079
1073
    }
1080
1074
  }
1081
1075
 
1095
1089
 
1096
1090
  if (options.has_comment())
1097
1091
  {
1098
 
    destination.append(" COMMENT=");
 
1092
    destination.append(" COMMENT=", 9);
1099
1093
    append_escaped_string(&destination, options.comment());
1100
1094
  }
1101
1095
 
1102
1096
  if (options.has_collation())
1103
1097
  {
1104
 
    destination.append(" COLLATE = ");
 
1098
    destination.append(" COLLATE = ", 11);
1105
1099
    destination.append(options.collation());
1106
1100
  }
1107
1101
 
1108
1102
  if (options.has_data_file_name())
1109
1103
  {
1110
 
    destination.append("\nDATA_FILE_NAME = '");
 
1104
    destination.append("\nDATA_FILE_NAME = '", 19);
1111
1105
    destination.append(options.data_file_name());
1112
1106
    destination.push_back('\'');
1113
1107
  }
1114
1108
 
1115
1109
  if (options.has_index_file_name())
1116
1110
  {
1117
 
    destination.append("\nINDEX_FILE_NAME = '");
 
1111
    destination.append("\nINDEX_FILE_NAME = '", 20);
1118
1112
    destination.append(options.index_file_name());
1119
1113
    destination.push_back('\'');
1120
1114
  }
1121
1115
 
1122
1116
  if (options.has_max_rows())
1123
1117
  {
1124
 
    destination.append("\nMAX_ROWS = ");
 
1118
    destination.append("\nMAX_ROWS = ", 12);
1125
1119
    destination.append(boost::lexical_cast<string>(options.max_rows()));
1126
1120
  }
1127
1121
 
1128
1122
  if (options.has_min_rows())
1129
1123
  {
1130
 
    destination.append("\nMIN_ROWS = ");
 
1124
    destination.append("\nMIN_ROWS = ", 12);
1131
1125
    destination.append(boost::lexical_cast<string>(options.min_rows()));
1132
1126
  }
1133
1127
 
1134
1128
  if (options.has_user_set_auto_increment_value()
1135
1129
      && options.has_auto_increment_value())
1136
1130
  {
1137
 
    destination.append(" AUTO_INCREMENT=");
 
1131
    destination.append(" AUTO_INCREMENT=", 16);
1138
1132
    destination.append(boost::lexical_cast<string>(options.auto_increment_value()));
1139
1133
  }
1140
1134
 
1141
1135
  if (options.has_avg_row_length())
1142
1136
  {
1143
 
    destination.append("\nAVG_ROW_LENGTH = ");
 
1137
    destination.append("\nAVG_ROW_LENGTH = ", 18);
1144
1138
    destination.append(boost::lexical_cast<string>(options.avg_row_length()));
1145
1139
  }
1146
1140
 
1147
 
  if (options.has_checksum() && options.checksum())
1148
 
    destination.append("\nCHECKSUM = TRUE");
1149
 
 
1150
 
  if (options.has_page_checksum() && options.page_checksum())
1151
 
    destination.append("\nPAGE_CHECKSUM = TRUE");
1152
 
 
1153
 
  if (options.has_dont_replicate() and options.dont_replicate())
1154
 
  {
1155
 
    destination.append(" REPLICATION = FALSE");
1156
 
  }
 
1141
  if (options.has_checksum() &&
 
1142
      options.checksum())
 
1143
    destination.append("\nCHECKSUM = TRUE", 16);
 
1144
  if (options.has_page_checksum() &&
 
1145
      options.page_checksum())
 
1146
    destination.append("\nPAGE_CHECKSUM = TRUE", 21);
1157
1147
 
1158
1148
  return NONE;
1159
1149
}
1171
1161
  destination.append("  ", 2);
1172
1162
 
1173
1163
  if (index.is_primary())
1174
 
    destination.append("PRIMARY ");
 
1164
    destination.append("PRIMARY ", 8);
1175
1165
  else if (index.is_unique())
1176
 
    destination.append("UNIQUE ");
 
1166
    destination.append("UNIQUE ", 7);
1177
1167
 
1178
1168
  destination.append("KEY ", 4);
1179
1169
  if (! (index.is_primary() && index.name().compare("PRIMARY")==0))
1225
1215
  case Table::Index::UNKNOWN_INDEX:
1226
1216
    break;
1227
1217
  case Table::Index::BTREE:
1228
 
    destination.append(" USING BTREE");
 
1218
    destination.append(" USING BTREE", 12);
1229
1219
    break;
1230
1220
  case Table::Index::RTREE:
1231
 
    destination.append(" USING RTREE");
 
1221
    destination.append(" USING RTREE", 12);
1232
1222
    break;
1233
1223
  case Table::Index::HASH:
1234
 
    destination.append(" USING HASH");
 
1224
    destination.append(" USING HASH", 11);
1235
1225
    break;
1236
1226
  case Table::Index::FULLTEXT:
1237
 
    destination.append(" USING FULLTEXT");
 
1227
    destination.append(" USING FULLTEXT", 15);
1238
1228
    break;
1239
1229
  }
1240
1230
 
1241
1231
  if (index.has_comment())
1242
1232
  {
1243
 
    destination.append(" COMMENT ");
 
1233
    destination.append(" COMMENT ", 9);
1244
1234
    append_escaped_string(&destination, index.comment());
1245
1235
  }
1246
1236
 
1280
1270
  if (sql_variant == ANSI)
1281
1271
    quoted_identifier= '"';
1282
1272
 
1283
 
  destination.append("  ");
 
1273
  destination.append("  ", 2);
1284
1274
 
1285
1275
  if (fkey.has_name())
1286
1276
  {
1287
 
    destination.append("CONSTRAINT ");
 
1277
    destination.append("CONSTRAINT ", 11);
1288
1278
    append_escaped_string(&destination, fkey.name(), quoted_identifier);
1289
1279
    destination.append(" ", 1);
1290
1280
  }
1291
1281
 
1292
 
  destination.append("FOREIGN KEY (");
 
1282
  destination.append("FOREIGN KEY (", 13);
1293
1283
 
1294
1284
  for (ssize_t x= 0; x < fkey.column_names_size(); ++x)
1295
1285
  {
1300
1290
                          quoted_identifier);
1301
1291
  }
1302
1292
 
1303
 
  destination.append(") REFERENCES ");
 
1293
  destination.append(") REFERENCES ", 13);
1304
1294
 
1305
1295
  append_escaped_string(&destination, fkey.references_table_name(),
1306
1296
                        quoted_identifier);
1307
 
  destination.append(" (");
 
1297
  destination.append(" (", 2);
1308
1298
 
1309
1299
  for (ssize_t x= 0; x < fkey.references_columns_size(); ++x)
1310
1300
  {
1319
1309
 
1320
1310
  if (fkey.has_update_option() and fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1321
1311
  {
1322
 
    destination.append(" ON UPDATE ");
 
1312
    destination.append(" ON UPDATE ", 11);
1323
1313
    transformForeignKeyOptionToSql(fkey.update_option(), destination);
1324
1314
  }
1325
1315
 
1326
1316
  if (fkey.has_delete_option() and fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1327
1317
  {
1328
 
    destination.append(" ON DELETE ");
 
1318
    destination.append(" ON DELETE ", 11);
1329
1319
    transformForeignKeyOptionToSql(fkey.delete_option(), destination);
1330
1320
  }
1331
1321
 
1355
1345
  switch (field_type)
1356
1346
  {
1357
1347
    case Table::Field::DOUBLE:
1358
 
    destination.append(" DOUBLE");
 
1348
    destination.append(" DOUBLE", 7);
1359
1349
    if (field.has_numeric_options()
1360
1350
        && field.numeric_options().has_precision())
1361
1351
    {
1369
1359
    {
1370
1360
      if (field.string_options().has_collation()
1371
1361
          && field.string_options().collation().compare("binary") == 0)
1372
 
        destination.append(" VARBINARY(");
 
1362
        destination.append(" VARBINARY(", 11);
1373
1363
      else
1374
 
        destination.append(" VARCHAR(");
 
1364
        destination.append(" VARCHAR(", 9);
1375
1365
 
1376
1366
      destination.append(boost::lexical_cast<string>(field.string_options().length()));
1377
1367
      destination.append(")");
1381
1371
    {
1382
1372
      if (field.string_options().has_collation()
1383
1373
          && field.string_options().collation().compare("binary") == 0)
1384
 
        destination.append(" BLOB");
 
1374
        destination.append(" BLOB", 5);
1385
1375
      else
1386
 
        destination.append(" TEXT");
 
1376
        destination.append(" TEXT", 5);
1387
1377
    }
1388
1378
    break;
1389
1379
  case Table::Field::ENUM:
1390
1380
    {
1391
1381
      size_t num_field_values= field.enumeration_values().field_value_size();
1392
 
      destination.append(" ENUM(");
 
1382
      destination.append(" ENUM(", 6);
1393
1383
      for (size_t x= 0; x < num_field_values; ++x)
1394
1384
      {
1395
1385
        const string &type= field.enumeration_values().field_value(x);
1405
1395
      break;
1406
1396
    }
1407
1397
  case Table::Field::UUID:
1408
 
    destination.append(" UUID");
 
1398
    destination.append(" UUID", 5);
1409
1399
    break;
1410
1400
  case Table::Field::BOOLEAN:
1411
 
    destination.append(" BOOLEAN");
 
1401
    destination.append(" BOOLEAN", 8);
1412
1402
    break;
1413
1403
  case Table::Field::INTEGER:
1414
 
    destination.append(" INT");
 
1404
    destination.append(" INT", 4);
1415
1405
    break;
1416
1406
  case Table::Field::BIGINT:
1417
1407
    if (field.has_constraints() and
1418
1408
        field.constraints().is_unsigned())
1419
1409
    {
1420
 
      destination.append(" BIGINT UNSIGNED");
 
1410
      destination.append(" BIGINT UNSIGNED", sizeof(" BIGINT UNSIGNED") -1);
1421
1411
    }
1422
1412
    else
1423
1413
    {
1424
 
      destination.append(" BIGINT");
 
1414
      destination.append(" BIGINT", 7);
1425
1415
    }
1426
1416
    break;
1427
1417
  case Table::Field::DECIMAL:
1428
1418
    {
1429
 
      destination.append(" DECIMAL(");
 
1419
      destination.append(" DECIMAL(", 9);
1430
1420
      stringstream ss;
1431
1421
      ss << field.numeric_options().precision() << ",";
1432
1422
      ss << field.numeric_options().scale() << ")";
1434
1424
    }
1435
1425
    break;
1436
1426
  case Table::Field::DATE:
1437
 
    destination.append(" DATE");
 
1427
    destination.append(" DATE", 5);
1438
1428
    break;
1439
1429
 
1440
1430
  case Table::Field::EPOCH:
1444
1434
    }
1445
1435
    else
1446
1436
    {
1447
 
      destination.append(" TIMESTAMP");
 
1437
      destination.append(" TIMESTAMP",  10);
1448
1438
    }
1449
1439
    break;
1450
1440
 
1451
1441
  case Table::Field::DATETIME:
1452
 
    destination.append(" DATETIME");
 
1442
    destination.append(" DATETIME",  9);
1453
1443
    break;
1454
1444
  case Table::Field::TIME:
1455
 
    destination.append(" TIME");
 
1445
    destination.append(" TIME",  5);
1456
1446
    break;
1457
1447
  }
1458
1448
 
1462
1452
    if (field.string_options().has_collation()
1463
1453
        && field.string_options().collation().compare("binary"))
1464
1454
    {
1465
 
      destination.append(" COLLATE ");
 
1455
      destination.append(" COLLATE ", 9);
1466
1456
      destination.append(field.string_options().collation());
1467
1457
    }
1468
1458
  }
1469
1459
 
1470
1460
  if (field.has_constraints() and field.constraints().is_unique())
1471
1461
  {
1472
 
    destination.append(" UNIQUE");
 
1462
    destination.append(" UNIQUE", sizeof(" UNIQUE") -1);
1473
1463
  }
1474
1464
 
1475
1465
  if (field.has_constraints() && field.constraints().is_notnull())
1476
1466
  {
1477
 
    destination.append(" NOT NULL");
 
1467
    destination.append(" NOT NULL", 9);
1478
1468
  }
1479
1469
  else if (field.type() == Table::Field::EPOCH)
1480
1470
  {
1481
 
    destination.append(" NULL");
 
1471
    destination.append(" NULL", 5);
1482
1472
  }
1483
1473
 
1484
1474
  if (field.type() == Table::Field::INTEGER || 
1488
1478
    if (field.has_numeric_options() &&
1489
1479
        field.numeric_options().is_autoincrement())
1490
1480
    {
1491
 
      destination.append(" AUTO_INCREMENT");
 
1481
      destination.append(" AUTO_INCREMENT", 15);
1492
1482
    }
1493
1483
  }
1494
1484
 
1495
1485
  if (field.options().has_default_value())
1496
1486
  {
1497
 
    destination.append(" DEFAULT ");
 
1487
    destination.append(" DEFAULT ", 9);
1498
1488
    append_escaped_string(&destination, field.options().default_value());
1499
1489
  }
1500
1490
  else if (field.options().has_default_expression())
1501
1491
  {
1502
 
    destination.append(" DEFAULT ");
 
1492
    destination.append(" DEFAULT ", 9);
1503
1493
    destination.append(field.options().default_expression());
1504
1494
  }
1505
1495
  else if (field.options().has_default_bin_value())
1507
1497
    const string &v= field.options().default_bin_value();
1508
1498
    if (v.length() == 0)
1509
1499
    {
1510
 
      destination.append(" DEFAULT ''");
 
1500
      destination.append(" DEFAULT ''", 11);
1511
1501
    }
1512
1502
    else
1513
1503
    {
1514
 
      destination.append(" DEFAULT 0x");
 
1504
      destination.append(" DEFAULT 0x", 11);
1515
1505
      for (size_t x= 0; x < v.length(); x++)
1516
1506
      {
1517
1507
        char hex[3];
1524
1514
           && field.options().default_null()
1525
1515
           && field.type() != Table::Field::BLOB)
1526
1516
  {
1527
 
    destination.append(" DEFAULT NULL");
 
1517
    destination.append(" DEFAULT NULL", 13);
1528
1518
  }
1529
1519
 
1530
1520
  if (field.has_options() && field.options().has_update_expression())
1531
1521
  {
1532
 
    destination.append(" ON UPDATE ");
 
1522
    destination.append(" ON UPDATE ", 11);
1533
1523
    destination.append(field.options().update_expression());
1534
1524
  }
1535
1525
 
1536
1526
  if (field.has_comment())
1537
1527
  {
1538
 
    destination.append(" COMMENT ");
 
1528
    destination.append(" COMMENT ", 9);
1539
1529
    append_escaped_string(&destination, field.comment(), quoted_default);
1540
1530
  }
1541
1531
  return NONE;