1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
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
29
29
* Statement messages to other formats, including SQL strings.
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"
36
#include <drizzled/charset.h>
37
#include <drizzled/charset_info.h>
38
#include <drizzled/global_charset_info.h>
39
#include <drizzled/message.h>
40
#include <drizzled/message/statement_transform.h>
41
#include <drizzled/message/transaction.pb.h>
42
#include <drizzled/message/access.h>
152
154
const InsertHeader &insert_header= source.insert_header();
153
155
const InsertData &insert_data= source.insert_data();
154
156
size_t num_keys= insert_data.record_size();
157
158
if (num_keys > 1 && ! already_in_transaction)
158
159
sql_strings.push_back("START TRANSACTION");
160
for (x= 0; x < num_keys; ++x)
161
for (size_t x= 0; x < num_keys; ++x)
162
163
string destination;
318
319
sql_strings.push_back(destination);
322
case Statement::ALTER_SCHEMA:
324
assert(source.has_alter_schema_statement());
326
error= transformAlterSchemaStatementToSql(source.alter_schema_statement(),
329
sql_strings.push_back(destination);
321
332
case Statement::SET_VARIABLE:
323
334
assert(source.has_set_variable_statement());
808
821
enum TransformSqlError
822
transformAlterSchemaStatementToSql(const AlterSchemaStatement &statement,
824
enum TransformSqlVariant sql_variant)
826
const Schema &before= statement.before();
827
const Schema &after= statement.after();
829
/* Make sure we are given the before and after for the same object */
830
if (before.uuid() != after.uuid())
831
return UUID_MISMATCH;
833
char quoted_identifier= '`';
834
if (sql_variant == ANSI)
835
quoted_identifier= '"';
837
destination.append("ALTER SCHEMA ");
838
destination.push_back(quoted_identifier);
839
destination.append(before.name());
840
destination.push_back(quoted_identifier);
843
* Diff our schemas. Currently, only collation can change so a
844
* diff of the two structures is not really necessary.
846
destination.append(" COLLATE = ");
847
destination.append(after.collation());
852
enum TransformSqlError
809
853
transformDropSchemaStatementToSql(const DropSchemaStatement &statement,
810
854
string &destination,
811
855
enum TransformSqlVariant sql_variant)
834
878
const Schema &schema= statement.schema();
836
destination.append("CREATE SCHEMA ", 14);
880
destination.append("CREATE SCHEMA ");
837
881
destination.push_back(quoted_identifier);
838
882
destination.append(schema.name());
839
883
destination.push_back(quoted_identifier);
841
885
if (schema.has_collation())
843
destination.append(" COLLATE ", 9);
887
destination.append(" COLLATE ");
844
888
destination.append(schema.collation());
891
if (not message::is_replicated(schema))
893
destination.append(" REPLICATE = FALSE");
896
if (message::has_definer(schema))
898
destination.append(" DEFINER ");
899
destination.append(message::definer(schema));
859
914
const TableMetadata &table_metadata= statement.table_metadata();
861
destination.append("DROP TABLE ", 11);
916
destination.append("DROP TABLE ");
863
918
/* Add the IF EXISTS clause if necessary */
864
919
if (statement.has_if_exists_clause() &&
865
920
statement.if_exists_clause() == true)
867
destination.append("IF EXISTS ", 10);
922
destination.append("IF EXISTS ");
870
925
destination.push_back(quoted_identifier);
890
945
const TableMetadata &table_metadata= statement.table_metadata();
892
destination.append("TRUNCATE TABLE ", 15);
947
destination.append("TRUNCATE TABLE ");
893
948
destination.push_back(quoted_identifier);
894
949
destination.append(table_metadata.schema_name());
895
950
destination.push_back(quoted_identifier);
910
965
const FieldMetadata &variable_metadata= statement.variable_metadata();
911
966
bool should_quote_field_value= shouldQuoteFieldValue(variable_metadata.type());
913
destination.append("SET GLOBAL ", 11); /* Only global variables are replicated */
968
destination.append("SET GLOBAL "); /* Only global variables are replicated */
914
969
destination.append(variable_metadata.name());
915
970
destination.push_back('=');
942
997
if (sql_variant == ANSI)
943
998
quoted_identifier= '"';
945
destination.append("CREATE ", 7);
1000
destination.append("CREATE ");
947
1002
if (table.type() == Table::TEMPORARY)
948
destination.append("TEMPORARY ", 10);
1003
destination.append("TEMPORARY ");
950
destination.append("TABLE ", 6);
1005
destination.append("TABLE ");
951
1006
if (with_schema)
953
1008
append_escaped_string(&destination, table.schema(), quoted_identifier);
954
1009
destination.push_back('.');
956
1011
append_escaped_string(&destination, table.name(), quoted_identifier);
957
destination.append(" (\n", 3);
1012
destination.append(" (\n");
959
1014
enum TransformSqlError result= NONE;
960
1015
size_t num_fields= table.field_size();
976
1031
size_t num_indexes= table.indexes_size();
978
1033
if (num_indexes > 0)
979
destination.append(",\n", 2);
1034
destination.append(",\n");
981
1036
for (size_t x= 0; x < num_indexes; ++x)
983
1038
const message::Table::Index &index= table.indexes(x);
986
destination.append(",\n", 2);
1041
destination.append(",\n");
988
1043
result= transformIndexDefinitionToSql(index, table, destination, sql_variant);
994
1049
size_t num_foreign_keys= table.fk_constraint_size();
996
1051
if (num_foreign_keys > 0)
997
destination.append(",\n", 2);
1052
destination.append(",\n");
999
1054
for (size_t x= 0; x < num_foreign_keys; ++x)
1001
1056
const message::Table::ForeignKeyConstraint &fkey= table.fk_constraint(x);
1004
destination.append(",\n", 2);
1059
destination.append(",\n");
1006
1061
result= transformForeignKeyConstraintDefinitionToSql(fkey, table, destination, sql_variant);
1012
destination.append("\n)", 2);
1067
destination.append("\n)");
1014
1069
/* Add ENGINE = " clause */
1015
1070
if (table.has_engine())
1017
destination.append(" ENGINE=", 8);
1072
destination.append(" ENGINE=");
1018
1073
destination.append(table.engine().name());
1020
1075
size_t num_engine_options= table.engine().options_size();
1025
1080
const Engine::Option &option= table.engine().options(x);
1026
1081
destination.append(option.name());
1027
destination.append("='", 2);
1082
destination.append("='");
1028
1083
destination.append(option.state());
1029
destination.append("'", 1);
1030
if(x != num_engine_options-1)
1031
destination.append(", ", 2);
1084
destination.append("'");
1085
if (x != num_engine_options-1)
1087
destination.append(", ");
1035
1092
if (table.has_options())
1036
1093
(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.append(message::definer(table));
1049
1117
if (options.has_comment())
1051
destination.append(" COMMENT=", 9);
1119
destination.append(" COMMENT=");
1052
1120
append_escaped_string(&destination, options.comment());
1055
1123
if (options.has_collation())
1057
destination.append(" COLLATE = ", 11);
1125
destination.append(" COLLATE = ");
1058
1126
destination.append(options.collation());
1061
1129
if (options.has_data_file_name())
1063
destination.append("\nDATA_FILE_NAME = '", 19);
1131
destination.append("\nDATA_FILE_NAME = '");
1064
1132
destination.append(options.data_file_name());
1065
1133
destination.push_back('\'');
1068
1136
if (options.has_index_file_name())
1070
destination.append("\nINDEX_FILE_NAME = '", 20);
1138
destination.append("\nINDEX_FILE_NAME = '");
1071
1139
destination.append(options.index_file_name());
1072
1140
destination.push_back('\'');
1075
1143
if (options.has_max_rows())
1077
destination.append("\nMAX_ROWS = ", 12);
1145
destination.append("\nMAX_ROWS = ");
1078
1146
destination.append(boost::lexical_cast<string>(options.max_rows()));
1081
1149
if (options.has_min_rows())
1083
destination.append("\nMIN_ROWS = ", 12);
1151
destination.append("\nMIN_ROWS = ");
1084
1152
destination.append(boost::lexical_cast<string>(options.min_rows()));
1087
1155
if (options.has_user_set_auto_increment_value()
1088
1156
&& options.has_auto_increment_value())
1090
destination.append(" AUTO_INCREMENT=", 16);
1158
destination.append(" AUTO_INCREMENT=");
1091
1159
destination.append(boost::lexical_cast<string>(options.auto_increment_value()));
1094
1162
if (options.has_avg_row_length())
1096
destination.append("\nAVG_ROW_LENGTH = ", 18);
1164
destination.append("\nAVG_ROW_LENGTH = ");
1097
1165
destination.append(boost::lexical_cast<string>(options.avg_row_length()));
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);
1168
if (options.has_checksum() && options.checksum())
1169
destination.append("\nCHECKSUM = TRUE");
1171
if (options.has_page_checksum() && options.page_checksum())
1172
destination.append("\nPAGE_CHECKSUM = TRUE");
1120
1187
destination.append(" ", 2);
1122
1189
if (index.is_primary())
1123
destination.append("PRIMARY ", 8);
1190
destination.append("PRIMARY ");
1124
1191
else if (index.is_unique())
1125
destination.append("UNIQUE ", 7);
1192
destination.append("UNIQUE ");
1127
1194
destination.append("KEY ", 4);
1128
1195
if (! (index.is_primary() && index.name().compare("PRIMARY")==0))
1174
1241
case Table::Index::UNKNOWN_INDEX:
1176
1243
case Table::Index::BTREE:
1177
destination.append(" USING BTREE", 12);
1244
destination.append(" USING BTREE");
1179
1246
case Table::Index::RTREE:
1180
destination.append(" USING RTREE", 12);
1247
destination.append(" USING RTREE");
1182
1249
case Table::Index::HASH:
1183
destination.append(" USING HASH", 11);
1250
destination.append(" USING HASH");
1185
1252
case Table::Index::FULLTEXT:
1186
destination.append(" USING FULLTEXT", 15);
1253
destination.append(" USING FULLTEXT");
1190
1257
if (index.has_comment())
1192
destination.append(" COMMENT ", 9);
1259
destination.append(" COMMENT ");
1193
1260
append_escaped_string(&destination, index.comment());
1229
1296
if (sql_variant == ANSI)
1230
1297
quoted_identifier= '"';
1232
destination.append(" ", 2);
1299
destination.append(" ");
1234
1301
if (fkey.has_name())
1236
destination.append("CONSTRAINT ", 11);
1303
destination.append("CONSTRAINT ");
1237
1304
append_escaped_string(&destination, fkey.name(), quoted_identifier);
1238
1305
destination.append(" ", 1);
1241
destination.append("FOREIGN KEY (", 13);
1308
destination.append("FOREIGN KEY (");
1243
1310
for (ssize_t x= 0; x < fkey.column_names_size(); ++x)
1249
1316
quoted_identifier);
1252
destination.append(") REFERENCES ", 13);
1319
destination.append(") REFERENCES ");
1254
1321
append_escaped_string(&destination, fkey.references_table_name(),
1255
1322
quoted_identifier);
1256
destination.append(" (", 2);
1323
destination.append(" (");
1258
1325
for (ssize_t x= 0; x < fkey.references_columns_size(); ++x)
1269
1336
if (fkey.has_update_option() and fkey.update_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1271
destination.append(" ON UPDATE ", 11);
1338
destination.append(" ON UPDATE ");
1272
1339
transformForeignKeyOptionToSql(fkey.update_option(), destination);
1275
1342
if (fkey.has_delete_option() and fkey.delete_option() != Table::ForeignKeyConstraint::OPTION_UNDEF)
1277
destination.append(" ON DELETE ", 11);
1344
destination.append(" ON DELETE ");
1278
1345
transformForeignKeyOptionToSql(fkey.delete_option(), destination);
1319
1386
if (field.string_options().has_collation()
1320
1387
&& field.string_options().collation().compare("binary") == 0)
1321
destination.append(" VARBINARY(", 11);
1388
destination.append(" VARBINARY(");
1323
destination.append(" VARCHAR(", 9);
1390
destination.append(" VARCHAR(");
1325
1392
destination.append(boost::lexical_cast<string>(field.string_options().length()));
1326
1393
destination.append(")");
1331
1398
if (field.string_options().has_collation()
1332
1399
&& field.string_options().collation().compare("binary") == 0)
1333
destination.append(" BLOB", 5);
1400
destination.append(" BLOB");
1335
destination.append(" TEXT", 5);
1402
destination.append(" TEXT");
1338
1405
case Table::Field::ENUM:
1340
1407
size_t num_field_values= field.enumeration_values().field_value_size();
1341
destination.append(" ENUM(", 6);
1408
destination.append(" ENUM(");
1342
1409
for (size_t x= 0; x < num_field_values; ++x)
1344
1411
const string &type= field.enumeration_values().field_value(x);
1356
1423
case Table::Field::UUID:
1357
destination.append(" UUID", 5);
1424
destination.append(" UUID");
1426
case Table::Field::BOOLEAN:
1427
destination.append(" BOOLEAN");
1359
1429
case Table::Field::INTEGER:
1360
destination.append(" INT", 4);
1430
destination.append(" INT");
1362
1432
case Table::Field::BIGINT:
1363
destination.append(" BIGINT", 7);
1433
if (field.has_constraints() and
1434
field.constraints().is_unsigned())
1436
destination.append(" BIGINT UNSIGNED");
1440
destination.append(" BIGINT");
1365
1443
case Table::Field::DECIMAL:
1367
destination.append(" DECIMAL(", 9);
1445
destination.append(" DECIMAL(");
1368
1446
stringstream ss;
1369
1447
ss << field.numeric_options().precision() << ",";
1370
1448
ss << field.numeric_options().scale() << ")";
1374
1452
case Table::Field::DATE:
1375
destination.append(" DATE", 5);
1377
case Table::Field::TIMESTAMP:
1378
destination.append(" TIMESTAMP", 10);
1453
destination.append(" DATE");
1456
case Table::Field::EPOCH:
1457
if (field.time_options().microseconds())
1459
destination.append(" TIMESTAMP(6)");
1463
destination.append(" TIMESTAMP");
1380
1467
case Table::Field::DATETIME:
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);
1468
destination.append(" DATETIME");
1470
case Table::Field::TIME:
1471
destination.append(" TIME");
1396
1475
if (field.type() == Table::Field::BLOB ||
1399
1478
if (field.string_options().has_collation()
1400
1479
&& field.string_options().collation().compare("binary"))
1402
destination.append(" COLLATE ", 9);
1481
destination.append(" COLLATE ");
1403
1482
destination.append(field.string_options().collation());
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);
1486
if (field.has_constraints() and field.constraints().is_unique())
1488
destination.append(" UNIQUE");
1491
if (field.has_constraints() && field.constraints().is_notnull())
1493
destination.append(" NOT NULL");
1495
else if (field.type() == Table::Field::EPOCH)
1497
destination.append(" NULL");
1415
1500
if (field.type() == Table::Field::INTEGER ||
1416
1501
field.type() == Table::Field::BIGINT)
1419
1504
if (field.has_numeric_options() &&
1420
1505
field.numeric_options().is_autoincrement())
1422
destination.append(" AUTO_INCREMENT", 15);
1507
destination.append(" AUTO_INCREMENT");
1426
1511
if (field.options().has_default_value())
1428
destination.append(" DEFAULT ", 9);
1513
destination.append(" DEFAULT ");
1429
1514
append_escaped_string(&destination, field.options().default_value());
1431
1516
else if (field.options().has_default_expression())
1433
destination.append(" DEFAULT ", 9);
1518
destination.append(" DEFAULT ");
1434
1519
destination.append(field.options().default_expression());
1436
1521
else if (field.options().has_default_bin_value())
1438
1523
const string &v= field.options().default_bin_value();
1439
1524
if (v.length() == 0)
1440
destination.append(" DEFAULT ''", 11);
1526
destination.append(" DEFAULT ''");
1443
destination.append(" DEFAULT 0x", 11);
1530
destination.append(" DEFAULT 0x");
1444
1531
for (size_t x= 0; x < v.length(); x++)
1453
1540
&& field.options().default_null()
1454
1541
&& field.type() != Table::Field::BLOB)
1456
destination.append(" DEFAULT NULL", 13);
1543
destination.append(" DEFAULT NULL");
1459
1546
if (field.has_options() && field.options().has_update_expression())
1461
destination.append(" ON UPDATE ", 11);
1548
destination.append(" ON UPDATE ");
1462
1549
destination.append(field.options().update_expression());
1465
1552
if (field.has_comment())
1467
destination.append(" COMMENT ", 9);
1554
destination.append(" COMMENT ");
1468
1555
append_escaped_string(&destination, field.comment(), quoted_default);
1494
1581
case DRIZZLE_TYPE_NULL:
1495
1582
assert(false); /* Not a user definable type */
1496
1583
return Table::Field::INTEGER; /* unreachable */
1584
case DRIZZLE_TYPE_MICROTIME:
1497
1585
case DRIZZLE_TYPE_TIMESTAMP:
1498
return Table::Field::TIMESTAMP;
1586
return Table::Field::EPOCH;
1499
1587
case DRIZZLE_TYPE_LONGLONG:
1500
1588
return Table::Field::BIGINT;
1501
1589
case DRIZZLE_TYPE_DATETIME:
1502
1590
return Table::Field::DATETIME;
1591
case DRIZZLE_TYPE_TIME:
1592
return Table::Field::TIME;
1503
1593
case DRIZZLE_TYPE_DATE:
1504
1594
return Table::Field::DATE;
1505
1595
case DRIZZLE_TYPE_VARCHAR: