~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-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2009 Sun Microsystems
5
 
 *  Copyright (c) 2010 Jay Pipes
 
4
 *  Copyright (C) 2009 Sun Microsystems, Inc.
 
5
 *  Copyright (C) 2010 Jay Pipes
6
6
 *
7
7
 *  Authors:
8
8
 *
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>
127
127
 
128
128
  switch (source.type())
129
129
  {
 
130
  case Statement::ROLLBACK_STATEMENT:
 
131
    {
 
132
      break;
 
133
    }
130
134
  case Statement::ROLLBACK:
131
135
    {
132
136
      sql_strings.push_back("ROLLBACK");
148
152
      const InsertHeader &insert_header= source.insert_header();
149
153
      const InsertData &insert_data= source.insert_data();
150
154
      size_t num_keys= insert_data.record_size();
151
 
      size_t x;
152
155
 
153
156
      if (num_keys > 1 && ! already_in_transaction)
154
157
        sql_strings.push_back("START TRANSACTION");
155
158
 
156
 
      for (x= 0; x < num_keys; ++x)
 
159
      for (size_t x= 0; x < num_keys; ++x)
157
160
      {
158
161
        string destination;
159
162
 
314
317
      sql_strings.push_back(destination);
315
318
    }
316
319
    break;
 
320
  case Statement::ALTER_SCHEMA:
 
321
    {
 
322
      assert(source.has_alter_schema_statement());
 
323
      string destination;
 
324
      error= transformAlterSchemaStatementToSql(source.alter_schema_statement(),
 
325
                                                destination,
 
326
                                                sql_variant);
 
327
      sql_strings.push_back(destination);
 
328
    }
 
329
    break;
317
330
  case Statement::SET_VARIABLE:
318
331
    {
319
332
      assert(source.has_set_variable_statement());
802
815
}
803
816
 
804
817
enum TransformSqlError
 
818
transformAlterSchemaStatementToSql(const AlterSchemaStatement &statement,
 
819
                                   string &destination,
 
820
                                   enum TransformSqlVariant sql_variant)
 
821
{
 
822
  const Schema &before= statement.before();
 
823
  const Schema &after= statement.after();
 
824
 
 
825
  /* Make sure we are given the before and after for the same object */
 
826
  if (before.uuid() != after.uuid())
 
827
    return UUID_MISMATCH;
 
828
 
 
829
  char quoted_identifier= '`';
 
830
  if (sql_variant == ANSI)
 
831
    quoted_identifier= '"';
 
832
 
 
833
  destination.append("ALTER SCHEMA ");
 
834
  destination.push_back(quoted_identifier);
 
835
  destination.append(before.name());
 
836
  destination.push_back(quoted_identifier);
 
837
 
 
838
  /*
 
839
   * Diff our schemas. Currently, only collation can change so a
 
840
   * diff of the two structures is not really necessary.
 
841
   */
 
842
  destination.append(" COLLATE = ");
 
843
  destination.append(after.collation());
 
844
 
 
845
  return NONE;
 
846
}
 
847
 
 
848
enum TransformSqlError
805
849
transformDropSchemaStatementToSql(const DropSchemaStatement &statement,
806
850
                                  string &destination,
807
851
                                  enum TransformSqlVariant sql_variant)
829
873
 
830
874
  const Schema &schema= statement.schema();
831
875
 
832
 
  destination.append("CREATE SCHEMA ", 14);
 
876
  destination.append("CREATE SCHEMA ");
833
877
  destination.push_back(quoted_identifier);
834
878
  destination.append(schema.name());
835
879
  destination.push_back(quoted_identifier);
836
880
 
837
881
  if (schema.has_collation())
838
882
  {
839
 
    destination.append(" COLLATE ", 9);
 
883
    destination.append(" COLLATE ");
840
884
    destination.append(schema.collation());
841
885
  }
842
886
 
 
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
 
843
892
  return NONE;
844
893
}
845
894
 
854
903
 
855
904
  const TableMetadata &table_metadata= statement.table_metadata();
856
905
 
857
 
  destination.append("DROP TABLE ", 11);
 
906
  destination.append("DROP TABLE ");
858
907
 
859
908
  /* Add the IF EXISTS clause if necessary */
860
909
  if (statement.has_if_exists_clause() &&
861
910
      statement.if_exists_clause() == true)
862
911
  {
863
 
    destination.append("IF EXISTS ", 10);
 
912
    destination.append("IF EXISTS ");
864
913
  }
865
914
 
866
915
  destination.push_back(quoted_identifier);
885
934
 
886
935
  const TableMetadata &table_metadata= statement.table_metadata();
887
936
 
888
 
  destination.append("TRUNCATE TABLE ", 15);
 
937
  destination.append("TRUNCATE TABLE ");
889
938
  destination.push_back(quoted_identifier);
890
939
  destination.append(table_metadata.schema_name());
891
940
  destination.push_back(quoted_identifier);
906
955
  const FieldMetadata &variable_metadata= statement.variable_metadata();
907
956
  bool should_quote_field_value= shouldQuoteFieldValue(variable_metadata.type());
908
957
 
909
 
  destination.append("SET GLOBAL ", 11); /* Only global variables are replicated */
 
958
  destination.append("SET GLOBAL "); /* Only global variables are replicated */
910
959
  destination.append(variable_metadata.name());
911
960
  destination.push_back('=');
912
961
 
938
987
  if (sql_variant == ANSI)
939
988
    quoted_identifier= '"';
940
989
 
941
 
  destination.append("CREATE ", 7);
 
990
  destination.append("CREATE ");
942
991
 
943
992
  if (table.type() == Table::TEMPORARY)
944
 
    destination.append("TEMPORARY ", 10);
 
993
    destination.append("TEMPORARY ");
945
994
  
946
 
  destination.append("TABLE ", 6);
 
995
  destination.append("TABLE ");
947
996
  if (with_schema)
948
997
  {
949
998
    append_escaped_string(&destination, table.schema(), quoted_identifier);
950
999
    destination.push_back('.');
951
1000
  }
952
1001
  append_escaped_string(&destination, table.name(), quoted_identifier);
953
 
  destination.append(" (\n", 3);
 
1002
  destination.append(" (\n");
954
1003
 
955
1004
  enum TransformSqlError result= NONE;
956
1005
  size_t num_fields= table.field_size();
959
1008
    const Table::Field &field= table.field(x);
960
1009
 
961
1010
    if (x != 0)
962
 
      destination.append(",\n", 2);
 
1011
      destination.append(",\n");
963
1012
 
964
1013
    destination.append("  ");
965
1014
 
972
1021
  size_t num_indexes= table.indexes_size();
973
1022
  
974
1023
  if (num_indexes > 0)
975
 
    destination.append(",\n", 2);
 
1024
    destination.append(",\n");
976
1025
 
977
1026
  for (size_t x= 0; x < num_indexes; ++x)
978
1027
  {
979
1028
    const message::Table::Index &index= table.indexes(x);
980
1029
 
981
1030
    if (x != 0)
982
 
      destination.append(",\n", 2);
 
1031
      destination.append(",\n");
983
1032
 
984
1033
    result= transformIndexDefinitionToSql(index, table, destination, sql_variant);
985
1034
    
990
1039
  size_t num_foreign_keys= table.fk_constraint_size();
991
1040
 
992
1041
  if (num_foreign_keys > 0)
993
 
    destination.append(",\n", 2);
 
1042
    destination.append(",\n");
994
1043
 
995
1044
  for (size_t x= 0; x < num_foreign_keys; ++x)
996
1045
  {
997
1046
    const message::Table::ForeignKeyConstraint &fkey= table.fk_constraint(x);
998
1047
 
999
1048
    if (x != 0)
1000
 
      destination.append(",\n", 2);
 
1049
      destination.append(",\n");
1001
1050
 
1002
1051
    result= transformForeignKeyConstraintDefinitionToSql(fkey, table, destination, sql_variant);
1003
1052
 
1005
1054
      return result;
1006
1055
  }
1007
1056
 
1008
 
  destination.append("\n)", 2);
 
1057
  destination.append("\n)");
1009
1058
 
1010
1059
  /* Add ENGINE = " clause */
1011
1060
  if (table.has_engine())
1012
1061
  {
1013
 
    destination.append(" ENGINE=", 8);
 
1062
    destination.append(" ENGINE=");
1014
1063
    destination.append(table.engine().name());
1015
1064
 
1016
1065
    size_t num_engine_options= table.engine().options_size();
1020
1069
    {
1021
1070
      const Engine::Option &option= table.engine().options(x);
1022
1071
      destination.append(option.name());
1023
 
      destination.append("='", 2);
 
1072
      destination.append("='");
1024
1073
      destination.append(option.state());
1025
 
      destination.append("'", 1);
1026
 
      if(x != num_engine_options-1)
1027
 
        destination.append(", ", 2);
 
1074
      destination.append("'");
 
1075
      if (x != num_engine_options-1)
 
1076
      {
 
1077
        destination.append(", ");
 
1078
      }
1028
1079
    }
1029
1080
  }
1030
1081
 
1044
1095
 
1045
1096
  if (options.has_comment())
1046
1097
  {
1047
 
    destination.append(" COMMENT=", 9);
 
1098
    destination.append(" COMMENT=");
1048
1099
    append_escaped_string(&destination, options.comment());
1049
1100
  }
1050
1101
 
1051
1102
  if (options.has_collation())
1052
1103
  {
1053
 
    destination.append(" COLLATE = ", 11);
 
1104
    destination.append(" COLLATE = ");
1054
1105
    destination.append(options.collation());
1055
1106
  }
1056
1107
 
1057
1108
  if (options.has_data_file_name())
1058
1109
  {
1059
 
    destination.append("\nDATA_FILE_NAME = '", 19);
 
1110
    destination.append("\nDATA_FILE_NAME = '");
1060
1111
    destination.append(options.data_file_name());
1061
1112
    destination.push_back('\'');
1062
1113
  }
1063
1114
 
1064
1115
  if (options.has_index_file_name())
1065
1116
  {
1066
 
    destination.append("\nINDEX_FILE_NAME = '", 20);
 
1117
    destination.append("\nINDEX_FILE_NAME = '");
1067
1118
    destination.append(options.index_file_name());
1068
1119
    destination.push_back('\'');
1069
1120
  }
1070
1121
 
1071
1122
  if (options.has_max_rows())
1072
1123
  {
1073
 
    destination.append("\nMAX_ROWS = ", 12);
 
1124
    destination.append("\nMAX_ROWS = ");
1074
1125
    destination.append(boost::lexical_cast<string>(options.max_rows()));
1075
1126
  }
1076
1127
 
1077
1128
  if (options.has_min_rows())
1078
1129
  {
1079
 
    destination.append("\nMIN_ROWS = ", 12);
 
1130
    destination.append("\nMIN_ROWS = ");
1080
1131
    destination.append(boost::lexical_cast<string>(options.min_rows()));
1081
1132
  }
1082
1133
 
1083
1134
  if (options.has_user_set_auto_increment_value()
1084
1135
      && options.has_auto_increment_value())
1085
1136
  {
1086
 
    destination.append(" AUTO_INCREMENT=", 16);
 
1137
    destination.append(" AUTO_INCREMENT=");
1087
1138
    destination.append(boost::lexical_cast<string>(options.auto_increment_value()));
1088
1139
  }
1089
1140
 
1090
1141
  if (options.has_avg_row_length())
1091
1142
  {
1092
 
    destination.append("\nAVG_ROW_LENGTH = ", 18);
 
1143
    destination.append("\nAVG_ROW_LENGTH = ");
1093
1144
    destination.append(boost::lexical_cast<string>(options.avg_row_length()));
1094
1145
  }
1095
1146
 
1096
 
  if (options.has_checksum() &&
1097
 
      options.checksum())
1098
 
    destination.append("\nCHECKSUM = TRUE", 16);
1099
 
  if (options.has_page_checksum() &&
1100
 
      options.page_checksum())
1101
 
    destination.append("\nPAGE_CHECKSUM = TRUE", 21);
 
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
  }
1102
1157
 
1103
1158
  return NONE;
1104
1159
}
1116
1171
  destination.append("  ", 2);
1117
1172
 
1118
1173
  if (index.is_primary())
1119
 
    destination.append("PRIMARY ", 8);
 
1174
    destination.append("PRIMARY ");
1120
1175
  else if (index.is_unique())
1121
 
    destination.append("UNIQUE ", 7);
 
1176
    destination.append("UNIQUE ");
1122
1177
 
1123
1178
  destination.append("KEY ", 4);
1124
1179
  if (! (index.is_primary() && index.name().compare("PRIMARY")==0))
1170
1225
  case Table::Index::UNKNOWN_INDEX:
1171
1226
    break;
1172
1227
  case Table::Index::BTREE:
1173
 
    destination.append(" USING BTREE", 12);
 
1228
    destination.append(" USING BTREE");
1174
1229
    break;
1175
1230
  case Table::Index::RTREE:
1176
 
    destination.append(" USING RTREE", 12);
 
1231
    destination.append(" USING RTREE");
1177
1232
    break;
1178
1233
  case Table::Index::HASH:
1179
 
    destination.append(" USING HASH", 11);
 
1234
    destination.append(" USING HASH");
1180
1235
    break;
1181
1236
  case Table::Index::FULLTEXT:
1182
 
    destination.append(" USING FULLTEXT", 15);
 
1237
    destination.append(" USING FULLTEXT");
1183
1238
    break;
1184
1239
  }
1185
1240
 
1186
1241
  if (index.has_comment())
1187
1242
  {
1188
 
    destination.append(" COMMENT ", 9);
 
1243
    destination.append(" COMMENT ");
1189
1244
    append_escaped_string(&destination, index.comment());
1190
1245
  }
1191
1246
 
1196
1251
{
1197
1252
  switch (opt)
1198
1253
  {
1199
 
  case Table::ForeignKeyConstraint::OPTION_UNDEF:
1200
 
    break;
1201
1254
  case Table::ForeignKeyConstraint::OPTION_RESTRICT:
1202
1255
    destination.append("RESTRICT");
1203
1256
    break;
1207
1260
  case Table::ForeignKeyConstraint::OPTION_SET_NULL:
1208
1261
    destination.append("SET NULL");
1209
1262
    break;
 
1263
  case Table::ForeignKeyConstraint::OPTION_UNDEF:
1210
1264
  case Table::ForeignKeyConstraint::OPTION_NO_ACTION:
1211
1265
    destination.append("NO ACTION");
1212
1266
    break;
1213
 
  case Table::ForeignKeyConstraint::OPTION_DEFAULT:
 
1267
  case Table::ForeignKeyConstraint::OPTION_SET_DEFAULT:
1214
1268
    destination.append("SET DEFAULT");
1215
1269
    break;
1216
1270
  }
1226
1280
  if (sql_variant == ANSI)
1227
1281
    quoted_identifier= '"';
1228
1282
 
1229
 
  destination.append("  ", 2);
 
1283
  destination.append("  ");
1230
1284
 
1231
1285
  if (fkey.has_name())
1232
1286
  {
1233
 
    destination.append("CONSTRAINT ", 11);
 
1287
    destination.append("CONSTRAINT ");
1234
1288
    append_escaped_string(&destination, fkey.name(), quoted_identifier);
1235
1289
    destination.append(" ", 1);
1236
1290
  }
1237
1291
 
1238
 
  destination.append("FOREIGN KEY (", 13);
 
1292
  destination.append("FOREIGN KEY (");
1239
1293
 
1240
1294
  for (ssize_t x= 0; x < fkey.column_names_size(); ++x)
1241
1295
  {
1246
1300
                          quoted_identifier);
1247
1301
  }
1248
1302
 
1249
 
  destination.append(") REFERENCES ", 13);
 
1303
  destination.append(") REFERENCES ");
1250
1304
 
1251
1305
  append_escaped_string(&destination, fkey.references_table_name(),
1252
1306
                        quoted_identifier);
1253
 
  destination.append(" (", 2);
 
1307
  destination.append(" (");
1254
1308
 
1255
1309
  for (ssize_t x= 0; x < fkey.references_columns_size(); ++x)
1256
1310
  {
1263
1317
 
1264
1318
  destination.push_back(')');
1265
1319
 
1266
 
  if (fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
 
1320
  if (fkey.has_update_option() and fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1267
1321
  {
1268
 
    destination.append(" ON UPDATE ", 11);
 
1322
    destination.append(" ON UPDATE ");
1269
1323
    transformForeignKeyOptionToSql(fkey.update_option(), destination);
1270
1324
  }
1271
1325
 
1272
 
  if (fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
 
1326
  if (fkey.has_delete_option() and fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1273
1327
  {
1274
 
    destination.append(" ON DELETE ", 11);
 
1328
    destination.append(" ON DELETE ");
1275
1329
    transformForeignKeyOptionToSql(fkey.delete_option(), destination);
1276
1330
  }
1277
1331
 
1301
1355
  switch (field_type)
1302
1356
  {
1303
1357
    case Table::Field::DOUBLE:
1304
 
    destination.append(" DOUBLE", 7);
 
1358
    destination.append(" DOUBLE");
1305
1359
    if (field.has_numeric_options()
1306
1360
        && field.numeric_options().has_precision())
1307
1361
    {
1315
1369
    {
1316
1370
      if (field.string_options().has_collation()
1317
1371
          && field.string_options().collation().compare("binary") == 0)
1318
 
        destination.append(" VARBINARY(", 11);
 
1372
        destination.append(" VARBINARY(");
1319
1373
      else
1320
 
        destination.append(" VARCHAR(", 9);
 
1374
        destination.append(" VARCHAR(");
1321
1375
 
1322
1376
      destination.append(boost::lexical_cast<string>(field.string_options().length()));
1323
1377
      destination.append(")");
1327
1381
    {
1328
1382
      if (field.string_options().has_collation()
1329
1383
          && field.string_options().collation().compare("binary") == 0)
1330
 
        destination.append(" BLOB", 5);
 
1384
        destination.append(" BLOB");
1331
1385
      else
1332
 
        destination.append(" TEXT", 5);
 
1386
        destination.append(" TEXT");
1333
1387
    }
1334
1388
    break;
1335
1389
  case Table::Field::ENUM:
1336
1390
    {
1337
1391
      size_t num_field_values= field.enumeration_values().field_value_size();
1338
 
      destination.append(" ENUM(", 6);
 
1392
      destination.append(" ENUM(");
1339
1393
      for (size_t x= 0; x < num_field_values; ++x)
1340
1394
      {
1341
1395
        const string &type= field.enumeration_values().field_value(x);
1350
1404
      destination.push_back(')');
1351
1405
      break;
1352
1406
    }
 
1407
  case Table::Field::UUID:
 
1408
    destination.append(" UUID");
 
1409
    break;
 
1410
  case Table::Field::BOOLEAN:
 
1411
    destination.append(" BOOLEAN");
 
1412
    break;
1353
1413
  case Table::Field::INTEGER:
1354
 
    destination.append(" INT", 4);
 
1414
    destination.append(" INT");
1355
1415
    break;
1356
1416
  case Table::Field::BIGINT:
1357
 
    destination.append(" BIGINT", 7);
 
1417
    if (field.has_constraints() and
 
1418
        field.constraints().is_unsigned())
 
1419
    {
 
1420
      destination.append(" BIGINT UNSIGNED");
 
1421
    }
 
1422
    else
 
1423
    {
 
1424
      destination.append(" BIGINT");
 
1425
    }
1358
1426
    break;
1359
1427
  case Table::Field::DECIMAL:
1360
1428
    {
1361
 
      destination.append(" DECIMAL(", 9);
 
1429
      destination.append(" DECIMAL(");
1362
1430
      stringstream ss;
1363
1431
      ss << field.numeric_options().precision() << ",";
1364
1432
      ss << field.numeric_options().scale() << ")";
1366
1434
    }
1367
1435
    break;
1368
1436
  case Table::Field::DATE:
1369
 
    destination.append(" DATE", 5);
1370
 
    break;
1371
 
  case Table::Field::TIMESTAMP:
1372
 
    destination.append(" TIMESTAMP",  10);
1373
 
    break;
 
1437
    destination.append(" DATE");
 
1438
    break;
 
1439
 
 
1440
  case Table::Field::EPOCH:
 
1441
    if (field.time_options().microseconds())
 
1442
    {
 
1443
      destination.append(" TIMESTAMP(6)");
 
1444
    }
 
1445
    else
 
1446
    {
 
1447
      destination.append(" TIMESTAMP");
 
1448
    }
 
1449
    break;
 
1450
 
1374
1451
  case Table::Field::DATETIME:
1375
 
    destination.append(" DATETIME",  9);
1376
 
    break;
1377
 
  }
1378
 
 
1379
 
  if (field.type() == Table::Field::INTEGER || 
1380
 
      field.type() == Table::Field::BIGINT)
1381
 
  {
1382
 
    if (field.has_constraints() &&
1383
 
        field.constraints().has_is_unsigned() &&
1384
 
        field.constraints().is_unsigned())
1385
 
    {
1386
 
      destination.append(" UNSIGNED", 9);
1387
 
    }
 
1452
    destination.append(" DATETIME");
 
1453
    break;
 
1454
  case Table::Field::TIME:
 
1455
    destination.append(" TIME");
 
1456
    break;
1388
1457
  }
1389
1458
 
1390
1459
  if (field.type() == Table::Field::BLOB ||
1393
1462
    if (field.string_options().has_collation()
1394
1463
        && field.string_options().collation().compare("binary"))
1395
1464
    {
1396
 
      destination.append(" COLLATE ", 9);
 
1465
      destination.append(" COLLATE ");
1397
1466
      destination.append(field.string_options().collation());
1398
1467
    }
1399
1468
  }
1400
1469
 
1401
 
  if (field.has_constraints() &&
1402
 
      ! field.constraints().is_nullable())
1403
 
  {
1404
 
    destination.append(" NOT NULL", 9);
1405
 
  }
1406
 
  else if (field.type() == Table::Field::TIMESTAMP)
1407
 
    destination.append(" NULL", 5);
 
1470
  if (field.has_constraints() and field.constraints().is_unique())
 
1471
  {
 
1472
    destination.append(" UNIQUE");
 
1473
  }
 
1474
 
 
1475
  if (field.has_constraints() && field.constraints().is_notnull())
 
1476
  {
 
1477
    destination.append(" NOT NULL");
 
1478
  }
 
1479
  else if (field.type() == Table::Field::EPOCH)
 
1480
  {
 
1481
    destination.append(" NULL");
 
1482
  }
1408
1483
 
1409
1484
  if (field.type() == Table::Field::INTEGER || 
1410
1485
      field.type() == Table::Field::BIGINT)
1413
1488
    if (field.has_numeric_options() &&
1414
1489
        field.numeric_options().is_autoincrement())
1415
1490
    {
1416
 
      destination.append(" AUTO_INCREMENT", 15);
 
1491
      destination.append(" AUTO_INCREMENT");
1417
1492
    }
1418
1493
  }
1419
1494
 
1420
1495
  if (field.options().has_default_value())
1421
1496
  {
1422
 
    destination.append(" DEFAULT ", 9);
 
1497
    destination.append(" DEFAULT ");
1423
1498
    append_escaped_string(&destination, field.options().default_value());
1424
1499
  }
1425
1500
  else if (field.options().has_default_expression())
1426
1501
  {
1427
 
    destination.append(" DEFAULT ", 9);
 
1502
    destination.append(" DEFAULT ");
1428
1503
    destination.append(field.options().default_expression());
1429
1504
  }
1430
1505
  else if (field.options().has_default_bin_value())
1431
1506
  {
1432
1507
    const string &v= field.options().default_bin_value();
1433
1508
    if (v.length() == 0)
1434
 
      destination.append(" DEFAULT ''", 11);
 
1509
    {
 
1510
      destination.append(" DEFAULT ''");
 
1511
    }
1435
1512
    else
1436
1513
    {
1437
 
      destination.append(" DEFAULT 0x", 11);
 
1514
      destination.append(" DEFAULT 0x");
1438
1515
      for (size_t x= 0; x < v.length(); x++)
1439
1516
      {
1440
1517
        char hex[3];
1447
1524
           && field.options().default_null()
1448
1525
           && field.type() != Table::Field::BLOB)
1449
1526
  {
1450
 
    destination.append(" DEFAULT NULL", 13);
 
1527
    destination.append(" DEFAULT NULL");
1451
1528
  }
1452
1529
 
1453
1530
  if (field.has_options() && field.options().has_update_expression())
1454
1531
  {
1455
 
    destination.append(" ON UPDATE ", 11);
 
1532
    destination.append(" ON UPDATE ");
1456
1533
    destination.append(field.options().update_expression());
1457
1534
  }
1458
1535
 
1459
1536
  if (field.has_comment())
1460
1537
  {
1461
 
    destination.append(" COMMENT ", 9);
 
1538
    destination.append(" COMMENT ");
1462
1539
    append_escaped_string(&destination, field.comment(), quoted_default);
1463
1540
  }
1464
1541
  return NONE;
1488
1565
  case DRIZZLE_TYPE_NULL:
1489
1566
    assert(false); /* Not a user definable type */
1490
1567
    return Table::Field::INTEGER; /* unreachable */
 
1568
  case DRIZZLE_TYPE_MICROTIME:
1491
1569
  case DRIZZLE_TYPE_TIMESTAMP:
1492
 
    return Table::Field::TIMESTAMP;
 
1570
    return Table::Field::EPOCH;
1493
1571
  case DRIZZLE_TYPE_LONGLONG:
1494
1572
    return Table::Field::BIGINT;
1495
1573
  case DRIZZLE_TYPE_DATETIME:
1496
1574
    return Table::Field::DATETIME;
 
1575
  case DRIZZLE_TYPE_TIME:
 
1576
    return Table::Field::TIME;
1497
1577
  case DRIZZLE_TYPE_DATE:
1498
1578
    return Table::Field::DATE;
1499
1579
  case DRIZZLE_TYPE_VARCHAR:
1504
1584
    return Table::Field::ENUM;
1505
1585
  case DRIZZLE_TYPE_BLOB:
1506
1586
    return Table::Field::BLOB;
 
1587
  case DRIZZLE_TYPE_UUID:
 
1588
    return Table::Field::UUID;
 
1589
  case DRIZZLE_TYPE_BOOLEAN:
 
1590
    return Table::Field::BOOLEAN;
1507
1591
  }
1508
1592
 
1509
1593
  assert(false);