~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/message/statement_transform.cc

  • Committer: Lee Bieber
  • Date: 2010-08-21 22:42:44 UTC
  • mto: (1727.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1728.
  • Revision ID: lbieber@kalebral-2.local-20100821224244-kh3gmsvi45dlbuu1
For the feature request (https://blueprints.launchpad.net/drizzle/+spec/limit-maximum-sort-size) 
that is requesting the ability to cap various buffers, we first tried setting the join buffer to 
1 to see how that would affect the test results and expose test results that need to 
sorted (by adding --sorted_result). 

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
 
32
32
#include "config.h"
33
33
 
34
 
#include <boost/lexical_cast.hpp>
35
34
#include "drizzled/message/statement_transform.h"
36
35
#include "drizzled/message/transaction.pb.h"
37
36
#include "drizzled/message/table.pb.h"
52
51
namespace message
53
52
{
54
53
 
55
 
static void escapeEmbeddedQuotes(string &s, const char quote='\'')
56
 
{
57
 
  string::iterator it;
58
 
 
59
 
  for (it= s.begin(); it != s.end(); ++it)
60
 
  {
61
 
    if (*it == quote)
62
 
    {
63
 
      it= s.insert(it, quote);
64
 
      ++it;  // advance back to the quote
65
 
    }
66
 
  }
67
 
}
68
 
 
69
54
/* Incredibly similar to append_unescaped() in table.cc, but for std::string */
70
55
static void append_escaped_string(std::string *res, const std::string &input, const char quote='\'')
71
56
{
127
112
 
128
113
  switch (source.type())
129
114
  {
130
 
  case Statement::ROLLBACK_STATEMENT:
131
 
    {
132
 
      break;
133
 
    }
134
 
  case Statement::ROLLBACK:
135
 
    {
136
 
      sql_strings.push_back("ROLLBACK");
137
 
      break;
138
 
    }
139
115
  case Statement::INSERT:
140
116
    {
141
117
      if (! source.has_insert_header())
413
389
    if (should_quote_field_value)
414
390
      destination.push_back('\'');
415
391
 
416
 
    if (record.is_null(x))
 
392
    if (field_metadata.type() == Table::Field::BLOB)
417
393
    {
418
 
      destination.append("NULL");
 
394
      /* 
 
395
        * We do this here because BLOB data is returned
 
396
        * in a string correctly, but calling append()
 
397
        * without a length will result in only the string
 
398
        * up to a \0 being output here.
 
399
        */
 
400
      string raw_data(record.insert_value(x));
 
401
      destination.append(raw_data.c_str(), raw_data.size());
419
402
    }
420
403
    else
421
404
    {
422
 
      if (field_metadata.type() == Table::Field::BLOB)
423
 
      {
424
 
        /*
425
 
         * We do this here because BLOB data is returned
426
 
         * in a string correctly, but calling append()
427
 
         * without a length will result in only the string
428
 
         * up to a \0 being output here.
429
 
         */
430
 
        string raw_data(record.insert_value(x));
431
 
        destination.append(raw_data.c_str(), raw_data.size());
432
 
      }
433
 
      else
434
 
      {
435
 
        string tmp(record.insert_value(x));
436
 
        escapeEmbeddedQuotes(tmp);
437
 
        destination.append(tmp);
438
 
      }
 
405
      if (record.is_null(x))
 
406
      {
 
407
        destination.append("NULL");
 
408
      }
 
409
      else 
 
410
      {
 
411
        destination.append(record.insert_value(x));
 
412
      } 
439
413
    }
440
414
 
441
415
    if (should_quote_field_value)
498
472
      }
499
473
      else
500
474
      {
501
 
        string tmp(data.record(x).insert_value(y));
502
 
        escapeEmbeddedQuotes(tmp);
503
 
        destination.append(tmp);
 
475
        destination.append(data.record(x).insert_value(y));
504
476
      }
505
477
 
506
478
      if (should_quote_field_value)
576
548
    if (should_quote_field_value)
577
549
      destination.push_back('\'');
578
550
 
579
 
    if (record.is_null(x))
 
551
    if (field_metadata.type() == Table::Field::BLOB)
580
552
    {
581
 
      destination.append("NULL");
 
553
      /* 
 
554
       * We do this here because BLOB data is returned
 
555
       * in a string correctly, but calling append()
 
556
       * without a length will result in only the string
 
557
       * up to a \0 being output here.
 
558
       */
 
559
      string raw_data(record.after_value(x));
 
560
      destination.append(raw_data.c_str(), raw_data.size());
582
561
    }
583
 
    else 
 
562
    else
584
563
    {
585
 
      if (field_metadata.type() == Table::Field::BLOB)
 
564
      if (record.is_null(x))
586
565
      {
587
 
        /*
588
 
         * We do this here because BLOB data is returned
589
 
         * in a string correctly, but calling append()
590
 
         * without a length will result in only the string
591
 
         * up to a \0 being output here.
592
 
         */
593
 
        string raw_data(record.after_value(x));
594
 
        destination.append(raw_data.c_str(), raw_data.size());
 
566
        destination.append("NULL");
595
567
      }
596
 
      else 
 
568
      else
597
569
      {
598
 
        string tmp(record.after_value(x));
599
 
        escapeEmbeddedQuotes(tmp);
600
 
        destination.append(tmp);
 
570
        destination.append(record.after_value(x));
601
571
      }
602
572
    }
603
573
 
720
690
    }
721
691
    else
722
692
    {
723
 
      string tmp(record.key_value(x));
724
 
      escapeEmbeddedQuotes(tmp);
725
 
      destination.append(tmp);
 
693
      destination.append(record.key_value(x));
726
694
    }
727
695
 
728
696
    if (should_quote_field_value)
791
759
      }
792
760
      else
793
761
      {
794
 
        string tmp(data.record(x).key_value(y));
795
 
        escapeEmbeddedQuotes(tmp);
796
 
        destination.append(tmp);
 
762
        destination.append(data.record(x).key_value(y));
797
763
      }
798
764
 
799
765
      if (should_quote_field_value)
950
916
  destination.append("TABLE ", 6);
951
917
  if (with_schema)
952
918
  {
953
 
    append_escaped_string(&destination, table.schema(), quoted_identifier);
 
919
    destination.push_back(quoted_identifier);
 
920
    destination.append(table.schema());
 
921
    destination.push_back(quoted_identifier);
954
922
    destination.push_back('.');
955
923
  }
956
 
  append_escaped_string(&destination, table.name(), quoted_identifier);
 
924
  destination.push_back(quoted_identifier);
 
925
  destination.append(table.name());
 
926
  destination.push_back(quoted_identifier);
957
927
  destination.append(" (\n", 3);
958
928
 
959
929
  enum TransformSqlError result= NONE;
965
935
    if (x != 0)
966
936
      destination.append(",\n", 2);
967
937
 
968
 
    destination.append("  ");
969
 
 
970
938
    result= transformFieldDefinitionToSql(field, destination, sql_variant);
971
 
 
 
939
    
972
940
    if (result != NONE)
973
941
      return result;
974
942
  }
1014
982
  /* Add ENGINE = " clause */
1015
983
  if (table.has_engine())
1016
984
  {
1017
 
    destination.append(" ENGINE=", 8);
 
985
    destination.append("\nENGINE = ", 10);
1018
986
    destination.append(table.engine().name());
1019
987
 
1020
988
    size_t num_engine_options= table.engine().options_size();
1021
 
    if (num_engine_options > 0)
1022
 
      destination.append(" ", 1);
1023
989
    for (size_t x= 0; x < num_engine_options; ++x)
1024
990
    {
1025
991
      const Engine::Option &option= table.engine().options(x);
 
992
      destination.push_back('\n');
1026
993
      destination.append(option.name());
1027
 
      destination.append("='", 2);
 
994
      destination.append(" = ", 3);
1028
995
      destination.append(option.state());
1029
 
      destination.append("'", 1);
1030
 
      if(x != num_engine_options-1)
1031
 
        destination.append(", ", 2);
 
996
      destination.push_back('\n');
1032
997
    }
1033
998
  }
1034
999
 
1046
1011
  if (sql_variant == ANSI)
1047
1012
    return NONE; /* ANSI does not support table options... */
1048
1013
 
 
1014
  stringstream ss;
 
1015
 
1049
1016
  if (options.has_comment())
1050
1017
  {
1051
 
    destination.append(" COMMENT=", 9);
1052
 
    append_escaped_string(&destination, options.comment());
 
1018
    destination.append("\nCOMMENT = '", 12);
 
1019
    destination.append(options.comment());
 
1020
    destination.push_back('\'');
1053
1021
  }
1054
1022
 
1055
1023
  if (options.has_collation())
1056
1024
  {
1057
 
    destination.append(" COLLATE = ", 11);
 
1025
    destination.append("\nCOLLATE = ", 11);
1058
1026
    destination.append(options.collation());
1059
1027
  }
1060
1028
 
 
1029
  if (options.has_auto_increment())
 
1030
  {
 
1031
    ss << options.auto_increment();
 
1032
    destination.append("\nAUTOINCREMENT_OFFSET = ", 24);
 
1033
    destination.append(ss.str());
 
1034
    ss.clear();
 
1035
  }
 
1036
 
1061
1037
  if (options.has_data_file_name())
1062
1038
  {
1063
1039
    destination.append("\nDATA_FILE_NAME = '", 19);
1074
1050
 
1075
1051
  if (options.has_max_rows())
1076
1052
  {
 
1053
    ss << options.max_rows();
1077
1054
    destination.append("\nMAX_ROWS = ", 12);
1078
 
    destination.append(boost::lexical_cast<string>(options.max_rows()));
 
1055
    destination.append(ss.str());
 
1056
    ss.clear();
1079
1057
  }
1080
1058
 
1081
1059
  if (options.has_min_rows())
1082
1060
  {
 
1061
    ss << options.min_rows();
1083
1062
    destination.append("\nMIN_ROWS = ", 12);
1084
 
    destination.append(boost::lexical_cast<string>(options.min_rows()));
 
1063
    destination.append(ss.str());
 
1064
    ss.clear();
1085
1065
  }
1086
1066
 
1087
 
  if (options.has_user_set_auto_increment_value()
1088
 
      && options.has_auto_increment_value())
 
1067
  if (options.has_auto_increment_value())
1089
1068
  {
1090
 
    destination.append(" AUTO_INCREMENT=", 16);
1091
 
    destination.append(boost::lexical_cast<string>(options.auto_increment_value()));
 
1069
    ss << options.auto_increment_value();
 
1070
    destination.append("\nAUTO_INCREMENT = ", 18);
 
1071
    destination.append(ss.str());
 
1072
    ss.clear();
1092
1073
  }
1093
1074
 
1094
1075
  if (options.has_avg_row_length())
1095
1076
  {
 
1077
    ss << options.avg_row_length();
1096
1078
    destination.append("\nAVG_ROW_LENGTH = ", 18);
1097
 
    destination.append(boost::lexical_cast<string>(options.avg_row_length()));
 
1079
    destination.append(ss.str());
 
1080
    ss.clear();
1098
1081
  }
1099
1082
 
1100
1083
  if (options.has_checksum() &&
1117
1100
  if (sql_variant == ANSI)
1118
1101
    quoted_identifier= '"';
1119
1102
 
1120
 
  destination.append("  ", 2);
1121
 
 
1122
1103
  if (index.is_primary())
1123
1104
    destination.append("PRIMARY ", 8);
1124
1105
  else if (index.is_unique())
1125
1106
    destination.append("UNIQUE ", 7);
1126
1107
 
1127
1108
  destination.append("KEY ", 4);
1128
 
  if (! (index.is_primary() && index.name().compare("PRIMARY")==0))
1129
 
  {
1130
 
    destination.push_back(quoted_identifier);
1131
 
    destination.append(index.name());
1132
 
    destination.push_back(quoted_identifier);
1133
 
    destination.append(" (", 2);
1134
 
  }
1135
 
  else
1136
 
    destination.append("(", 1);
1137
 
 
 
1109
  destination.push_back(quoted_identifier);
 
1110
  destination.append(index.name());
 
1111
  destination.push_back(quoted_identifier);
 
1112
  destination.append(" (", 2);
 
1113
  
1138
1114
  size_t num_parts= index.index_part_size();
1139
1115
  for (size_t x= 0; x < num_parts; ++x)
1140
1116
  {
1160
1136
      {
1161
1137
        if (part.compare_length() != field.string_options().length())
1162
1138
        {
 
1139
          stringstream ss;
1163
1140
          destination.push_back('(');
1164
 
          destination.append(boost::lexical_cast<string>(part.compare_length()));
 
1141
          ss << part.compare_length();
 
1142
          destination.append(ss.str());
1165
1143
          destination.push_back(')');
1166
1144
        }
1167
1145
      }
1169
1147
  }
1170
1148
  destination.push_back(')');
1171
1149
 
1172
 
  switch (index.type())
1173
 
  {
1174
 
  case Table::Index::UNKNOWN_INDEX:
1175
 
    break;
1176
 
  case Table::Index::BTREE:
1177
 
    destination.append(" USING BTREE", 12);
1178
 
    break;
1179
 
  case Table::Index::RTREE:
1180
 
    destination.append(" USING RTREE", 12);
1181
 
    break;
1182
 
  case Table::Index::HASH:
1183
 
    destination.append(" USING HASH", 11);
1184
 
    break;
1185
 
  case Table::Index::FULLTEXT:
1186
 
    destination.append(" USING FULLTEXT", 15);
1187
 
    break;
1188
 
  }
1189
 
 
1190
 
  if (index.has_comment())
1191
 
  {
1192
 
    destination.append(" COMMENT ", 9);
1193
 
    append_escaped_string(&destination, index.comment());
1194
 
  }
1195
 
 
1196
1150
  return NONE;
1197
1151
}
1198
1152
 
1200
1154
{
1201
1155
  switch (opt)
1202
1156
  {
 
1157
  case Table::ForeignKeyConstraint::OPTION_UNDEF:
 
1158
    break;
1203
1159
  case Table::ForeignKeyConstraint::OPTION_RESTRICT:
1204
1160
    destination.append("RESTRICT");
1205
1161
    break;
1209
1165
  case Table::ForeignKeyConstraint::OPTION_SET_NULL:
1210
1166
    destination.append("SET NULL");
1211
1167
    break;
1212
 
  case Table::ForeignKeyConstraint::OPTION_UNDEF:
1213
1168
  case Table::ForeignKeyConstraint::OPTION_NO_ACTION:
1214
1169
    destination.append("NO ACTION");
1215
1170
    break;
1216
 
  case Table::ForeignKeyConstraint::OPTION_SET_DEFAULT:
 
1171
  case Table::ForeignKeyConstraint::OPTION_DEFAULT:
1217
1172
    destination.append("SET DEFAULT");
1218
1173
    break;
1219
1174
  }
1243
1198
  for (ssize_t x= 0; x < fkey.column_names_size(); ++x)
1244
1199
  {
1245
1200
    if (x != 0)
1246
 
      destination.append(", ");
 
1201
      destination.push_back(',');
1247
1202
 
1248
1203
    append_escaped_string(&destination, fkey.column_names(x),
1249
1204
                          quoted_identifier);
1258
1213
  for (ssize_t x= 0; x < fkey.references_columns_size(); ++x)
1259
1214
  {
1260
1215
    if (x != 0)
1261
 
      destination.append(", ");
 
1216
      destination.push_back(',');
1262
1217
 
1263
1218
    append_escaped_string(&destination, fkey.references_columns(x),
1264
1219
                          quoted_identifier);
1266
1221
 
1267
1222
  destination.push_back(')');
1268
1223
 
1269
 
  if (fkey.has_update_option() and fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
 
1224
  if (fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1270
1225
  {
1271
1226
    destination.append(" ON UPDATE ", 11);
1272
1227
    transformForeignKeyOptionToSql(fkey.update_option(), destination);
1273
1228
  }
1274
1229
 
1275
 
  if (fkey.has_delete_option() and fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
 
1230
  if (fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1276
1231
  {
1277
1232
    destination.append(" ON DELETE ", 11);
1278
1233
    transformForeignKeyOptionToSql(fkey.delete_option(), destination);
1287
1242
                              enum TransformSqlVariant sql_variant)
1288
1243
{
1289
1244
  char quoted_identifier= '`';
1290
 
  char quoted_default;
1291
 
 
1292
1245
  if (sql_variant == ANSI)
1293
1246
    quoted_identifier= '"';
1294
1247
 
1295
 
  if (sql_variant == DRIZZLE)
1296
 
    quoted_default= '\'';
1297
 
  else
1298
 
    quoted_default= quoted_identifier;
1299
 
 
1300
 
  append_escaped_string(&destination, field.name(), quoted_identifier);
 
1248
  destination.push_back(quoted_identifier);
 
1249
  destination.append(field.name());
 
1250
  destination.push_back(quoted_identifier);
1301
1251
 
1302
1252
  Table::Field::FieldType field_type= field.type();
1303
1253
 
1305
1255
  {
1306
1256
    case Table::Field::DOUBLE:
1307
1257
    destination.append(" DOUBLE", 7);
1308
 
    if (field.has_numeric_options()
1309
 
        && field.numeric_options().has_precision())
1310
 
    {
1311
 
      stringstream ss;
1312
 
      ss << "(" << field.numeric_options().precision() << ",";
1313
 
      ss << field.numeric_options().scale() << ")";
1314
 
      destination.append(ss.str());
1315
 
    }
1316
1258
    break;
1317
1259
  case Table::Field::VARCHAR:
1318
1260
    {
1319
 
      if (field.string_options().has_collation()
1320
 
          && field.string_options().collation().compare("binary") == 0)
1321
 
        destination.append(" VARBINARY(", 11);
1322
 
      else
1323
 
        destination.append(" VARCHAR(", 9);
1324
 
 
1325
 
      destination.append(boost::lexical_cast<string>(field.string_options().length()));
1326
 
      destination.append(")");
 
1261
      destination.append(" VARCHAR(", 9);
 
1262
      stringstream ss;
 
1263
      ss << field.string_options().length() << ")";
 
1264
      destination.append(ss.str());
1327
1265
    }
1328
1266
    break;
1329
1267
  case Table::Field::BLOB:
1330
 
    {
1331
 
      if (field.string_options().has_collation()
1332
 
          && field.string_options().collation().compare("binary") == 0)
1333
 
        destination.append(" BLOB", 5);
1334
 
      else
1335
 
        destination.append(" TEXT", 5);
1336
 
    }
 
1268
    destination.append(" BLOB", 5);
1337
1269
    break;
1338
1270
  case Table::Field::ENUM:
1339
1271
    {
1353
1285
      destination.push_back(')');
1354
1286
      break;
1355
1287
    }
1356
 
  case Table::Field::UUID:
1357
 
    destination.append(" UUID", 5);
1358
 
    break;
1359
1288
  case Table::Field::INTEGER:
1360
1289
    destination.append(" INT", 4);
1361
1290
    break;
1393
1322
    }
1394
1323
  }
1395
1324
 
 
1325
 
 
1326
  if (! (field.has_constraints() &&
 
1327
         field.constraints().is_nullable()))
 
1328
  {
 
1329
    destination.append(" NOT", 4);
 
1330
  }
 
1331
  destination.append(" NULL", 5);
 
1332
 
 
1333
  if (field.type() == Table::Field::INTEGER || 
 
1334
      field.type() == Table::Field::BIGINT)
 
1335
  {
 
1336
    /* AUTO_INCREMENT must be after NOT NULL */
 
1337
    if (field.has_numeric_options() &&
 
1338
        field.numeric_options().is_autoincrement())
 
1339
    {
 
1340
      destination.append(" AUTO_INCREMENT", 15);
 
1341
    }
 
1342
  }
 
1343
 
1396
1344
  if (field.type() == Table::Field::BLOB ||
1397
1345
      field.type() == Table::Field::VARCHAR)
1398
1346
  {
1399
 
    if (field.string_options().has_collation()
1400
 
        && field.string_options().collation().compare("binary"))
 
1347
    if (field.string_options().has_collation())
1401
1348
    {
1402
1349
      destination.append(" COLLATE ", 9);
1403
1350
      destination.append(field.string_options().collation());
1404
1351
    }
1405
1352
  }
1406
1353
 
1407
 
  if (field.has_constraints() &&
1408
 
      ! field.constraints().is_nullable())
1409
 
  {
1410
 
    destination.append(" NOT NULL", 9);
1411
 
  }
1412
 
  else if (field.type() == Table::Field::TIMESTAMP)
1413
 
    destination.append(" NULL", 5);
1414
 
 
1415
 
  if (field.type() == Table::Field::INTEGER || 
1416
 
      field.type() == Table::Field::BIGINT)
1417
 
  {
1418
 
    /* AUTO_INCREMENT must be after NOT NULL */
1419
 
    if (field.has_numeric_options() &&
1420
 
        field.numeric_options().is_autoincrement())
1421
 
    {
1422
 
      destination.append(" AUTO_INCREMENT", 15);
1423
 
    }
1424
 
  }
1425
 
 
1426
1354
  if (field.options().has_default_value())
1427
1355
  {
1428
1356
    destination.append(" DEFAULT ", 9);
1429
 
    append_escaped_string(&destination, field.options().default_value());
1430
 
  }
1431
 
  else if (field.options().has_default_expression())
1432
 
  {
1433
 
    destination.append(" DEFAULT ", 9);
1434
 
    destination.append(field.options().default_expression());
1435
 
  }
1436
 
  else if (field.options().has_default_bin_value())
 
1357
    destination.push_back(quoted_identifier);
 
1358
    destination.append(field.options().default_value());
 
1359
    destination.push_back(quoted_identifier);
 
1360
  }
 
1361
 
 
1362
  if (field.options().has_default_bin_value())
1437
1363
  {
1438
1364
    const string &v= field.options().default_bin_value();
1439
 
    if (v.length() == 0)
1440
 
      destination.append(" DEFAULT ''", 11);
1441
 
    else
 
1365
    destination.append(" DEFAULT 0x", 11);
 
1366
    for (size_t x= 0; x < v.length(); x++)
1442
1367
    {
1443
 
      destination.append(" DEFAULT 0x", 11);
1444
 
      for (size_t x= 0; x < v.length(); x++)
1445
 
      {
1446
 
        char hex[3];
1447
 
        snprintf(hex, sizeof(hex), "%.2X", *(v.c_str() + x));
1448
 
        destination.append(hex, 2);
1449
 
      }
 
1368
      printf("%.2x", *(v.c_str() + x));
1450
1369
    }
1451
1370
  }
1452
 
  else if (field.options().has_default_null()
1453
 
           && field.options().default_null()
1454
 
           && field.type() != Table::Field::BLOB)
1455
 
  {
1456
 
    destination.append(" DEFAULT NULL", 13);
1457
 
  }
1458
1371
 
1459
 
  if (field.has_options() && field.options().has_update_expression())
 
1372
  if (field.has_options() && field.options().has_update_value())
1460
1373
  {
1461
1374
    destination.append(" ON UPDATE ", 11);
1462
 
    destination.append(field.options().update_expression());
 
1375
    destination.append(field.options().update_value());
1463
1376
  }
1464
1377
 
1465
1378
  if (field.has_comment())
1466
1379
  {
1467
1380
    destination.append(" COMMENT ", 9);
1468
 
    append_escaped_string(&destination, field.comment(), quoted_default);
 
1381
    destination.push_back(quoted_identifier);
 
1382
    destination.append(field.comment());
 
1383
    destination.push_back(quoted_identifier);
1469
1384
  }
1470
1385
  return NONE;
1471
1386
}
1478
1393
  case Table::Field::DECIMAL:
1479
1394
  case Table::Field::INTEGER:
1480
1395
  case Table::Field::BIGINT:
 
1396
  case Table::Field::ENUM:
1481
1397
    return false;
1482
1398
  default:
1483
1399
    return true;
1510
1426
    return Table::Field::ENUM;
1511
1427
  case DRIZZLE_TYPE_BLOB:
1512
1428
    return Table::Field::BLOB;
1513
 
  case DRIZZLE_TYPE_UUID:
1514
 
    return Table::Field::UUID;
1515
1429
  }
1516
1430
 
1517
1431
  assert(false);