29
29
* Statement messages to other formats, including SQL strings.
34
34
#include <boost/lexical_cast.hpp>
36
#include <drizzled/charset.h>
37
#include <drizzled/message.h>
38
#include <drizzled/message/statement_transform.h>
39
#include <drizzled/message/transaction.pb.h>
40
#include <drizzled/message/access.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"
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();
156
157
if (num_keys > 1 && ! already_in_transaction)
157
158
sql_strings.push_back("START TRANSACTION");
159
for (size_t x= 0; x < num_keys; ++x)
160
for (x= 0; x < num_keys; ++x)
161
162
string destination;
317
318
sql_strings.push_back(destination);
320
case Statement::ALTER_SCHEMA:
322
assert(source.has_alter_schema_statement());
324
error= transformAlterSchemaStatementToSql(source.alter_schema_statement(),
327
sql_strings.push_back(destination);
330
321
case Statement::SET_VARIABLE:
332
323
assert(source.has_set_variable_statement());
819
808
enum TransformSqlError
820
transformAlterSchemaStatementToSql(const AlterSchemaStatement &statement,
822
enum TransformSqlVariant sql_variant)
824
const Schema &before= statement.before();
825
const Schema &after= statement.after();
827
/* Make sure we are given the before and after for the same object */
828
if (before.uuid() != after.uuid())
829
return UUID_MISMATCH;
831
char quoted_identifier= '`';
832
if (sql_variant == ANSI)
833
quoted_identifier= '"';
835
destination.append("ALTER SCHEMA ");
836
destination.push_back(quoted_identifier);
837
destination.append(before.name());
838
destination.push_back(quoted_identifier);
841
* Diff our schemas. Currently, only collation can change so a
842
* diff of the two structures is not really necessary.
844
destination.append(" COLLATE = ");
845
destination.append(after.collation());
850
enum TransformSqlError
851
809
transformDropSchemaStatementToSql(const DropSchemaStatement &statement,
852
810
string &destination,
853
811
enum TransformSqlVariant sql_variant)
876
834
const Schema &schema= statement.schema();
878
destination.append("CREATE SCHEMA ");
836
destination.append("CREATE SCHEMA ", 14);
879
837
destination.push_back(quoted_identifier);
880
838
destination.append(schema.name());
881
839
destination.push_back(quoted_identifier);
883
841
if (schema.has_collation())
885
destination.append(" COLLATE ");
843
destination.append(" COLLATE ", 9);
886
844
destination.append(schema.collation());
889
if (not message::is_replicated(schema))
891
destination.append(" REPLICATE = FALSE");
894
if (message::has_definer(schema))
896
destination.append(" DEFINER ");
897
destination.push_back('\'');
898
destination.append(message::definer(schema));
899
destination.push_back('\'');
914
859
const TableMetadata &table_metadata= statement.table_metadata();
916
destination.append("DROP TABLE ");
861
destination.append("DROP TABLE ", 11);
918
863
/* Add the IF EXISTS clause if necessary */
919
864
if (statement.has_if_exists_clause() &&
920
865
statement.if_exists_clause() == true)
922
destination.append("IF EXISTS ");
867
destination.append("IF EXISTS ", 10);
925
870
destination.push_back(quoted_identifier);
945
890
const TableMetadata &table_metadata= statement.table_metadata();
947
destination.append("TRUNCATE TABLE ");
892
destination.append("TRUNCATE TABLE ", 15);
948
893
destination.push_back(quoted_identifier);
949
894
destination.append(table_metadata.schema_name());
950
895
destination.push_back(quoted_identifier);
965
910
const FieldMetadata &variable_metadata= statement.variable_metadata();
966
911
bool should_quote_field_value= shouldQuoteFieldValue(variable_metadata.type());
968
destination.append("SET GLOBAL "); /* Only global variables are replicated */
913
destination.append("SET GLOBAL ", 11); /* Only global variables are replicated */
969
914
destination.append(variable_metadata.name());
970
915
destination.push_back('=');
997
942
if (sql_variant == ANSI)
998
943
quoted_identifier= '"';
1000
destination.append("CREATE ");
945
destination.append("CREATE ", 7);
1002
947
if (table.type() == Table::TEMPORARY)
1003
destination.append("TEMPORARY ");
948
destination.append("TEMPORARY ", 10);
1005
destination.append("TABLE ");
950
destination.append("TABLE ", 6);
1006
951
if (with_schema)
1008
953
append_escaped_string(&destination, table.schema(), quoted_identifier);
1009
954
destination.push_back('.');
1011
956
append_escaped_string(&destination, table.name(), quoted_identifier);
1012
destination.append(" (\n");
957
destination.append(" (\n", 3);
1014
959
enum TransformSqlError result= NONE;
1015
960
size_t num_fields= table.field_size();
1031
976
size_t num_indexes= table.indexes_size();
1033
978
if (num_indexes > 0)
1034
destination.append(",\n");
979
destination.append(",\n", 2);
1036
981
for (size_t x= 0; x < num_indexes; ++x)
1038
983
const message::Table::Index &index= table.indexes(x);
1041
destination.append(",\n");
986
destination.append(",\n", 2);
1043
988
result= transformIndexDefinitionToSql(index, table, destination, sql_variant);
1049
994
size_t num_foreign_keys= table.fk_constraint_size();
1051
996
if (num_foreign_keys > 0)
1052
destination.append(",\n");
997
destination.append(",\n", 2);
1054
999
for (size_t x= 0; x < num_foreign_keys; ++x)
1056
1001
const message::Table::ForeignKeyConstraint &fkey= table.fk_constraint(x);
1059
destination.append(",\n");
1004
destination.append(",\n", 2);
1061
1006
result= transformForeignKeyConstraintDefinitionToSql(fkey, table, destination, sql_variant);
1067
destination.append("\n)");
1012
destination.append("\n)", 2);
1069
1014
/* Add ENGINE = " clause */
1070
1015
if (table.has_engine())
1072
destination.append(" ENGINE=");
1017
destination.append(" ENGINE=", 8);
1073
1018
destination.append(table.engine().name());
1075
1020
size_t num_engine_options= table.engine().options_size();
1080
1025
const Engine::Option &option= table.engine().options(x);
1081
1026
destination.append(option.name());
1082
destination.append("='");
1027
destination.append("='", 2);
1083
1028
destination.append(option.state());
1084
destination.append("'");
1085
if (x != num_engine_options-1)
1087
destination.append(", ");
1029
destination.append("'", 1);
1030
if(x != num_engine_options-1)
1031
destination.append(", ", 2);
1092
1035
if (table.has_options())
1093
1036
(void) transformTableOptionsToSql(table.options(), destination, sql_variant);
1095
if (not message::is_replicated(table))
1097
destination.append(" REPLICATE = FALSE");
1100
if (message::has_definer(table))
1102
destination.append(" DEFINER ");
1103
destination.push_back('\'');
1104
destination.append(message::definer(table));
1105
destination.push_back('\'');
1119
1049
if (options.has_comment())
1121
destination.append(" COMMENT=");
1051
destination.append(" COMMENT=", 9);
1122
1052
append_escaped_string(&destination, options.comment());
1125
1055
if (options.has_collation())
1127
destination.append(" COLLATE = ");
1057
destination.append(" COLLATE = ", 11);
1128
1058
destination.append(options.collation());
1131
1061
if (options.has_data_file_name())
1133
destination.append("\nDATA_FILE_NAME = '");
1063
destination.append("\nDATA_FILE_NAME = '", 19);
1134
1064
destination.append(options.data_file_name());
1135
1065
destination.push_back('\'');
1138
1068
if (options.has_index_file_name())
1140
destination.append("\nINDEX_FILE_NAME = '");
1070
destination.append("\nINDEX_FILE_NAME = '", 20);
1141
1071
destination.append(options.index_file_name());
1142
1072
destination.push_back('\'');
1145
1075
if (options.has_max_rows())
1147
destination.append("\nMAX_ROWS = ");
1077
destination.append("\nMAX_ROWS = ", 12);
1148
1078
destination.append(boost::lexical_cast<string>(options.max_rows()));
1151
1081
if (options.has_min_rows())
1153
destination.append("\nMIN_ROWS = ");
1083
destination.append("\nMIN_ROWS = ", 12);
1154
1084
destination.append(boost::lexical_cast<string>(options.min_rows()));
1157
1087
if (options.has_user_set_auto_increment_value()
1158
1088
&& options.has_auto_increment_value())
1160
destination.append(" AUTO_INCREMENT=");
1090
destination.append(" AUTO_INCREMENT=", 16);
1161
1091
destination.append(boost::lexical_cast<string>(options.auto_increment_value()));
1164
1094
if (options.has_avg_row_length())
1166
destination.append("\nAVG_ROW_LENGTH = ");
1096
destination.append("\nAVG_ROW_LENGTH = ", 18);
1167
1097
destination.append(boost::lexical_cast<string>(options.avg_row_length()));
1170
if (options.has_checksum() && options.checksum())
1171
destination.append("\nCHECKSUM = TRUE");
1173
if (options.has_page_checksum() && options.page_checksum())
1174
destination.append("\nPAGE_CHECKSUM = TRUE");
1100
if (options.has_checksum() &&
1102
destination.append("\nCHECKSUM = TRUE", 16);
1103
if (options.has_page_checksum() &&
1104
options.page_checksum())
1105
destination.append("\nPAGE_CHECKSUM = TRUE", 21);
1189
1120
destination.append(" ", 2);
1191
1122
if (index.is_primary())
1192
destination.append("PRIMARY ");
1123
destination.append("PRIMARY ", 8);
1193
1124
else if (index.is_unique())
1194
destination.append("UNIQUE ");
1125
destination.append("UNIQUE ", 7);
1196
1127
destination.append("KEY ", 4);
1197
1128
if (! (index.is_primary() && index.name().compare("PRIMARY")==0))
1243
1174
case Table::Index::UNKNOWN_INDEX:
1245
1176
case Table::Index::BTREE:
1246
destination.append(" USING BTREE");
1177
destination.append(" USING BTREE", 12);
1248
1179
case Table::Index::RTREE:
1249
destination.append(" USING RTREE");
1180
destination.append(" USING RTREE", 12);
1251
1182
case Table::Index::HASH:
1252
destination.append(" USING HASH");
1183
destination.append(" USING HASH", 11);
1254
1185
case Table::Index::FULLTEXT:
1255
destination.append(" USING FULLTEXT");
1186
destination.append(" USING FULLTEXT", 15);
1259
1190
if (index.has_comment())
1261
destination.append(" COMMENT ");
1192
destination.append(" COMMENT ", 9);
1262
1193
append_escaped_string(&destination, index.comment());
1298
1229
if (sql_variant == ANSI)
1299
1230
quoted_identifier= '"';
1301
destination.append(" ");
1232
destination.append(" ", 2);
1303
1234
if (fkey.has_name())
1305
destination.append("CONSTRAINT ");
1236
destination.append("CONSTRAINT ", 11);
1306
1237
append_escaped_string(&destination, fkey.name(), quoted_identifier);
1307
1238
destination.append(" ", 1);
1310
destination.append("FOREIGN KEY (");
1241
destination.append("FOREIGN KEY (", 13);
1312
1243
for (ssize_t x= 0; x < fkey.column_names_size(); ++x)
1318
1249
quoted_identifier);
1321
destination.append(") REFERENCES ");
1252
destination.append(") REFERENCES ", 13);
1323
1254
append_escaped_string(&destination, fkey.references_table_name(),
1324
1255
quoted_identifier);
1325
destination.append(" (");
1256
destination.append(" (", 2);
1327
1258
for (ssize_t x= 0; x < fkey.references_columns_size(); ++x)
1338
1269
if (fkey.has_update_option() and fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1340
destination.append(" ON UPDATE ");
1271
destination.append(" ON UPDATE ", 11);
1341
1272
transformForeignKeyOptionToSql(fkey.update_option(), destination);
1344
1275
if (fkey.has_delete_option() and fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1346
destination.append(" ON DELETE ");
1277
destination.append(" ON DELETE ", 11);
1347
1278
transformForeignKeyOptionToSql(fkey.delete_option(), destination);
1388
1319
if (field.string_options().has_collation()
1389
1320
&& field.string_options().collation().compare("binary") == 0)
1390
destination.append(" VARBINARY(");
1321
destination.append(" VARBINARY(", 11);
1392
destination.append(" VARCHAR(");
1323
destination.append(" VARCHAR(", 9);
1394
1325
destination.append(boost::lexical_cast<string>(field.string_options().length()));
1395
1326
destination.append(")");
1400
1331
if (field.string_options().has_collation()
1401
1332
&& field.string_options().collation().compare("binary") == 0)
1402
destination.append(" BLOB");
1333
destination.append(" BLOB", 5);
1404
destination.append(" TEXT");
1335
destination.append(" TEXT", 5);
1407
1338
case Table::Field::ENUM:
1409
1340
size_t num_field_values= field.enumeration_values().field_value_size();
1410
destination.append(" ENUM(");
1341
destination.append(" ENUM(", 6);
1411
1342
for (size_t x= 0; x < num_field_values; ++x)
1413
1344
const string &type= field.enumeration_values().field_value(x);
1425
1356
case Table::Field::UUID:
1426
destination.append(" UUID");
1428
case Table::Field::IPV6:
1429
destination.append(" IPV6");
1431
case Table::Field::BOOLEAN:
1432
destination.append(" BOOLEAN");
1357
destination.append(" UUID", 5);
1434
1359
case Table::Field::INTEGER:
1435
destination.append(" INT");
1360
destination.append(" INT", 4);
1437
1362
case Table::Field::BIGINT:
1438
if (field.has_constraints() and
1439
field.constraints().is_unsigned())
1441
destination.append(" BIGINT UNSIGNED");
1445
destination.append(" BIGINT");
1363
destination.append(" BIGINT", 7);
1448
1365
case Table::Field::DECIMAL:
1450
destination.append(" DECIMAL(");
1367
destination.append(" DECIMAL(", 9);
1451
1368
stringstream ss;
1452
1369
ss << field.numeric_options().precision() << ",";
1453
1370
ss << field.numeric_options().scale() << ")";
1457
1374
case Table::Field::DATE:
1458
destination.append(" DATE");
1461
case Table::Field::EPOCH:
1462
if (field.time_options().microseconds())
1464
destination.append(" TIMESTAMP(6)");
1468
destination.append(" TIMESTAMP");
1375
destination.append(" DATE", 5);
1377
case Table::Field::TIMESTAMP:
1378
destination.append(" TIMESTAMP", 10);
1472
1380
case Table::Field::DATETIME:
1473
destination.append(" DATETIME");
1475
case Table::Field::TIME:
1476
destination.append(" TIME");
1381
destination.append(" DATETIME", 9);
1385
if (field.type() == Table::Field::INTEGER ||
1386
field.type() == Table::Field::BIGINT)
1388
if (field.has_constraints() &&
1389
field.constraints().has_is_unsigned() &&
1390
field.constraints().is_unsigned())
1392
destination.append(" UNSIGNED", 9);
1480
1396
if (field.type() == Table::Field::BLOB ||
1483
1399
if (field.string_options().has_collation()
1484
1400
&& field.string_options().collation().compare("binary"))
1486
destination.append(" COLLATE ");
1402
destination.append(" COLLATE ", 9);
1487
1403
destination.append(field.string_options().collation());
1491
if (field.has_constraints() and field.constraints().is_unique())
1493
destination.append(" UNIQUE");
1496
if (field.has_constraints() && field.constraints().is_notnull())
1498
destination.append(" NOT NULL");
1500
else if (field.type() == Table::Field::EPOCH)
1502
destination.append(" NULL");
1407
if (field.has_constraints() &&
1408
! field.constraints().is_nullable())
1410
destination.append(" NOT NULL", 9);
1412
else if (field.type() == Table::Field::TIMESTAMP)
1413
destination.append(" NULL", 5);
1505
1415
if (field.type() == Table::Field::INTEGER ||
1506
1416
field.type() == Table::Field::BIGINT)
1509
1419
if (field.has_numeric_options() &&
1510
1420
field.numeric_options().is_autoincrement())
1512
destination.append(" AUTO_INCREMENT");
1422
destination.append(" AUTO_INCREMENT", 15);
1516
1426
if (field.options().has_default_value())
1518
destination.append(" DEFAULT ");
1428
destination.append(" DEFAULT ", 9);
1519
1429
append_escaped_string(&destination, field.options().default_value());
1521
1431
else if (field.options().has_default_expression())
1523
destination.append(" DEFAULT ");
1433
destination.append(" DEFAULT ", 9);
1524
1434
destination.append(field.options().default_expression());
1526
1436
else if (field.options().has_default_bin_value())
1528
1438
const string &v= field.options().default_bin_value();
1529
1439
if (v.length() == 0)
1531
destination.append(" DEFAULT ''");
1440
destination.append(" DEFAULT ''", 11);
1535
destination.append(" DEFAULT 0x");
1443
destination.append(" DEFAULT 0x", 11);
1536
1444
for (size_t x= 0; x < v.length(); x++)
1545
1453
&& field.options().default_null()
1546
1454
&& field.type() != Table::Field::BLOB)
1548
destination.append(" DEFAULT NULL");
1456
destination.append(" DEFAULT NULL", 13);
1551
1459
if (field.has_options() && field.options().has_update_expression())
1553
destination.append(" ON UPDATE ");
1461
destination.append(" ON UPDATE ", 11);
1554
1462
destination.append(field.options().update_expression());
1557
1465
if (field.has_comment())
1559
destination.append(" COMMENT ");
1467
destination.append(" COMMENT ", 9);
1560
1468
append_escaped_string(&destination, field.comment(), quoted_default);
1586
1494
case DRIZZLE_TYPE_NULL:
1587
1495
assert(false); /* Not a user definable type */
1588
1496
return Table::Field::INTEGER; /* unreachable */
1589
case DRIZZLE_TYPE_MICROTIME:
1590
1497
case DRIZZLE_TYPE_TIMESTAMP:
1591
return Table::Field::EPOCH;
1498
return Table::Field::TIMESTAMP;
1592
1499
case DRIZZLE_TYPE_LONGLONG:
1593
1500
return Table::Field::BIGINT;
1594
1501
case DRIZZLE_TYPE_DATETIME:
1595
1502
return Table::Field::DATETIME;
1596
case DRIZZLE_TYPE_TIME:
1597
return Table::Field::TIME;
1598
1503
case DRIZZLE_TYPE_DATE:
1599
1504
return Table::Field::DATE;
1600
1505
case DRIZZLE_TYPE_VARCHAR: