818
798
enum TransformSqlError
819
transformAlterSchemaStatementToSql(const AlterSchemaStatement &statement,
821
enum TransformSqlVariant sql_variant)
823
const Schema &before= statement.before();
824
const Schema &after= statement.after();
826
/* Make sure we are given the before and after for the same object */
827
if (before.uuid() != after.uuid())
828
return UUID_MISMATCH;
830
char quoted_identifier= '`';
831
if (sql_variant == ANSI)
832
quoted_identifier= '"';
834
destination.append("ALTER SCHEMA ");
835
destination.push_back(quoted_identifier);
836
destination.append(before.name());
837
destination.push_back(quoted_identifier);
840
* Diff our schemas. Currently, only collation can change so a
841
* diff of the two structures is not really necessary.
843
destination.append(" COLLATE = ");
844
destination.append(after.collation());
849
enum TransformSqlError
850
799
transformDropSchemaStatementToSql(const DropSchemaStatement &statement,
851
800
string &destination,
852
801
enum TransformSqlVariant sql_variant)
875
824
const Schema &schema= statement.schema();
877
destination.append("CREATE SCHEMA ");
826
destination.append("CREATE SCHEMA ", 14);
878
827
destination.push_back(quoted_identifier);
879
828
destination.append(schema.name());
880
829
destination.push_back(quoted_identifier);
882
831
if (schema.has_collation())
884
destination.append(" COLLATE ");
833
destination.append(" COLLATE ", 9);
885
834
destination.append(schema.collation());
900
849
const TableMetadata &table_metadata= statement.table_metadata();
902
destination.append("DROP TABLE ");
851
destination.append("DROP TABLE ", 11);
904
853
/* Add the IF EXISTS clause if necessary */
905
854
if (statement.has_if_exists_clause() &&
906
855
statement.if_exists_clause() == true)
908
destination.append("IF EXISTS ");
857
destination.append("IF EXISTS ", 10);
911
860
destination.push_back(quoted_identifier);
983
932
if (sql_variant == ANSI)
984
933
quoted_identifier= '"';
986
destination.append("CREATE ");
935
destination.append("CREATE ", 7);
988
937
if (table.type() == Table::TEMPORARY)
989
destination.append("TEMPORARY ");
938
destination.append("TEMPORARY ", 10);
991
destination.append("TABLE ");
940
destination.append("TABLE ", 6);
994
943
append_escaped_string(&destination, table.schema(), quoted_identifier);
995
944
destination.push_back('.');
997
946
append_escaped_string(&destination, table.name(), quoted_identifier);
998
destination.append(" (\n");
947
destination.append(" (\n", 3);
1000
949
enum TransformSqlError result= NONE;
1001
950
size_t num_fields= table.field_size();
1017
966
size_t num_indexes= table.indexes_size();
1019
968
if (num_indexes > 0)
1020
destination.append(",\n");
969
destination.append(",\n", 2);
1022
971
for (size_t x= 0; x < num_indexes; ++x)
1024
973
const message::Table::Index &index= table.indexes(x);
1027
destination.append(",\n");
976
destination.append(",\n", 2);
1029
978
result= transformIndexDefinitionToSql(index, table, destination, sql_variant);
1035
984
size_t num_foreign_keys= table.fk_constraint_size();
1037
986
if (num_foreign_keys > 0)
1038
destination.append(",\n");
987
destination.append(",\n", 2);
1040
989
for (size_t x= 0; x < num_foreign_keys; ++x)
1042
991
const message::Table::ForeignKeyConstraint &fkey= table.fk_constraint(x);
1045
destination.append(",\n");
994
destination.append(",\n", 2);
1047
996
result= transformForeignKeyConstraintDefinitionToSql(fkey, table, destination, sql_variant);
1053
destination.append("\n)");
1002
destination.append("\n)", 2);
1055
1004
/* Add ENGINE = " clause */
1056
1005
if (table.has_engine())
1058
destination.append(" ENGINE=");
1007
destination.append(" ENGINE=", 8);
1059
1008
destination.append(table.engine().name());
1061
1010
size_t num_engine_options= table.engine().options_size();
1066
1015
const Engine::Option &option= table.engine().options(x);
1067
1016
destination.append(option.name());
1068
destination.append("='");
1017
destination.append("='", 2);
1069
1018
destination.append(option.state());
1070
destination.append("'");
1071
if (x != num_engine_options-1)
1073
destination.append(", ");
1019
destination.append("'", 1);
1020
if(x != num_engine_options-1)
1021
destination.append(", ", 2);
1089
1036
if (sql_variant == ANSI)
1090
1037
return NONE; /* ANSI does not support table options... */
1092
1041
if (options.has_comment())
1094
destination.append(" COMMENT=");
1043
destination.append(" COMMENT=", 9);
1095
1044
append_escaped_string(&destination, options.comment());
1098
1047
if (options.has_collation())
1100
destination.append(" COLLATE = ");
1049
destination.append(" COLLATE = ", 11);
1101
1050
destination.append(options.collation());
1104
1053
if (options.has_data_file_name())
1106
destination.append("\nDATA_FILE_NAME = '");
1055
destination.append("\nDATA_FILE_NAME = '", 19);
1107
1056
destination.append(options.data_file_name());
1108
1057
destination.push_back('\'');
1111
1060
if (options.has_index_file_name())
1113
destination.append("\nINDEX_FILE_NAME = '");
1062
destination.append("\nINDEX_FILE_NAME = '", 20);
1114
1063
destination.append(options.index_file_name());
1115
1064
destination.push_back('\'');
1118
1067
if (options.has_max_rows())
1120
destination.append("\nMAX_ROWS = ");
1121
destination.append(boost::lexical_cast<string>(options.max_rows()));
1069
ss << options.max_rows();
1070
destination.append("\nMAX_ROWS = ", 12);
1071
destination.append(ss.str());
1124
1075
if (options.has_min_rows())
1126
destination.append("\nMIN_ROWS = ");
1127
destination.append(boost::lexical_cast<string>(options.min_rows()));
1077
ss << options.min_rows();
1078
destination.append("\nMIN_ROWS = ", 12);
1079
destination.append(ss.str());
1130
1083
if (options.has_user_set_auto_increment_value()
1131
1084
&& options.has_auto_increment_value())
1133
destination.append(" AUTO_INCREMENT=");
1134
destination.append(boost::lexical_cast<string>(options.auto_increment_value()));
1086
ss << options.auto_increment_value();
1087
destination.append(" AUTO_INCREMENT=", 16);
1088
destination.append(ss.str());
1137
1092
if (options.has_avg_row_length())
1139
destination.append("\nAVG_ROW_LENGTH = ");
1140
destination.append(boost::lexical_cast<string>(options.avg_row_length()));
1094
ss << options.avg_row_length();
1095
destination.append("\nAVG_ROW_LENGTH = ", 18);
1096
destination.append(ss.str());
1143
1100
if (options.has_checksum() &&
1144
1101
options.checksum())
1145
destination.append("\nCHECKSUM = TRUE");
1102
destination.append("\nCHECKSUM = TRUE", 16);
1146
1103
if (options.has_page_checksum() &&
1147
1104
options.page_checksum())
1148
destination.append("\nPAGE_CHECKSUM = TRUE");
1105
destination.append("\nPAGE_CHECKSUM = TRUE", 21);
1163
1120
destination.append(" ", 2);
1165
1122
if (index.is_primary())
1166
destination.append("PRIMARY ");
1123
destination.append("PRIMARY ", 8);
1167
1124
else if (index.is_unique())
1168
destination.append("UNIQUE ");
1125
destination.append("UNIQUE ", 7);
1170
1127
destination.append("KEY ", 4);
1171
1128
if (! (index.is_primary() && index.name().compare("PRIMARY")==0))
1217
1176
case Table::Index::UNKNOWN_INDEX:
1219
1178
case Table::Index::BTREE:
1220
destination.append(" USING BTREE");
1179
destination.append(" USING BTREE", 12);
1222
1181
case Table::Index::RTREE:
1223
destination.append(" USING RTREE");
1182
destination.append(" USING RTREE", 12);
1225
1184
case Table::Index::HASH:
1226
destination.append(" USING HASH");
1185
destination.append(" USING HASH", 11);
1228
1187
case Table::Index::FULLTEXT:
1229
destination.append(" USING FULLTEXT");
1188
destination.append(" USING FULLTEXT", 15);
1233
1192
if (index.has_comment())
1235
destination.append(" COMMENT ");
1194
destination.append(" COMMENT ", 9);
1236
1195
append_escaped_string(&destination, index.comment());
1252
1213
case Table::ForeignKeyConstraint::OPTION_SET_NULL:
1253
1214
destination.append("SET NULL");
1255
case Table::ForeignKeyConstraint::OPTION_UNDEF:
1256
1216
case Table::ForeignKeyConstraint::OPTION_NO_ACTION:
1257
1217
destination.append("NO ACTION");
1259
case Table::ForeignKeyConstraint::OPTION_SET_DEFAULT:
1219
case Table::ForeignKeyConstraint::OPTION_DEFAULT:
1260
1220
destination.append("SET DEFAULT");
1272
1232
if (sql_variant == ANSI)
1273
1233
quoted_identifier= '"';
1275
destination.append(" ");
1235
destination.append(" ", 2);
1277
1237
if (fkey.has_name())
1279
destination.append("CONSTRAINT ");
1239
destination.append("CONSTRAINT ", 11);
1280
1240
append_escaped_string(&destination, fkey.name(), quoted_identifier);
1281
1241
destination.append(" ", 1);
1284
destination.append("FOREIGN KEY (");
1244
destination.append("FOREIGN KEY (", 13);
1286
1246
for (ssize_t x= 0; x < fkey.column_names_size(); ++x)
1292
1252
quoted_identifier);
1295
destination.append(") REFERENCES ");
1255
destination.append(") REFERENCES ", 13);
1297
1257
append_escaped_string(&destination, fkey.references_table_name(),
1298
1258
quoted_identifier);
1299
destination.append(" (");
1259
destination.append(" (", 2);
1301
1261
for (ssize_t x= 0; x < fkey.references_columns_size(); ++x)
1310
1270
destination.push_back(')');
1312
if (fkey.has_update_option() and fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1272
if (fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1314
destination.append(" ON UPDATE ");
1274
destination.append(" ON UPDATE ", 11);
1315
1275
transformForeignKeyOptionToSql(fkey.update_option(), destination);
1318
if (fkey.has_delete_option() and fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1278
if (fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1320
destination.append(" ON DELETE ");
1280
destination.append(" ON DELETE ", 11);
1321
1281
transformForeignKeyOptionToSql(fkey.delete_option(), destination);
1362
1322
if (field.string_options().has_collation()
1363
1323
&& field.string_options().collation().compare("binary") == 0)
1364
destination.append(" VARBINARY(");
1324
destination.append(" VARBINARY(", 11);
1366
destination.append(" VARCHAR(");
1326
destination.append(" VARCHAR(", 9);
1368
destination.append(boost::lexical_cast<string>(field.string_options().length()));
1369
destination.append(")");
1329
ss << field.string_options().length() << ")";
1330
destination.append(ss.str());
1372
1333
case Table::Field::BLOB:
1374
1335
if (field.string_options().has_collation()
1375
1336
&& field.string_options().collation().compare("binary") == 0)
1376
destination.append(" BLOB");
1337
destination.append(" BLOB", 5);
1378
destination.append(" TEXT");
1339
destination.append(" TEXT", 5);
1381
1342
case Table::Field::ENUM:
1383
1344
size_t num_field_values= field.enumeration_values().field_value_size();
1384
destination.append(" ENUM(");
1345
destination.append(" ENUM(", 6);
1385
1346
for (size_t x= 0; x < num_field_values; ++x)
1387
1348
const string &type= field.enumeration_values().field_value(x);
1396
1357
destination.push_back(')');
1399
case Table::Field::UUID:
1400
destination.append(" UUID");
1402
case Table::Field::BOOLEAN:
1403
destination.append(" BOOLEAN");
1405
1360
case Table::Field::INTEGER:
1406
destination.append(" INT");
1361
destination.append(" INT", 4);
1408
1363
case Table::Field::BIGINT:
1409
if (field.has_constraints() and
1410
field.constraints().is_unsigned())
1412
destination.append(" BIGINT UNSIGNED");
1416
destination.append(" BIGINT");
1364
destination.append(" BIGINT", 7);
1419
1366
case Table::Field::DECIMAL:
1421
destination.append(" DECIMAL(");
1368
destination.append(" DECIMAL(", 9);
1422
1369
stringstream ss;
1423
1370
ss << field.numeric_options().precision() << ",";
1424
1371
ss << field.numeric_options().scale() << ")";
1428
1375
case Table::Field::DATE:
1429
destination.append(" DATE");
1432
case Table::Field::EPOCH:
1433
if (field.time_options().microseconds())
1435
destination.append(" TIMESTAMP(6)");
1439
destination.append(" TIMESTAMP");
1376
destination.append(" DATE", 5);
1378
case Table::Field::TIMESTAMP:
1379
destination.append(" TIMESTAMP", 10);
1443
1381
case Table::Field::DATETIME:
1444
destination.append(" DATETIME");
1446
case Table::Field::TIME:
1447
destination.append(" TIME");
1382
destination.append(" DATETIME", 9);
1386
if (field.type() == Table::Field::INTEGER ||
1387
field.type() == Table::Field::BIGINT)
1389
if (field.has_constraints() &&
1390
field.constraints().has_is_unsigned() &&
1391
field.constraints().is_unsigned())
1393
destination.append(" UNSIGNED", 9);
1451
1397
if (field.type() == Table::Field::BLOB ||
1454
1400
if (field.string_options().has_collation()
1455
1401
&& field.string_options().collation().compare("binary"))
1457
destination.append(" COLLATE ");
1403
destination.append(" COLLATE ", 9);
1458
1404
destination.append(field.string_options().collation());
1462
if (field.has_constraints() and field.constraints().is_unique())
1464
destination.append(" UNIQUE");
1467
if (field.has_constraints() && field.constraints().is_notnull())
1469
destination.append(" NOT NULL");
1471
else if (field.type() == Table::Field::EPOCH)
1473
destination.append(" NULL");
1408
if (field.has_constraints() &&
1409
! field.constraints().is_nullable())
1411
destination.append(" NOT NULL", 9);
1413
else if (field.type() == Table::Field::TIMESTAMP)
1414
destination.append(" NULL", 5);
1476
1416
if (field.type() == Table::Field::INTEGER ||
1477
1417
field.type() == Table::Field::BIGINT)
1480
1420
if (field.has_numeric_options() &&
1481
1421
field.numeric_options().is_autoincrement())
1483
destination.append(" AUTO_INCREMENT");
1423
destination.append(" AUTO_INCREMENT", 15);
1487
1427
if (field.options().has_default_value())
1489
destination.append(" DEFAULT ");
1429
destination.append(" DEFAULT ", 9);
1490
1430
append_escaped_string(&destination, field.options().default_value());
1492
1432
else if (field.options().has_default_expression())
1494
destination.append(" DEFAULT ");
1434
destination.append(" DEFAULT ", 9);
1495
1435
destination.append(field.options().default_expression());
1497
1437
else if (field.options().has_default_bin_value())
1499
1439
const string &v= field.options().default_bin_value();
1500
1440
if (v.length() == 0)
1502
destination.append(" DEFAULT ''");
1441
destination.append(" DEFAULT ''", 11);
1506
destination.append(" DEFAULT 0x");
1444
destination.append(" DEFAULT 0x", 11);
1507
1445
for (size_t x= 0; x < v.length(); x++)
1516
1454
&& field.options().default_null()
1517
1455
&& field.type() != Table::Field::BLOB)
1519
destination.append(" DEFAULT NULL");
1457
destination.append(" DEFAULT NULL", 13);
1522
1460
if (field.has_options() && field.options().has_update_expression())
1524
destination.append(" ON UPDATE ");
1462
destination.append(" ON UPDATE ", 11);
1525
1463
destination.append(field.options().update_expression());
1528
1466
if (field.has_comment())
1530
destination.append(" COMMENT ");
1468
destination.append(" COMMENT ", 9);
1531
1469
append_escaped_string(&destination, field.comment(), quoted_default);
1557
1495
case DRIZZLE_TYPE_NULL:
1558
1496
assert(false); /* Not a user definable type */
1559
1497
return Table::Field::INTEGER; /* unreachable */
1560
case DRIZZLE_TYPE_MICROTIME:
1561
1498
case DRIZZLE_TYPE_TIMESTAMP:
1562
return Table::Field::EPOCH;
1499
return Table::Field::TIMESTAMP;
1563
1500
case DRIZZLE_TYPE_LONGLONG:
1564
1501
return Table::Field::BIGINT;
1565
1502
case DRIZZLE_TYPE_DATETIME:
1566
1503
return Table::Field::DATETIME;
1567
case DRIZZLE_TYPE_TIME:
1568
return Table::Field::TIME;
1569
1504
case DRIZZLE_TYPE_DATE:
1570
1505
return Table::Field::DATE;
1571
1506
case DRIZZLE_TYPE_VARCHAR: