629
672
* up to a \0 being output here.
631
674
string raw_data(data.record(x).key_value(y));
632
destination->append(raw_data.c_str(), raw_data.size());
675
destination.append(raw_data.c_str(), raw_data.size());
636
destination->append(data.record(x).key_value(y));
679
destination.append(data.record(x).key_value(y));
639
682
if (should_quote_field_value)
640
destination->push_back('\'');
683
destination.push_back('\'');
642
685
if (num_key_fields > 1)
643
destination->push_back(')');
686
destination.push_back(')');
648
enum message::TransformSqlError
649
message::transformTruncateTableStatementToSql(const message::TruncateTableStatement &statement,
650
std::string *destination,
651
enum message::TransformSqlVariant sql_variant)
653
char quoted_identifier= '`';
654
if (sql_variant == ANSI)
655
quoted_identifier= '"';
657
const message::TableMetadata &table_metadata= statement.table_metadata();
659
destination->append("TRUNCATE TABLE ", 15);
660
destination->push_back(quoted_identifier);
661
destination->append(table_metadata.schema_name());
662
destination->push_back(quoted_identifier);
663
destination->push_back('.');
664
destination->push_back(quoted_identifier);
665
destination->append(table_metadata.table_name());
666
destination->push_back(quoted_identifier);
671
enum message::TransformSqlError
672
message::transformSetVariableStatementToSql(const message::SetVariableStatement &statement,
673
std::string *destination,
674
enum message::TransformSqlVariant sql_variant)
691
enum TransformSqlError
692
transformDropSchemaStatementToSql(const DropSchemaStatement &statement,
694
enum TransformSqlVariant sql_variant)
696
char quoted_identifier= '`';
697
if (sql_variant == ANSI)
698
quoted_identifier= '"';
700
destination.append("DROP SCHEMA ", 12);
701
destination.push_back(quoted_identifier);
702
destination.append(statement.schema_name());
703
destination.push_back(quoted_identifier);
708
enum TransformSqlError
709
transformCreateSchemaStatementToSql(const CreateSchemaStatement &statement,
711
enum TransformSqlVariant sql_variant)
713
char quoted_identifier= '`';
714
if (sql_variant == ANSI)
715
quoted_identifier= '"';
717
const Schema &schema= statement.schema();
719
destination.append("CREATE SCHEMA ", 14);
720
destination.push_back(quoted_identifier);
721
destination.append(schema.name());
722
destination.push_back(quoted_identifier);
724
if (schema.has_collation())
726
destination.append(" COLLATE ", 9);
727
destination.append(schema.collation());
733
enum TransformSqlError
734
transformDropTableStatementToSql(const DropTableStatement &statement,
736
enum TransformSqlVariant sql_variant)
738
char quoted_identifier= '`';
739
if (sql_variant == ANSI)
740
quoted_identifier= '"';
742
const TableMetadata &table_metadata= statement.table_metadata();
744
destination.append("DROP TABLE ", 11);
746
/* Add the IF EXISTS clause if necessary */
747
if (statement.has_if_exists_clause() &&
748
statement.if_exists_clause() == true)
750
destination.append("IF EXISTS ", 10);
753
destination.push_back(quoted_identifier);
754
destination.append(table_metadata.schema_name());
755
destination.push_back(quoted_identifier);
756
destination.push_back('.');
757
destination.push_back(quoted_identifier);
758
destination.append(table_metadata.table_name());
759
destination.push_back(quoted_identifier);
764
enum TransformSqlError
765
transformTruncateTableStatementToSql(const TruncateTableStatement &statement,
767
enum TransformSqlVariant sql_variant)
769
char quoted_identifier= '`';
770
if (sql_variant == ANSI)
771
quoted_identifier= '"';
773
const TableMetadata &table_metadata= statement.table_metadata();
775
destination.append("TRUNCATE TABLE ", 15);
776
destination.push_back(quoted_identifier);
777
destination.append(table_metadata.schema_name());
778
destination.push_back(quoted_identifier);
779
destination.push_back('.');
780
destination.push_back(quoted_identifier);
781
destination.append(table_metadata.table_name());
782
destination.push_back(quoted_identifier);
787
enum TransformSqlError
788
transformSetVariableStatementToSql(const SetVariableStatement &statement,
790
enum TransformSqlVariant sql_variant)
676
792
(void) sql_variant;
677
const message::FieldMetadata &variable_metadata= statement.variable_metadata();
678
bool should_quote_field_value= message::shouldQuoteFieldValue(variable_metadata.type());
680
destination->append("SET GLOBAL ", 11); /* Only global variables are replicated */
681
destination->append(variable_metadata.name());
682
destination->push_back('=');
684
if (should_quote_field_value)
685
destination->push_back('\'');
687
destination->append(statement.variable_value());
689
if (should_quote_field_value)
690
destination->push_back('\'');
695
bool message::shouldQuoteFieldValue(message::Table::Field::FieldType in_type)
793
const FieldMetadata &variable_metadata= statement.variable_metadata();
794
bool should_quote_field_value= shouldQuoteFieldValue(variable_metadata.type());
796
destination.append("SET GLOBAL ", 11); /* Only global variables are replicated */
797
destination.append(variable_metadata.name());
798
destination.push_back('=');
800
if (should_quote_field_value)
801
destination.push_back('\'');
803
destination.append(statement.variable_value());
805
if (should_quote_field_value)
806
destination.push_back('\'');
811
enum TransformSqlError
812
transformCreateTableStatementToSql(const CreateTableStatement &statement,
814
enum TransformSqlVariant sql_variant)
816
return transformTableDefinitionToSql(statement.table(), destination, sql_variant);
819
enum TransformSqlError
820
transformTableDefinitionToSql(const Table &table,
822
enum TransformSqlVariant sql_variant)
824
char quoted_identifier= '`';
825
if (sql_variant == ANSI)
826
quoted_identifier= '"';
828
destination.append("CREATE ", 7);
830
if (table.type() == Table::TEMPORARY)
831
destination.append("TEMPORARY ", 10);
833
destination.append("TABLE ", 6);
834
destination.push_back(quoted_identifier);
835
destination.append(table.name());
836
destination.push_back(quoted_identifier);
837
destination.append(" (\n", 3);
839
enum TransformSqlError result= NONE;
840
size_t num_fields= table.field_size();
841
for (size_t x= 0; x < num_fields; ++x)
843
const Table::Field &field= table.field(x);
846
destination.append(",\n", 2);
848
result= transformFieldDefinitionToSql(field, destination, sql_variant);
854
size_t num_indexes= table.indexes_size();
857
destination.append(",\n", 2);
859
for (size_t x= 0; x < num_indexes; ++x)
861
const message::Table::Index &index= table.indexes(x);
864
destination.append(",\n", 2);
866
result= transformIndexDefinitionToSql(index, table, destination, sql_variant);
871
destination.append("\n)", 2);
873
/* Add ENGINE = " clause */
874
if (table.has_engine())
876
const Table::StorageEngine &engine= table.engine();
877
destination.append("\nENGINE = ", 10);
878
destination.append(engine.name());
880
size_t num_engine_options= engine.option_size();
881
for (size_t x= 0; x < num_engine_options; ++x)
883
const Table::StorageEngine::EngineOption &option= engine.option(x);
884
destination.push_back('\n');
885
destination.append(option.option_name());
886
destination.append(" = ", 3);
887
destination.append(option.option_value());
888
destination.push_back('\n');
892
if (table.has_options())
893
(void) transformTableOptionsToSql(table.options(), destination, sql_variant);
898
enum TransformSqlError
899
transformTableOptionsToSql(const Table::TableOptions &options,
901
enum TransformSqlVariant sql_variant)
903
if (sql_variant == ANSI)
904
return NONE; /* ANSI does not support table options... */
908
if (options.has_comment())
910
destination.append("\nCOMMENT = '", 12);
911
destination.append(options.comment());
912
destination.push_back('\'');
915
if (options.has_collation())
917
destination.append("\nCOLLATE = ", 11);
918
destination.append(options.collation());
921
if (options.has_auto_increment())
923
ss << options.auto_increment();
924
destination.append("\nAUTOINCREMENT_OFFSET = ", 24);
925
destination.append(ss.str());
929
if (options.has_row_type())
931
ss << options.row_type();
932
destination.append("\nROW_TYPE = ", 12);
933
destination.append(ss.str());
937
if (options.has_data_file_name())
939
destination.append("\nDATA_FILE_NAME = '", 19);
940
destination.append(options.data_file_name());
941
destination.push_back('\'');
944
if (options.has_index_file_name())
946
destination.append("\nINDEX_FILE_NAME = '", 20);
947
destination.append(options.index_file_name());
948
destination.push_back('\'');
951
if (options.has_max_rows())
953
ss << options.max_rows();
954
destination.append("\nMAX_ROWS = ", 12);
955
destination.append(ss.str());
959
if (options.has_min_rows())
961
ss << options.min_rows();
962
destination.append("\nMIN_ROWS = ", 12);
963
destination.append(ss.str());
967
if (options.has_auto_increment_value())
969
ss << options.auto_increment_value();
970
destination.append("\nAUTO_INCREMENT = ", 18);
971
destination.append(ss.str());
975
if (options.has_avg_row_length())
977
ss << options.avg_row_length();
978
destination.append("\nAVG_ROW_LENGTH = ", 18);
979
destination.append(ss.str());
983
if (options.has_key_block_size())
985
ss << options.key_block_size();
986
destination.append("\nKEY_BLOCK_SIZE = ", 18);
987
destination.append(ss.str());
991
if (options.has_block_size())
993
ss << options.block_size();
994
destination.append("\nBLOCK_SIZE = ", 14);
995
destination.append(ss.str());
999
if (options.has_pack_keys() &&
1000
options.pack_keys())
1001
destination.append("\nPACK_KEYS = TRUE", 17);
1002
if (options.has_pack_record() &&
1003
options.pack_record())
1004
destination.append("\nPACK_RECORD = TRUE", 19);
1005
if (options.has_checksum() &&
1007
destination.append("\nCHECKSUM = TRUE", 16);
1008
if (options.has_page_checksum() &&
1009
options.page_checksum())
1010
destination.append("\nPAGE_CHECKSUM = TRUE", 21);
1015
enum TransformSqlError
1016
transformIndexDefinitionToSql(const Table::Index &index,
1018
string &destination,
1019
enum TransformSqlVariant sql_variant)
1021
char quoted_identifier= '`';
1022
if (sql_variant == ANSI)
1023
quoted_identifier= '"';
1025
if (index.is_primary())
1026
destination.append("PRIMARY ", 8);
1027
else if (index.is_unique())
1028
destination.append("UNIQUE ", 7);
1030
destination.append("KEY ", 4);
1031
destination.push_back(quoted_identifier);
1032
destination.append(index.name());
1033
destination.push_back(quoted_identifier);
1034
destination.append(" (", 2);
1036
size_t num_parts= index.index_part_size();
1037
for (size_t x= 0; x < num_parts; ++x)
1039
const Table::Index::IndexPart &part= index.index_part(x);
1040
const Table::Field &field= table.field(part.fieldnr());
1043
destination.push_back(',');
1045
destination.push_back(quoted_identifier);
1046
destination.append(field.name());
1047
destination.push_back(quoted_identifier);
1050
* If the index part's field type is VARCHAR or TEXT
1051
* then check for a prefix length then is different
1052
* from the field's full length...
1054
if (field.type() == Table::Field::VARCHAR ||
1055
field.type() == Table::Field::BLOB)
1057
if (part.has_compare_length())
1059
size_t compare_length_in_chars= part.compare_length();
1061
/* hack: compare_length() is bytes, not chars, but
1062
* only for VARCHAR. Ass. */
1063
if (field.type() == Table::Field::VARCHAR)
1064
compare_length_in_chars/= 4;
1066
if (compare_length_in_chars != field.string_options().length())
1069
destination.push_back('(');
1070
ss << compare_length_in_chars;
1071
destination.append(ss.str());
1072
destination.push_back(')');
1077
destination.push_back(')');
1082
enum TransformSqlError
1083
transformFieldDefinitionToSql(const Table::Field &field,
1084
string &destination,
1085
enum TransformSqlVariant sql_variant)
1087
char quoted_identifier= '`';
1088
if (sql_variant == ANSI)
1089
quoted_identifier= '"';
1091
destination.push_back(quoted_identifier);
1092
destination.append(field.name());
1093
destination.push_back(quoted_identifier);
1095
Table::Field::FieldType field_type= field.type();
1099
case Table::Field::DOUBLE:
1100
destination.append(" DOUBLE", 7);
1102
case Table::Field::VARCHAR:
1104
destination.append(" VARCHAR(", 9);
1106
ss << field.string_options().length() << ")";
1107
destination.append(ss.str());
1110
case Table::Field::BLOB:
1111
destination.append(" BLOB", 5);
1113
case Table::Field::ENUM:
1115
size_t num_field_values= field.set_options().field_value_size();
1116
destination.append(" ENUM(", 6);
1117
for (size_t x= 0; x < num_field_values; ++x)
1119
const string &type= field.set_options().field_value(x);
1122
destination.push_back(',');
1124
destination.push_back('\'');
1125
destination.append(type);
1126
destination.push_back('\'');
1128
destination.push_back(')');
1131
case Table::Field::INTEGER:
1132
destination.append(" INT", 4);
1134
case Table::Field::BIGINT:
1135
destination.append(" BIGINT", 7);
1137
case Table::Field::DECIMAL:
1139
destination.append(" DECIMAL(", 9);
1141
ss << field.numeric_options().precision() << ",";
1142
ss << field.numeric_options().scale() << ")";
1143
destination.append(ss.str());
1146
case Table::Field::DATE:
1147
destination.append(" DATE", 5);
1149
case Table::Field::TIMESTAMP:
1150
destination.append(" TIMESTAMP", 10);
1152
case Table::Field::DATETIME:
1153
destination.append(" DATETIME", 9);
1157
if (field.type() == Table::Field::INTEGER ||
1158
field.type() == Table::Field::BIGINT)
1160
if (field.has_constraints() &&
1161
field.constraints().has_is_unsigned() &&
1162
field.constraints().is_unsigned())
1164
destination.append(" UNSIGNED", 9);
1169
if (! (field.has_constraints() &&
1170
field.constraints().is_nullable()))
1172
destination.append(" NOT", 4);
1174
destination.append(" NULL", 5);
1176
if (field.type() == Table::Field::INTEGER ||
1177
field.type() == Table::Field::BIGINT)
1179
/* AUTO_INCREMENT must be after NOT NULL */
1180
if (field.has_numeric_options() &&
1181
field.numeric_options().is_autoincrement())
1183
destination.append(" AUTO_INCREMENT", 15);
1187
if (field.type() == Table::Field::BLOB ||
1188
field.type() == Table::Field::VARCHAR)
1190
if (field.string_options().has_collation())
1192
destination.append(" COLLATE ", 9);
1193
destination.append(field.string_options().collation());
1197
if (field.options().has_default_value())
1199
destination.append(" DEFAULT ", 9);
1200
destination.push_back(quoted_identifier);
1201
destination.append(field.options().default_value());
1202
destination.push_back(quoted_identifier);
1205
if (field.options().has_default_bin_value())
1207
const string &v= field.options().default_bin_value();
1208
destination.append(" DEFAULT 0x", 11);
1209
for (size_t x= 0; x < v.length(); x++)
1211
printf("%.2x", *(v.c_str() + x));
1215
if (field.type() == Table::Field::TIMESTAMP)
1216
if (field.timestamp_options().has_auto_updates() &&
1217
field.timestamp_options().auto_updates())
1218
destination.append(" ON UPDATE CURRENT_TIMESTAMP", 28);
1220
if (field.has_comment())
1222
destination.append(" COMMENT ", 9);
1223
destination.push_back(quoted_identifier);
1224
destination.append(field.comment());
1225
destination.push_back(quoted_identifier);
1230
bool shouldQuoteFieldValue(Table::Field::FieldType in_type)
697
1232
switch (in_type)
699
case message::Table::Field::DOUBLE:
700
case message::Table::Field::DECIMAL:
701
case message::Table::Field::INTEGER:
702
case message::Table::Field::BIGINT:
703
case message::Table::Field::ENUM:
1234
case Table::Field::DOUBLE:
1235
case Table::Field::DECIMAL:
1236
case Table::Field::INTEGER:
1237
case Table::Field::BIGINT:
1238
case Table::Field::ENUM:
710
drizzled::message::Table::Field::FieldType message::internalFieldTypeToFieldProtoType(enum enum_field_types type)
1245
Table::Field::FieldType internalFieldTypeToFieldProtoType(enum enum_field_types type)
713
1248
case DRIZZLE_TYPE_LONG:
714
return message::Table::Field::INTEGER;
1249
return Table::Field::INTEGER;
715
1250
case DRIZZLE_TYPE_DOUBLE:
716
return message::Table::Field::DOUBLE;
1251
return Table::Field::DOUBLE;
717
1252
case DRIZZLE_TYPE_NULL:
718
1253
assert(false); /* Not a user definable type */
719
return message::Table::Field::INTEGER; /* unreachable */
1254
return Table::Field::INTEGER; /* unreachable */
720
1255
case DRIZZLE_TYPE_TIMESTAMP:
721
return message::Table::Field::TIMESTAMP;
1256
return Table::Field::TIMESTAMP;
722
1257
case DRIZZLE_TYPE_LONGLONG:
723
return message::Table::Field::BIGINT;
1258
return Table::Field::BIGINT;
724
1259
case DRIZZLE_TYPE_DATETIME:
725
return message::Table::Field::DATETIME;
1260
return Table::Field::DATETIME;
726
1261
case DRIZZLE_TYPE_DATE:
727
return message::Table::Field::DATE;
1262
return Table::Field::DATE;
728
1263
case DRIZZLE_TYPE_VARCHAR:
729
return message::Table::Field::VARCHAR;
1264
return Table::Field::VARCHAR;
730
1265
case DRIZZLE_TYPE_DECIMAL:
731
return message::Table::Field::DECIMAL;
1266
return Table::Field::DECIMAL;
732
1267
case DRIZZLE_TYPE_ENUM:
733
return message::Table::Field::ENUM;
1268
return Table::Field::ENUM;
734
1269
case DRIZZLE_TYPE_BLOB:
735
return message::Table::Field::BLOB;
1270
return Table::Field::BLOB;
739
return message::Table::Field::INTEGER; /* unreachable */
1274
return Table::Field::INTEGER; /* unreachable */
1277
} /* namespace message */
742
1278
} /* namespace drizzled */