~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to client/mysqldump.c

  • Committer: Brian Aker
  • Date: 2008-07-03 00:14:39 UTC
  • Revision ID: brian@tangent.org-20080703001439-pit0mcl0wk8elxlq
Cleanup of sql-common and mysqldump

Show diffs side-by-side

added added

removed removed

Lines of Context:
80
80
                             const char *option_value);
81
81
static ulong find_set(TYPELIB *lib, const char *x, uint length,
82
82
                      char **err_pos, uint *err_len);
83
 
static char *alloc_query_str(ulong size);
84
83
 
85
84
static void field_escape(DYNAMIC_STRING* in, const char *from);
86
85
static my_bool  verbose= 0, opt_no_create_info= 0, opt_no_data= 0,
124
123
static uint opt_mysql_port= 0, opt_master_data;
125
124
static uint opt_slave_data;
126
125
static uint my_end_arg;
127
 
static char * opt_mysql_unix_port=0;
128
126
static int   first_error=0;
129
127
static DYNAMIC_STRING extended_row;
130
128
FILE *md_result_file= 0;
133
131
#ifdef HAVE_SMEM
134
132
static char *shared_memory_base_name=0;
135
133
#endif
136
 
static uint opt_protocol= 0;
 
134
static uint opt_protocol= MYSQL_PROTOCOL_TCP;
137
135
 
138
136
/*
139
137
Dynamic_string wrapper functions. In this file use these
403
401
  {"port", 'P', "Port number to use for connection.", (uchar**) &opt_mysql_port,
404
402
   (uchar**) &opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0,
405
403
   0},
406
 
  {"protocol", OPT_MYSQL_PROTOCOL, "The protocol of connection (tcp,socket,pipe,memory).",
407
 
   0, 0, 0, GET_STR,  REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
408
404
  {"quick", 'q', "Don't buffer query, dump directly to stdout.",
409
405
   (uchar**) &quick, (uchar**) &quick, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
410
406
  {"quote-names",'Q', "Quote table and column names with backticks (`).",
454
450
  {"skip-opt", OPT_SKIP_OPTIMIZATION,
455
451
   "Disable --opt. Disables --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys.",
456
452
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
457
 
  {"socket", 'S', "Socket file to use for connection.",
458
 
   (uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR,
459
 
   REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
460
453
  {"tab",'T',
461
454
   "Creates tab separated textfile for each table to given path. (creates .sql and .txt files). NOTE: This only works if mysqldump is run on the same machine as the mysqld daemon.",
462
455
   (uchar**) &path, (uchar**) &path, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
492
485
                        int string_value);
493
486
static int dump_selected_tables(char *db, char **table_names, int tables);
494
487
static int dump_all_tables_in_db(char *db);
495
 
static int init_dumping_views(char *);
496
488
static int init_dumping_tables(char *);
497
489
static int init_dumping(char *, int init_func(char*));
498
490
static int dump_databases(char **);
500
492
static char *quote_name(const char *name, char *buff, my_bool force);
501
493
char check_if_ignore_table(const char *table_name, char *table_type);
502
494
static char *primary_key_fields(const char *table_name);
503
 
static my_bool get_view_structure(char *table, char* db);
504
 
static my_bool dump_all_views_in_db(char *database);
505
 
static int dump_all_tablespaces();
506
 
static int dump_tablespaces_for_tables(char *db, char **table_names, int tables);
507
 
static int dump_tablespaces_for_databases(char** databases);
508
 
static int dump_tablespaces(char* ts_where);
509
495
 
510
496
#include <help_start.h>
511
497
 
838
824
        default_charset= (char*) MYSQL_DEFAULT_CHARSET_NAME;
839
825
      break;
840
826
    }
841
 
  case (int) OPT_MYSQL_PROTOCOL:
842
 
    opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
843
 
                                    opt->name);
844
 
    break;
845
827
  }
846
828
  return 0;
847
829
}
1054
1036
}
1055
1037
 
1056
1038
 
1057
 
static int fetch_db_collation(const char *db_name,
1058
 
                              char *db_cl_name,
1059
 
                              int db_cl_size)
1060
 
{
1061
 
  my_bool err_status= FALSE;
1062
 
  char query[QUERY_LENGTH];
1063
 
  MYSQL_RES *db_cl_res;
1064
 
  MYSQL_ROW db_cl_row;
1065
 
  char quoted_database_buf[NAME_LEN*2+3];
1066
 
  char *qdatabase= quote_name(db_name, quoted_database_buf, 1);
1067
 
 
1068
 
  my_snprintf(query, sizeof (query), "use %s", qdatabase);
1069
 
 
1070
 
  if (mysql_query_with_error_report(mysql, NULL, query))
1071
 
    return 1;
1072
 
 
1073
 
  if (mysql_query_with_error_report(mysql, &db_cl_res,
1074
 
                                    "select @@collation_database"))
1075
 
    return 1;
1076
 
 
1077
 
  do
1078
 
  {
1079
 
    if (mysql_num_rows(db_cl_res) != 1)
1080
 
    {
1081
 
      err_status= TRUE;
1082
 
      break;
1083
 
    }
1084
 
 
1085
 
    if (!(db_cl_row= mysql_fetch_row(db_cl_res)))
1086
 
    {
1087
 
      err_status= TRUE;
1088
 
      break;
1089
 
    }
1090
 
 
1091
 
    strncpy(db_cl_name, db_cl_row[0], db_cl_size);
1092
 
    db_cl_name[db_cl_size - 1]= 0; /* just in case. */
1093
 
 
1094
 
  } while (FALSE);
1095
 
 
1096
 
  mysql_free_result(db_cl_res);
1097
 
 
1098
 
  return err_status ? 1 : 0;
1099
 
}
1100
 
 
1101
 
 
1102
 
static char *my_case_str(const char *str,
1103
 
                         uint str_len,
1104
 
                         const char *token,
1105
 
                         uint token_len)
1106
 
{
1107
 
  my_match_t match;
1108
 
 
1109
 
  uint status= my_charset_latin1.coll->instr(&my_charset_latin1,
1110
 
                                             str, str_len,
1111
 
                                             token, token_len,
1112
 
                                             &match, 1);
1113
 
 
1114
 
  return status ? (char *) str + match.end : NULL;
1115
 
}
1116
 
 
1117
 
 
1118
 
static int switch_db_collation(FILE *sql_file,
1119
 
                               const char *db_name,
1120
 
                               const char *delimiter,
1121
 
                               const char *current_db_cl_name,
1122
 
                               const char *required_db_cl_name,
1123
 
                               int *db_cl_altered)
1124
 
{
1125
 
  if (strcmp(current_db_cl_name, required_db_cl_name) != 0)
1126
 
  {
1127
 
    CHARSET_INFO *db_cl= get_charset_by_name(required_db_cl_name, MYF(0));
1128
 
 
1129
 
    if (!db_cl)
1130
 
      return 1;
1131
 
 
1132
 
    fprintf(sql_file,
1133
 
            "ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
1134
 
            (const char *) db_name,
1135
 
            (const char *) db_cl->csname,
1136
 
            (const char *) db_cl->name,
1137
 
            (const char *) delimiter);
1138
 
 
1139
 
    *db_cl_altered= 1;
1140
 
 
1141
 
    return 0;
1142
 
  }
1143
 
 
1144
 
  *db_cl_altered= 0;
1145
 
 
1146
 
  return 0;
1147
 
}
1148
 
 
1149
 
 
1150
 
static int restore_db_collation(FILE *sql_file,
1151
 
                                const char *db_name,
1152
 
                                const char *delimiter,
1153
 
                                const char *db_cl_name)
1154
 
{
1155
 
  CHARSET_INFO *db_cl= get_charset_by_name(db_cl_name, MYF(0));
1156
 
 
1157
 
  if (!db_cl)
1158
 
    return 1;
1159
 
 
1160
 
  fprintf(sql_file,
1161
 
          "ALTER DATABASE %s CHARACTER SET %s COLLATE %s %s\n",
1162
 
          (const char *) db_name,
1163
 
          (const char *) db_cl->csname,
1164
 
          (const char *) db_cl->name,
1165
 
          (const char *) delimiter);
1166
 
 
1167
 
  return 0;
1168
 
}
1169
 
 
1170
 
 
1171
 
static void switch_cs_variables(FILE *sql_file,
1172
 
                                const char *delimiter,
1173
 
                                const char *character_set_client,
1174
 
                                const char *character_set_results,
1175
 
                                const char *collation_connection)
1176
 
{
1177
 
  fprintf(sql_file,
1178
 
          "/*!50003 SET @saved_cs_client      = @@character_set_client */ %s\n"
1179
 
          "/*!50003 SET @saved_cs_results     = @@character_set_results */ %s\n"
1180
 
          "/*!50003 SET @saved_col_connection = @@collation_connection */ %s\n"
1181
 
          "/*!50003 SET character_set_client  = %s */ %s\n"
1182
 
          "/*!50003 SET character_set_results = %s */ %s\n"
1183
 
          "/*!50003 SET collation_connection  = %s */ %s\n",
1184
 
          (const char *) delimiter,
1185
 
          (const char *) delimiter,
1186
 
          (const char *) delimiter,
1187
 
 
1188
 
          (const char *) character_set_client,
1189
 
          (const char *) delimiter,
1190
 
 
1191
 
          (const char *) character_set_results,
1192
 
          (const char *) delimiter,
1193
 
 
1194
 
          (const char *) collation_connection,
1195
 
          (const char *) delimiter);
1196
 
}
1197
 
 
1198
 
 
1199
 
static void restore_cs_variables(FILE *sql_file,
1200
 
                                 const char *delimiter)
1201
 
{
1202
 
  fprintf(sql_file,
1203
 
          "/*!50003 SET character_set_client  = @saved_cs_client */ %s\n"
1204
 
          "/*!50003 SET character_set_results = @saved_cs_results */ %s\n"
1205
 
          "/*!50003 SET collation_connection  = @saved_col_connection */ %s\n",
1206
 
          (const char *) delimiter,
1207
 
          (const char *) delimiter,
1208
 
          (const char *) delimiter);
1209
 
}
1210
 
 
1211
 
 
1212
 
static void switch_sql_mode(FILE *sql_file,
1213
 
                            const char *delimiter,
1214
 
                            const char *sql_mode)
1215
 
{
1216
 
  fprintf(sql_file,
1217
 
          "/*!50003 SET @saved_sql_mode       = @@sql_mode */ %s\n"
1218
 
          "/*!50003 SET sql_mode              = '%s' */ %s\n",
1219
 
          (const char *) delimiter,
1220
 
 
1221
 
          (const char *) sql_mode,
1222
 
          (const char *) delimiter);
1223
 
}
1224
 
 
1225
 
 
1226
 
static void restore_sql_mode(FILE *sql_file,
1227
 
                             const char *delimiter)
1228
 
{
1229
 
  fprintf(sql_file,
1230
 
          "/*!50003 SET sql_mode              = @saved_sql_mode */ %s\n",
1231
 
          (const char *) delimiter);
1232
 
}
1233
 
 
1234
 
 
1235
 
static void switch_time_zone(FILE *sql_file,
1236
 
                             const char *delimiter,
1237
 
                             const char *time_zone)
1238
 
{
1239
 
  fprintf(sql_file,
1240
 
          "/*!50003 SET @saved_time_zone      = @@time_zone */ %s\n"
1241
 
          "/*!50003 SET time_zone             = '%s' */ %s\n",
1242
 
          (const char *) delimiter,
1243
 
 
1244
 
          (const char *) time_zone,
1245
 
          (const char *) delimiter);
1246
 
}
1247
 
 
1248
 
 
1249
 
static void restore_time_zone(FILE *sql_file,
1250
 
                              const char *delimiter)
1251
 
{
1252
 
  fprintf(sql_file,
1253
 
          "/*!50003 SET time_zone             = @saved_time_zone */ %s\n",
1254
 
          (const char *) delimiter);
1255
 
}
1256
 
 
1257
 
 
1258
1039
/**
1259
1040
  Switch charset for results to some specified charset.  If the server does not
1260
1041
  support character_set_results variable, nothing can be done here.  As for
1284
1065
  return mysql_real_query(mysql, query_buffer, query_length);
1285
1066
}
1286
1067
 
1287
 
/**
1288
 
  Rewrite CREATE FUNCTION or CREATE PROCEDURE statement, enclosing DEFINER
1289
 
  clause in version-specific comment.
1290
 
 
1291
 
  This function parses the CREATE FUNCTION | PROCEDURE statement and
1292
 
  encloses DEFINER-clause in version-specific comment:
1293
 
    input query:     CREATE DEFINER=a@b FUNCTION ...
1294
 
    rewritten query: CREATE * / / *!50020 DEFINER=a@b * / / *!50003 FUNCTION ...
1295
 
 
1296
 
  @note This function will go away when WL#3995 is implemented.
1297
 
 
1298
 
  @param[in] def_str        CREATE FUNCTION|PROCEDURE statement string.
1299
 
  @param[in] def_str_length length of the def_str.
1300
 
 
1301
 
  @return pointer to the new allocated query string.
1302
 
*/
1303
 
 
1304
 
static char *cover_definer_clause_in_sp(const char *def_str,
1305
 
                                        uint def_str_length)
1306
 
{
1307
 
  char *query_str= NULL;
1308
 
  char *definer_begin= my_case_str(def_str, def_str_length,
1309
 
                                   C_STRING_WITH_LEN(" DEFINER"));
1310
 
  char *definer_end;
1311
 
 
1312
 
  if (!definer_begin)
1313
 
    return NULL;
1314
 
 
1315
 
  definer_end= my_case_str(definer_begin, strlen(definer_begin),
1316
 
                           C_STRING_WITH_LEN(" PROCEDURE"));
1317
 
 
1318
 
  if (!definer_end)
1319
 
  {
1320
 
    definer_end= my_case_str(definer_begin, strlen(definer_begin),
1321
 
                             C_STRING_WITH_LEN(" FUNCTION"));
1322
 
  }
1323
 
 
1324
 
  if (definer_end)
1325
 
  {
1326
 
    char *query_str_tail;
1327
 
 
1328
 
    /*
1329
 
      Allocate memory for new query string: original string
1330
 
      from SHOW statement and version-specific comments.
1331
 
    */
1332
 
    query_str= alloc_query_str(def_str_length + 23);
1333
 
 
1334
 
    query_str_tail= strnmov(query_str, def_str, definer_begin - def_str);
1335
 
    query_str_tail= strmov(query_str_tail, "*/ /*!50020");
1336
 
    query_str_tail= strnmov(query_str_tail, definer_begin,
1337
 
                            definer_end - definer_begin);
1338
 
    query_str_tail= strxmov(query_str_tail, "*/ /*!50003",
1339
 
                            definer_end, NullS);
1340
 
  }
1341
 
 
1342
 
  return query_str;
1343
 
}
1344
 
 
1345
1068
/*
1346
1069
  Open a new .sql file to dump the table or view into
1347
1070
 
1415
1138
#endif
1416
1139
  mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset);
1417
1140
  if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd,
1418
 
                                  NULL,opt_mysql_port,opt_mysql_unix_port,
 
1141
                                  NULL,opt_mysql_port, NULL,
1419
1142
                                  0)))
1420
1143
  {
1421
1144
    DB_error(&mysql_connection, "when trying to connect");
1746
1469
 
1747
1470
 
1748
1471
/*
1749
 
 create_delimiter
1750
 
 Generate a new (null-terminated) string that does not exist in  query 
1751
 
 and is therefore suitable for use as a query delimiter.  Store this
1752
 
 delimiter in  delimiter_buff .
1753
 
 
1754
 
 This is quite simple in that it doesn't even try to parse statements as an
1755
 
 interpreter would.  It merely returns a string that is not in the query, which
1756
 
 is much more than adequate for constructing a delimiter.
1757
 
 
1758
 
 RETURN
1759
 
   ptr to the delimiter  on Success
1760
 
   NULL                  on Failure
1761
 
*/
1762
 
static char *create_delimiter(char *query, char *delimiter_buff, 
1763
 
                              int delimiter_max_size) 
1764
 
{
1765
 
  int proposed_length;
1766
 
  char *presence;
1767
 
 
1768
 
  delimiter_buff[0]= ';';  /* start with one semicolon, and */
1769
 
 
1770
 
  for (proposed_length= 2; proposed_length < delimiter_max_size; 
1771
 
      delimiter_max_size++) {
1772
 
 
1773
 
    delimiter_buff[proposed_length-1]= ';';  /* add semicolons, until */
1774
 
    delimiter_buff[proposed_length]= '\0';
1775
 
 
1776
 
    presence = strstr(query, delimiter_buff);
1777
 
    if (presence == NULL) { /* the proposed delimiter is not in the query. */
1778
 
       return delimiter_buff;
1779
 
    }
1780
 
 
1781
 
  }
1782
 
  return NULL;  /* but if we run out of space, return nothing at all. */
1783
 
}
1784
 
 
1785
 
 
1786
 
/*
1787
 
  dump_events_for_db
1788
 
  -- retrieves list of events for a given db, and prints out
1789
 
  the CREATE EVENT statement into the output (the dump).
1790
 
 
1791
 
  RETURN
1792
 
    0  Success
1793
 
    1  Error
1794
 
*/
1795
 
static uint dump_events_for_db(char *db)
1796
 
{
1797
 
  char       query_buff[QUERY_LENGTH];
1798
 
  char       db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
1799
 
  char       *event_name;
1800
 
  char       delimiter[QUERY_LENGTH];
1801
 
  FILE       *sql_file= md_result_file;
1802
 
  MYSQL_RES  *event_res, *event_list_res;
1803
 
  MYSQL_ROW  row, event_list_row;
1804
 
 
1805
 
  char       db_cl_name[MY_CS_NAME_SIZE];
1806
 
  int        db_cl_altered= FALSE;
1807
 
 
1808
 
  DBUG_ENTER("dump_events_for_db");
1809
 
  DBUG_PRINT("enter", ("db: '%s'", db));
1810
 
 
1811
 
  mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
1812
 
 
1813
 
  /* nice comments */
1814
 
  if (opt_comments)
1815
 
    fprintf(sql_file, "\n--\n-- Dumping events for database '%s'\n--\n", db);
1816
 
 
1817
 
  /*
1818
 
    not using "mysql_query_with_error_report" because we may have not
1819
 
    enough privileges to lock mysql.events.
1820
 
  */
1821
 
  if (lock_tables)
1822
 
    mysql_query(mysql, "LOCK TABLES mysql.event READ");
1823
 
 
1824
 
  if (mysql_query_with_error_report(mysql, &event_list_res, "show events"))
1825
 
    DBUG_RETURN(0);
1826
 
 
1827
 
  strcpy(delimiter, ";");
1828
 
  if (mysql_num_rows(event_list_res) > 0)
1829
 
  {
1830
 
    fprintf(sql_file, "/*!50106 SET @save_time_zone= @@TIME_ZONE */ ;\n");
1831
 
 
1832
 
    /* Get database collation. */
1833
 
 
1834
 
    if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name)))
1835
 
      DBUG_RETURN(1);
1836
 
 
1837
 
    if (switch_character_set_results(mysql, "binary"))
1838
 
      DBUG_RETURN(1);
1839
 
 
1840
 
    while ((event_list_row= mysql_fetch_row(event_list_res)) != NULL)
1841
 
    {
1842
 
      event_name= quote_name(event_list_row[1], name_buff, 0);
1843
 
      DBUG_PRINT("info", ("retrieving CREATE EVENT for %s", name_buff));
1844
 
      my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE EVENT %s", 
1845
 
          event_name);
1846
 
 
1847
 
      if (mysql_query_with_error_report(mysql, &event_res, query_buff))
1848
 
        DBUG_RETURN(1);
1849
 
 
1850
 
      while ((row= mysql_fetch_row(event_res)) != NULL)
1851
 
      {
1852
 
        /*
1853
 
          if the user has EXECUTE privilege he can see event names, but not the
1854
 
          event body!
1855
 
        */
1856
 
        if (strlen(row[3]) != 0)
1857
 
        {
1858
 
          if (opt_drop)
1859
 
            fprintf(sql_file, "/*!50106 DROP EVENT IF EXISTS %s */%s\n", 
1860
 
                event_name, delimiter);
1861
 
 
1862
 
          if (create_delimiter(row[3], delimiter, sizeof(delimiter)) == NULL)
1863
 
          {
1864
 
            fprintf(stderr, "%s: Warning: Can't create delimiter for event '%s'\n",
1865
 
                    my_progname, event_name);
1866
 
            DBUG_RETURN(1);
1867
 
          }
1868
 
 
1869
 
          fprintf(sql_file, "DELIMITER %s\n", delimiter);
1870
 
 
1871
 
          if (mysql_num_fields(event_res) >= 7)
1872
 
          {
1873
 
            if (switch_db_collation(sql_file, db_name_buff, delimiter,
1874
 
                                    db_cl_name, row[6], &db_cl_altered))
1875
 
            {
1876
 
              DBUG_RETURN(1);
1877
 
            }
1878
 
 
1879
 
            switch_cs_variables(sql_file, delimiter,
1880
 
                                row[4],   /* character_set_client */
1881
 
                                row[4],   /* character_set_results */
1882
 
                                row[5]);  /* collation_connection */
1883
 
          }
1884
 
            else
1885
 
            {
1886
 
              /*
1887
 
                mysqldump is being run against the server, that does not
1888
 
                provide character set information in SHOW CREATE
1889
 
                statements.
1890
 
 
1891
 
                NOTE: the dump may be incorrect, since character set
1892
 
                information is required in order to restore event properly.
1893
 
              */
1894
 
 
1895
 
              fprintf(sql_file,
1896
 
                      "--\n"
1897
 
                      "-- WARNING: old server version. "
1898
 
                        "The following dump may be incomplete.\n"
1899
 
                      "--\n");
1900
 
            }
1901
 
 
1902
 
          switch_sql_mode(sql_file, delimiter, row[1]);
1903
 
 
1904
 
          switch_time_zone(sql_file, delimiter, row[2]);
1905
 
 
1906
 
          fprintf(sql_file,
1907
 
                  "/*!50106 %s */ %s\n",
1908
 
                  (const char *) row[3],
1909
 
                  (const char *) delimiter);
1910
 
 
1911
 
          restore_time_zone(sql_file, delimiter);
1912
 
          restore_sql_mode(sql_file, delimiter);
1913
 
 
1914
 
          if (mysql_num_fields(event_res) >= 7)
1915
 
          {
1916
 
            restore_cs_variables(sql_file, delimiter);
1917
 
 
1918
 
            if (db_cl_altered)
1919
 
            {
1920
 
              if (restore_db_collation(sql_file, db_name_buff, delimiter,
1921
 
                                       db_cl_name))
1922
 
                DBUG_RETURN(1);
1923
 
            }
1924
 
          }
1925
 
        }
1926
 
      } /* end of event printing */
1927
 
      mysql_free_result(event_res);
1928
 
 
1929
 
    } /* end of list of events */
1930
 
    fprintf(sql_file, "DELIMITER ;\n");
1931
 
    fprintf(sql_file, "/*!50106 SET TIME_ZONE= @save_time_zone */ ;\n");
1932
 
 
1933
 
    if (switch_character_set_results(mysql, default_charset))
1934
 
      DBUG_RETURN(1);
1935
 
  }
1936
 
  mysql_free_result(event_list_res);
1937
 
 
1938
 
  if (lock_tables)
1939
 
    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
1940
 
  DBUG_RETURN(0);
1941
 
}
1942
 
 
1943
 
 
1944
 
/*
1945
1472
  Print hex value for blob data.
1946
1473
 
1947
1474
  SYNOPSIS
1964
1491
}
1965
1492
 
1966
1493
/*
1967
 
  dump_routines_for_db
1968
 
  -- retrieves list of routines for a given db, and prints out
1969
 
  the CREATE PROCEDURE definition into the output (the dump).
1970
 
 
1971
 
  This function has logic to print the appropriate syntax depending on whether
1972
 
  this is a procedure or functions
1973
 
 
1974
 
  RETURN
1975
 
    0  Success
1976
 
    1  Error
1977
 
*/
1978
 
 
1979
 
static uint dump_routines_for_db(char *db)
1980
 
{
1981
 
  char       query_buff[QUERY_LENGTH];
1982
 
  const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
1983
 
  char       db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
1984
 
  char       *routine_name;
1985
 
  int        i;
1986
 
  FILE       *sql_file= md_result_file;
1987
 
  MYSQL_RES  *routine_res, *routine_list_res;
1988
 
  MYSQL_ROW  row, routine_list_row;
1989
 
 
1990
 
  char       db_cl_name[MY_CS_NAME_SIZE];
1991
 
  int        db_cl_altered= FALSE;
1992
 
 
1993
 
  DBUG_ENTER("dump_routines_for_db");
1994
 
  DBUG_PRINT("enter", ("db: '%s'", db));
1995
 
 
1996
 
  mysql_real_escape_string(mysql, db_name_buff, db, strlen(db));
1997
 
 
1998
 
  /* nice comments */
1999
 
  if (opt_comments)
2000
 
    fprintf(sql_file, "\n--\n-- Dumping routines for database '%s'\n--\n", db);
2001
 
 
2002
 
  /*
2003
 
    not using "mysql_query_with_error_report" because we may have not
2004
 
    enough privileges to lock mysql.proc.
2005
 
  */
2006
 
  if (lock_tables)
2007
 
    mysql_query(mysql, "LOCK TABLES mysql.proc READ");
2008
 
 
2009
 
  /* Get database collation. */
2010
 
 
2011
 
  if (fetch_db_collation(db_name_buff, db_cl_name, sizeof (db_cl_name)))
2012
 
    DBUG_RETURN(1);
2013
 
 
2014
 
  if (switch_character_set_results(mysql, "binary"))
2015
 
    DBUG_RETURN(1);
2016
 
 
2017
 
  /* 0, retrieve and dump functions, 1, procedures */
2018
 
  for (i= 0; i <= 1; i++)
2019
 
  {
2020
 
    my_snprintf(query_buff, sizeof(query_buff),
2021
 
                "SHOW %s STATUS WHERE Db = '%s'",
2022
 
                routine_type[i], db_name_buff);
2023
 
 
2024
 
    if (mysql_query_with_error_report(mysql, &routine_list_res, query_buff))
2025
 
      DBUG_RETURN(1);
2026
 
 
2027
 
    if (mysql_num_rows(routine_list_res))
2028
 
    {
2029
 
 
2030
 
      while ((routine_list_row= mysql_fetch_row(routine_list_res)))
2031
 
      {
2032
 
        routine_name= quote_name(routine_list_row[1], name_buff, 0);
2033
 
        DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i],
2034
 
                            name_buff));
2035
 
        my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
2036
 
                    routine_type[i], routine_name);
2037
 
 
2038
 
        if (mysql_query_with_error_report(mysql, &routine_res, query_buff))
2039
 
          DBUG_RETURN(1);
2040
 
 
2041
 
        while ((row= mysql_fetch_row(routine_res)))
2042
 
        {
2043
 
          /*
2044
 
            if the user has EXECUTE privilege he see routine names, but NOT the
2045
 
            routine body of other routines that are not the creator of!
2046
 
          */
2047
 
          DBUG_PRINT("info",("length of body for %s row[2] '%s' is %d",
2048
 
                             routine_name, row[2] ? row[2] : "(null)",
2049
 
                             row[2] ? (int) strlen(row[2]) : 0));
2050
 
          if (row[2] == NULL)
2051
 
          {
2052
 
            fprintf(sql_file, "\n-- insufficient privileges to %s\n", query_buff);
2053
 
            fprintf(sql_file, "-- does %s have permissions on mysql.proc?\n\n", current_user);
2054
 
            maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff);
2055
 
          }
2056
 
          else if (strlen(row[2]))
2057
 
          {
2058
 
            char *query_str;
2059
 
            if (opt_drop)
2060
 
              fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n",
2061
 
                      routine_type[i], routine_name);
2062
 
 
2063
 
            query_str= cover_definer_clause_in_sp(row[2], strlen(row[2]));
2064
 
 
2065
 
            if (mysql_num_fields(routine_res) >= 6)
2066
 
            {
2067
 
              if (switch_db_collation(sql_file, db_name_buff, ";",
2068
 
                                      db_cl_name, row[5], &db_cl_altered))
2069
 
              {
2070
 
                DBUG_RETURN(1);
2071
 
              }
2072
 
 
2073
 
              switch_cs_variables(sql_file, ";",
2074
 
                                  row[3],   /* character_set_client */
2075
 
                                  row[3],   /* character_set_results */
2076
 
                                  row[4]);  /* collation_connection */
2077
 
            }
2078
 
            else
2079
 
            {
2080
 
              /*
2081
 
                mysqldump is being run against the server, that does not
2082
 
                provide character set information in SHOW CREATE
2083
 
                statements.
2084
 
 
2085
 
                NOTE: the dump may be incorrect, since character set
2086
 
                information is required in order to restore stored
2087
 
                procedure/function properly.
2088
 
              */
2089
 
 
2090
 
              fprintf(sql_file,
2091
 
                      "--\n"
2092
 
                      "-- WARNING: old server version. "
2093
 
                        "The following dump may be incomplete.\n"
2094
 
                      "--\n");
2095
 
            }
2096
 
 
2097
 
 
2098
 
            switch_sql_mode(sql_file, ";", row[1]);
2099
 
 
2100
 
            fprintf(sql_file,
2101
 
                    "DELIMITER ;;\n"
2102
 
                    "/*!50003 %s */;;\n"
2103
 
                    "DELIMITER ;\n",
2104
 
                    (const char *) (query_str != NULL ? query_str : row[2]));
2105
 
 
2106
 
            restore_sql_mode(sql_file, ";");
2107
 
 
2108
 
            if (mysql_num_fields(routine_res) >= 6)
2109
 
            {
2110
 
              restore_cs_variables(sql_file, ";");
2111
 
 
2112
 
              if (db_cl_altered)
2113
 
              {
2114
 
                if (restore_db_collation(sql_file, db_name_buff, ";", db_cl_name))
2115
 
                  DBUG_RETURN(1);
2116
 
              }
2117
 
            }
2118
 
 
2119
 
            my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
2120
 
          }
2121
 
        } /* end of routine printing */
2122
 
        mysql_free_result(routine_res);
2123
 
 
2124
 
      } /* end of list of routines */
2125
 
    }
2126
 
    mysql_free_result(routine_list_res);
2127
 
  } /* end of for i (0 .. 1)  */
2128
 
 
2129
 
  if (switch_character_set_results(mysql, default_charset))
2130
 
    DBUG_RETURN(1);
2131
 
 
2132
 
  if (lock_tables)
2133
 
    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
2134
 
  DBUG_RETURN(0);
2135
 
}
2136
 
 
2137
 
/*
2138
1494
  get_table_structure -- retrievs database structure, prints out corresponding
2139
1495
  CREATE statement and fills out insert_pat if the table is the type we will
2140
1496
  be dumping.
2715
2071
 
2716
2072
 
2717
2073
 
2718
 
static char *alloc_query_str(ulong size)
2719
 
{
2720
 
  char *query;
2721
 
 
2722
 
  if (!(query= (char*) my_malloc(size, MYF(MY_WME))))
2723
 
    die(EX_MYSQLERR, "Couldn't allocate a query string.");
2724
 
 
2725
 
  return query;
2726
 
}
2727
 
 
2728
 
 
2729
2074
/*
2730
2075
 
2731
2076
 SYNOPSIS
2837
2182
 
2838
2183
    /* now build the query string */
2839
2184
 
2840
 
    dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '");
 
2185
    dynstr_append_checked(&query_string, "SELECT * INTO OUTFILE '");
2841
2186
    dynstr_append_checked(&query_string, filename);
2842
2187
    dynstr_append_checked(&query_string, "'");
2843
2188
 
2881
2226
      check_io(md_result_file);
2882
2227
    }
2883
2228
    
2884
 
    dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
 
2229
    dynstr_append_checked(&query_string, "SELECT * FROM ");
2885
2230
    dynstr_append_checked(&query_string, result_table);
2886
2231
 
2887
2232
    if (where)
3258
2603
} /* getTableName */
3259
2604
 
3260
2605
 
3261
 
/*
3262
 
  dump all logfile groups and tablespaces
3263
 
*/
3264
 
 
3265
 
static int dump_all_tablespaces()
3266
 
{
3267
 
  return dump_tablespaces(NULL);
3268
 
}
3269
 
 
3270
 
static int dump_tablespaces_for_tables(char *db, char **table_names, int tables)
3271
 
{
3272
 
  DYNAMIC_STRING where;
3273
 
  int r;
3274
 
  int i;
3275
 
  char name_buff[NAME_LEN*2+3];
3276
 
 
3277
 
  mysql_real_escape_string(mysql, name_buff, db, strlen(db));
3278
 
 
3279
 
  init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
3280
 
                      "SELECT DISTINCT TABLESPACE_NAME FROM"
3281
 
                      " INFORMATION_SCHEMA.PARTITIONS"
3282
 
                      " WHERE"
3283
 
                      " TABLE_SCHEMA='", 256, 1024);
3284
 
  dynstr_append_checked(&where, name_buff);
3285
 
  dynstr_append_checked(&where, "' AND TABLE_NAME IN (");
3286
 
 
3287
 
  for (i=0 ; i<tables ; i++)
3288
 
  {
3289
 
    mysql_real_escape_string(mysql, name_buff,
3290
 
                             table_names[i], strlen(table_names[i]));
3291
 
 
3292
 
    dynstr_append_checked(&where, "'");
3293
 
    dynstr_append_checked(&where, name_buff);
3294
 
    dynstr_append_checked(&where, "',");
3295
 
  }
3296
 
  dynstr_trunc(&where, 1);
3297
 
  dynstr_append_checked(&where,"))");
3298
 
 
3299
 
  DBUG_PRINT("info",("Dump TS for Tables where: %s",where.str));
3300
 
  r= dump_tablespaces(where.str);
3301
 
  dynstr_free(&where);
3302
 
  return r;
3303
 
}
3304
 
 
3305
 
static int dump_tablespaces_for_databases(char** databases)
3306
 
{
3307
 
  DYNAMIC_STRING where;
3308
 
  int r;
3309
 
  int i;
3310
 
 
3311
 
  init_dynamic_string_checked(&where, " AND TABLESPACE_NAME IN ("
3312
 
                      "SELECT DISTINCT TABLESPACE_NAME FROM"
3313
 
                      " INFORMATION_SCHEMA.PARTITIONS"
3314
 
                      " WHERE"
3315
 
                      " TABLE_SCHEMA IN (", 256, 1024);
3316
 
 
3317
 
  for (i=0 ; databases[i]!=NULL ; i++)
3318
 
  {
3319
 
    char db_name_buff[NAME_LEN*2+3];
3320
 
    mysql_real_escape_string(mysql, db_name_buff,
3321
 
                             databases[i], strlen(databases[i]));
3322
 
    dynstr_append_checked(&where, "'");
3323
 
    dynstr_append_checked(&where, db_name_buff);
3324
 
    dynstr_append_checked(&where, "',");
3325
 
  }
3326
 
  dynstr_trunc(&where, 1);
3327
 
  dynstr_append_checked(&where,"))");
3328
 
 
3329
 
  DBUG_PRINT("info",("Dump TS for DBs where: %s",where.str));
3330
 
  r= dump_tablespaces(where.str);
3331
 
  dynstr_free(&where);
3332
 
  return r;
3333
 
}
3334
 
 
3335
 
static int dump_tablespaces(char* ts_where)
3336
 
{
3337
 
  MYSQL_ROW row;
3338
 
  MYSQL_RES *tableres;
3339
 
  char buf[FN_REFLEN];
3340
 
  DYNAMIC_STRING sqlbuf;
3341
 
  int first= 0;
3342
 
  /*
3343
 
    The following are used for parsing the EXTRA field
3344
 
  */
3345
 
  char extra_format[]= "UNDO_BUFFER_SIZE=";
3346
 
  char *ubs;
3347
 
  char *endsemi;
3348
 
  DBUG_ENTER("dump_tablespaces");
3349
 
 
3350
 
  init_dynamic_string_checked(&sqlbuf,
3351
 
                      "SELECT LOGFILE_GROUP_NAME,"
3352
 
                      " FILE_NAME,"
3353
 
                      " TOTAL_EXTENTS,"
3354
 
                      " INITIAL_SIZE,"
3355
 
                      " ENGINE,"
3356
 
                      " EXTRA"
3357
 
                      " FROM INFORMATION_SCHEMA.FILES"
3358
 
                      " WHERE FILE_TYPE = 'UNDO LOG'"
3359
 
                      " AND FILE_NAME IS NOT NULL",
3360
 
                      256, 1024);
3361
 
  if(ts_where)
3362
 
  {
3363
 
    dynstr_append_checked(&sqlbuf,
3364
 
                  " AND LOGFILE_GROUP_NAME IN ("
3365
 
                  "SELECT DISTINCT LOGFILE_GROUP_NAME"
3366
 
                  " FROM INFORMATION_SCHEMA.FILES"
3367
 
                  " WHERE FILE_TYPE = 'DATAFILE'"
3368
 
                  );
3369
 
    dynstr_append_checked(&sqlbuf, ts_where);
3370
 
    dynstr_append_checked(&sqlbuf, ")");
3371
 
  }
3372
 
  dynstr_append_checked(&sqlbuf,
3373
 
                " GROUP BY LOGFILE_GROUP_NAME, FILE_NAME"
3374
 
                ", ENGINE"
3375
 
                " ORDER BY LOGFILE_GROUP_NAME");
3376
 
 
3377
 
  if (mysql_query(mysql, sqlbuf.str) ||
3378
 
      !(tableres = mysql_store_result(mysql)))
3379
 
  {
3380
 
    dynstr_free(&sqlbuf);
3381
 
    if (mysql_errno(mysql) == ER_BAD_TABLE_ERROR ||
3382
 
        mysql_errno(mysql) == ER_BAD_DB_ERROR ||
3383
 
        mysql_errno(mysql) == ER_UNKNOWN_TABLE)
3384
 
    {
3385
 
      fprintf(md_result_file,
3386
 
              "\n--\n-- Not dumping tablespaces as no INFORMATION_SCHEMA.FILES"
3387
 
              " table on this server\n--\n");
3388
 
      check_io(md_result_file);
3389
 
      DBUG_RETURN(0);
3390
 
    }
3391
 
 
3392
 
    my_printf_error(0, "Error: '%s' when trying to dump tablespaces",
3393
 
                    MYF(0), mysql_error(mysql));
3394
 
    DBUG_RETURN(1);
3395
 
  }
3396
 
 
3397
 
  buf[0]= 0;
3398
 
  while ((row= mysql_fetch_row(tableres)))
3399
 
  {
3400
 
    if (strcmp(buf, row[0]) != 0)
3401
 
      first= 1;
3402
 
    if (first)
3403
 
    {
3404
 
      if (!opt_xml && opt_comments)
3405
 
      {
3406
 
        fprintf(md_result_file,"\n--\n-- Logfile group: %s\n--\n", row[0]);
3407
 
        check_io(md_result_file);
3408
 
      }
3409
 
      fprintf(md_result_file, "\nCREATE");
3410
 
    }
3411
 
    else
3412
 
    {
3413
 
      fprintf(md_result_file, "\nALTER");
3414
 
    }
3415
 
    fprintf(md_result_file,
3416
 
            " LOGFILE GROUP %s\n"
3417
 
            "  ADD UNDOFILE '%s'\n",
3418
 
            row[0],
3419
 
            row[1]);
3420
 
    if (first)
3421
 
    {
3422
 
      ubs= strstr(row[5],extra_format);
3423
 
      if(!ubs)
3424
 
        break;
3425
 
      ubs+= strlen(extra_format);
3426
 
      endsemi= strstr(ubs,";");
3427
 
      if(endsemi)
3428
 
        endsemi[0]= '\0';
3429
 
      fprintf(md_result_file,
3430
 
              "  UNDO_BUFFER_SIZE %s\n",
3431
 
              ubs);
3432
 
    }
3433
 
    fprintf(md_result_file,
3434
 
            "  INITIAL_SIZE %s\n"
3435
 
            "  ENGINE=%s;\n",
3436
 
            row[3],
3437
 
            row[4]);
3438
 
    check_io(md_result_file);
3439
 
    if (first)
3440
 
    {
3441
 
      first= 0;
3442
 
      strxmov(buf, row[0], NullS);
3443
 
    }
3444
 
  }
3445
 
  dynstr_free(&sqlbuf);
3446
 
  mysql_free_result(tableres);
3447
 
  init_dynamic_string_checked(&sqlbuf,
3448
 
                      "SELECT DISTINCT TABLESPACE_NAME,"
3449
 
                      " FILE_NAME,"
3450
 
                      " LOGFILE_GROUP_NAME,"
3451
 
                      " EXTENT_SIZE,"
3452
 
                      " INITIAL_SIZE,"
3453
 
                      " ENGINE"
3454
 
                      " FROM INFORMATION_SCHEMA.FILES"
3455
 
                      " WHERE FILE_TYPE = 'DATAFILE'",
3456
 
                      256, 1024);
3457
 
 
3458
 
  if(ts_where)
3459
 
    dynstr_append_checked(&sqlbuf, ts_where);
3460
 
 
3461
 
  dynstr_append_checked(&sqlbuf, " ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME");
3462
 
 
3463
 
  if (mysql_query_with_error_report(mysql, &tableres, sqlbuf.str))
3464
 
  {
3465
 
    dynstr_free(&sqlbuf);
3466
 
    DBUG_RETURN(1);
3467
 
  }
3468
 
 
3469
 
  buf[0]= 0;
3470
 
  while ((row= mysql_fetch_row(tableres)))
3471
 
  {
3472
 
    if (strcmp(buf, row[0]) != 0)
3473
 
      first= 1;
3474
 
    if (first)
3475
 
    {
3476
 
      if (!opt_xml && opt_comments)
3477
 
      {
3478
 
        fprintf(md_result_file,"\n--\n-- Tablespace: %s\n--\n", row[0]);
3479
 
        check_io(md_result_file);
3480
 
      }
3481
 
      fprintf(md_result_file, "\nCREATE");
3482
 
    }
3483
 
    else
3484
 
    {
3485
 
      fprintf(md_result_file, "\nALTER");
3486
 
    }
3487
 
    fprintf(md_result_file,
3488
 
            " TABLESPACE %s\n"
3489
 
            "  ADD DATAFILE '%s'\n",
3490
 
            row[0],
3491
 
            row[1]);
3492
 
    if (first)
3493
 
    {
3494
 
      fprintf(md_result_file,
3495
 
              "  USE LOGFILE GROUP %s\n"
3496
 
              "  EXTENT_SIZE %s\n",
3497
 
              row[2],
3498
 
              row[3]);
3499
 
    }
3500
 
    fprintf(md_result_file,
3501
 
            "  INITIAL_SIZE %s\n"
3502
 
            "  ENGINE=%s;\n",
3503
 
            row[4],
3504
 
            row[5]);
3505
 
    check_io(md_result_file);
3506
 
    if (first)
3507
 
    {
3508
 
      first= 0;
3509
 
      strxmov(buf, row[0], NullS);
3510
 
    }
3511
 
  }
3512
 
 
3513
 
  mysql_free_result(tableres);
3514
 
  dynstr_free(&sqlbuf);
3515
 
  DBUG_RETURN(0);
3516
 
}
3517
 
 
3518
2606
static int dump_all_databases()
3519
2607
{
3520
2608
  MYSQL_ROW row;
3528
2616
    if (dump_all_tables_in_db(row[0]))
3529
2617
      result=1;
3530
2618
  }
3531
 
  if (seen_views)
3532
 
  {
3533
 
    if (mysql_query(mysql, "SHOW DATABASES") ||
3534
 
        !(tableres= mysql_store_result(mysql)))
3535
 
    {
3536
 
      my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s",
3537
 
                      MYF(0), mysql_error(mysql));
3538
 
      return 1;
3539
 
    }
3540
 
    while ((row= mysql_fetch_row(tableres)))
3541
 
    {
3542
 
      if (dump_all_views_in_db(row[0]))
3543
 
        result=1;
3544
 
    }
3545
 
  }
3546
2619
  return result;
3547
2620
}
3548
2621
/* dump_all_databases */
3559
2632
    if (dump_all_tables_in_db(*db))
3560
2633
      result=1;
3561
2634
  }
3562
 
  if (!result && seen_views)
3563
 
  {
3564
 
    for (db= db_names ; *db ; db++)
3565
 
    {
3566
 
      if (dump_all_views_in_db(*db))
3567
 
        result=1;
3568
 
    }
3569
 
  }
3570
2635
  DBUG_RETURN(result);
3571
2636
} /* dump_databases */
3572
2637
 
3573
2638
 
3574
2639
/*
3575
 
View Specific database initalization.
3576
 
 
3577
 
SYNOPSIS
3578
 
  init_dumping_views
3579
 
  qdatabase      quoted name of the database
3580
 
 
3581
 
RETURN VALUES
3582
 
  0        Success.
3583
 
  1        Failure.
3584
 
*/
3585
 
int init_dumping_views(char *qdatabase __attribute__((unused)))
3586
 
{
3587
 
    return 0;
3588
 
} /* init_dumping_views */
3589
 
 
3590
 
 
3591
 
/*
3592
2640
Table Specific database initalization.
3593
2641
 
3594
2642
SYNOPSIS
3742
2790
      order_by= 0;
3743
2791
    }
3744
2792
  }
3745
 
  if (opt_events && !opt_xml &&
3746
 
      mysql_get_server_version(mysql) >= 50106)
3747
 
  {
3748
 
    DBUG_PRINT("info", ("Dumping events for database %s", database));
3749
 
    dump_events_for_db(database);
3750
 
  }
3751
 
  if (opt_routines && !opt_xml &&
3752
 
      mysql_get_server_version(mysql) >= 50009)
3753
 
  {
3754
 
    DBUG_PRINT("info", ("Dumping routines for database %s", database));
3755
 
    dump_routines_for_db(database);
3756
 
  }
3757
2793
  if (opt_xml)
3758
2794
  {
3759
2795
    fputs("</database>\n", md_result_file);
3771
2807
 
3772
2808
 
3773
2809
/*
3774
 
   dump structure of views of database
3775
 
 
3776
 
   SYNOPSIS
3777
 
     dump_all_views_in_db()
3778
 
     database  database name
3779
 
 
3780
 
  RETURN
3781
 
    0 OK
3782
 
    1 ERROR
3783
 
*/
3784
 
 
3785
 
static my_bool dump_all_views_in_db(char *database)
3786
 
{
3787
 
  char *table;
3788
 
  uint numrows;
3789
 
  char table_buff[NAME_LEN*2+3];
3790
 
  char hash_key[2*NAME_LEN+2];  /* "db.tablename" */
3791
 
  char *afterdot;
3792
 
 
3793
 
  afterdot= strmov(hash_key, database);
3794
 
  *afterdot++= '.';
3795
 
 
3796
 
  if (init_dumping(database, init_dumping_views))
3797
 
    return 1;
3798
 
  if (opt_xml)
3799
 
    print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS);
3800
 
  if (lock_tables)
3801
 
  {
3802
 
    DYNAMIC_STRING query;
3803
 
    init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);
3804
 
    for (numrows= 0 ; (table= getTableName(1)); )
3805
 
    {
3806
 
      char *end= strmov(afterdot, table);
3807
 
      if (include_table((uchar*) hash_key,end - hash_key))
3808
 
      {
3809
 
        numrows++;
3810
 
        dynstr_append_checked(&query, quote_name(table, table_buff, 1));
3811
 
        dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");
3812
 
      }
3813
 
    }
3814
 
    if (numrows && mysql_real_query(mysql, query.str, query.length-1))
3815
 
      DB_error(mysql, "when using LOCK TABLES");
3816
 
            /* We shall continue here, if --force was given */
3817
 
    dynstr_free(&query);
3818
 
  }
3819
 
  if (flush_logs)
3820
 
  {
3821
 
    if (mysql_refresh(mysql, REFRESH_LOG))
3822
 
      DB_error(mysql, "when doing refresh");
3823
 
           /* We shall continue here, if --force was given */
3824
 
  }
3825
 
  while ((table= getTableName(0)))
3826
 
  {
3827
 
    char *end= strmov(afterdot, table);
3828
 
    if (include_table((uchar*) hash_key, end - hash_key))
3829
 
      get_view_structure(table, database);
3830
 
  }
3831
 
  if (opt_xml)
3832
 
  {
3833
 
    fputs("</database>\n", md_result_file);
3834
 
    check_io(md_result_file);
3835
 
  }
3836
 
  if (lock_tables)
3837
 
    VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES"));
3838
 
  return 0;
3839
 
} /* dump_all_tables_in_db */
3840
 
 
3841
 
 
3842
 
/*
3843
2810
  get_actual_table_name -- executes a SHOW TABLES LIKE '%s' to get the actual
3844
2811
  table name from the server for the table name given on the command line.
3845
2812
  we do this because the table name given on the command line may be a
3965
2932
    dump_table(*pos, db);
3966
2933
  }
3967
2934
 
3968
 
  /* Dump each selected view */
3969
 
  if (seen_views)
3970
 
  {
3971
 
    for (pos= dump_tables; pos < end; pos++)
3972
 
      get_view_structure(*pos, db);
3973
 
  }
3974
 
  if (opt_events && !opt_xml &&
3975
 
      mysql_get_server_version(mysql) >= 50106)
3976
 
  {
3977
 
    DBUG_PRINT("info", ("Dumping events for database %s", db));
3978
 
    dump_events_for_db(db);
3979
 
  }
3980
 
  /* obtain dump of routines (procs/functions) */
3981
 
  if (opt_routines  && !opt_xml &&
3982
 
      mysql_get_server_version(mysql) >= 50009)
3983
 
  {
3984
 
    DBUG_PRINT("info", ("Dumping routines for database %s", db));
3985
 
    dump_routines_for_db(db);
3986
 
  }
3987
2935
  free_root(&root, MYF(0));
3988
2936
  my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
3989
2937
  order_by= 0;
4496
3444
  return result;
4497
3445
}
4498
3446
 
4499
 
 
4500
 
/*
4501
 
  Replace a substring
4502
 
 
4503
 
  SYNOPSIS
4504
 
    replace
4505
 
    ds_str      The string to search and perform the replace in
4506
 
    search_str  The string to search for
4507
 
    search_len  Length of the string to search for
4508
 
    replace_str The string to replace with
4509
 
    replace_len Length of the string to replace with
4510
 
 
4511
 
  RETURN
4512
 
    0 String replaced
4513
 
    1 Could not find search_str in str
4514
 
*/
4515
 
 
4516
 
static int replace(DYNAMIC_STRING *ds_str,
4517
 
                   const char *search_str, ulong search_len,
4518
 
                   const char *replace_str, ulong replace_len)
4519
 
{
4520
 
  DYNAMIC_STRING ds_tmp;
4521
 
  const char *start= strstr(ds_str->str, search_str);
4522
 
  if (!start)
4523
 
    return 1;
4524
 
  init_dynamic_string_checked(&ds_tmp, "",
4525
 
                      ds_str->length + replace_len, 256);
4526
 
  dynstr_append_mem_checked(&ds_tmp, ds_str->str, start - ds_str->str);
4527
 
  dynstr_append_mem_checked(&ds_tmp, replace_str, replace_len);
4528
 
  dynstr_append_checked(&ds_tmp, start + search_len);
4529
 
  dynstr_set_checked(ds_str, ds_tmp.str);
4530
 
  dynstr_free(&ds_tmp);
4531
 
  return 0;
4532
 
}
4533
 
 
4534
 
 
4535
 
/*
4536
 
  Getting VIEW structure
4537
 
 
4538
 
  SYNOPSIS
4539
 
    get_view_structure()
4540
 
    table   view name
4541
 
    db      db name
4542
 
 
4543
 
  RETURN
4544
 
    0 OK
4545
 
    1 ERROR
4546
 
*/
4547
 
 
4548
 
static my_bool get_view_structure(char *table, char* db)
4549
 
{
4550
 
  MYSQL_RES  *table_res;
4551
 
  MYSQL_ROW  row;
4552
 
  MYSQL_FIELD *field;
4553
 
  char       *result_table, *opt_quoted_table;
4554
 
  char       table_buff[NAME_LEN*2+3];
4555
 
  char       table_buff2[NAME_LEN*2+3];
4556
 
  char       query[QUERY_LENGTH];
4557
 
  FILE       *sql_file= md_result_file;
4558
 
  DBUG_ENTER("get_view_structure");
4559
 
 
4560
 
  if (opt_no_create_info) /* Don't write table creation info */
4561
 
    DBUG_RETURN(0);
4562
 
 
4563
 
  verbose_msg("-- Retrieving view structure for table %s...\n", table);
4564
 
 
4565
 
#ifdef NOT_REALLY_USED_YET
4566
 
  sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
4567
 
          (opt_quoted || opt_keywords));
4568
 
#endif
4569
 
 
4570
 
  result_table=     quote_name(table, table_buff, 1);
4571
 
  opt_quoted_table= quote_name(table, table_buff2, 0);
4572
 
 
4573
 
  if (switch_character_set_results(mysql, "binary"))
4574
 
    DBUG_RETURN(1);
4575
 
 
4576
 
  my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table);
4577
 
 
4578
 
  if (mysql_query_with_error_report(mysql, &table_res, query))
4579
 
  {
4580
 
    switch_character_set_results(mysql, default_charset);
4581
 
    DBUG_RETURN(0);
4582
 
  }
4583
 
 
4584
 
  /* Check if this is a view */
4585
 
  field= mysql_fetch_field_direct(table_res, 0);
4586
 
  if (strcmp(field->name, "View") != 0)
4587
 
  {
4588
 
    switch_character_set_results(mysql, default_charset);
4589
 
    verbose_msg("-- It's base table, skipped\n");
4590
 
    DBUG_RETURN(0);
4591
 
  }
4592
 
 
4593
 
  /* If requested, open separate .sql file for this view */
4594
 
  if (path)
4595
 
  {
4596
 
    if (!(sql_file= open_sql_file_for_table(table)))
4597
 
      DBUG_RETURN(1);
4598
 
 
4599
 
    write_header(sql_file, db);
4600
 
  }
4601
 
 
4602
 
  if (!opt_xml && opt_comments)
4603
 
  {
4604
 
    fprintf(sql_file, "\n--\n-- Final view structure for view %s\n--\n\n",
4605
 
            result_table);
4606
 
    check_io(sql_file);
4607
 
  }
4608
 
  fprintf(sql_file, "/*!50001 DROP TABLE %s*/;\n", opt_quoted_table);
4609
 
  if (opt_drop)
4610
 
  {
4611
 
    fprintf(sql_file, "/*!50001 DROP VIEW IF EXISTS %s*/;\n",
4612
 
            opt_quoted_table);
4613
 
    check_io(sql_file);
4614
 
  }
4615
 
 
4616
 
 
4617
 
  my_snprintf(query, sizeof(query),
4618
 
              "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE, "
4619
 
              "       CHARACTER_SET_CLIENT, COLLATION_CONNECTION "
4620
 
              "FROM information_schema.views "
4621
 
              "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
4622
 
 
4623
 
  if (mysql_query(mysql, query))
4624
 
  {
4625
 
    /*
4626
 
      Use the raw output from SHOW CREATE TABLE if
4627
 
       information_schema query fails.
4628
 
     */
4629
 
    row= mysql_fetch_row(table_res);
4630
 
    fprintf(sql_file, "/*!50001 %s */;\n", row[1]);
4631
 
    check_io(sql_file);
4632
 
    mysql_free_result(table_res);
4633
 
  }
4634
 
  else
4635
 
  {
4636
 
    char *ptr;
4637
 
    ulong *lengths;
4638
 
    char search_buf[256], replace_buf[256];
4639
 
    ulong search_len, replace_len;
4640
 
    DYNAMIC_STRING ds_view;
4641
 
 
4642
 
    /* Save the result of SHOW CREATE TABLE in ds_view */
4643
 
    row= mysql_fetch_row(table_res);
4644
 
    lengths= mysql_fetch_lengths(table_res);
4645
 
    init_dynamic_string_checked(&ds_view, row[1], lengths[1] + 1, 1024);
4646
 
    mysql_free_result(table_res);
4647
 
 
4648
 
    /* Get the result from "select ... information_schema" */
4649
 
    if (!(table_res= mysql_store_result(mysql)) ||
4650
 
        !(row= mysql_fetch_row(table_res)))
4651
 
    {
4652
 
      if (table_res)
4653
 
        mysql_free_result(table_res);
4654
 
      dynstr_free(&ds_view);
4655
 
      DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view.");
4656
 
      DBUG_RETURN(1);
4657
 
    }
4658
 
 
4659
 
    lengths= mysql_fetch_lengths(table_res);
4660
 
 
4661
 
    /*
4662
 
      "WITH %s CHECK OPTION" is available from 5.0.2
4663
 
      Surround it with !50002 comments
4664
 
    */
4665
 
    if (strcmp(row[0], "NONE"))
4666
 
    {
4667
 
 
4668
 
      ptr= search_buf;
4669
 
      search_len= (ulong)(strxmov(ptr, "WITH ", row[0],
4670
 
                                  " CHECK OPTION", NullS) - ptr);
4671
 
      ptr= replace_buf;
4672
 
      replace_len=(ulong)(strxmov(ptr, "*/\n/*!50002 WITH ", row[0],
4673
 
                                  " CHECK OPTION", NullS) - ptr);
4674
 
      replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
4675
 
    }
4676
 
 
4677
 
    /*
4678
 
      "DEFINER=%s SQL SECURITY %s" is available from 5.0.13
4679
 
      Surround it with !50013 comments
4680
 
    */
4681
 
    {
4682
 
      size_t     user_name_len;
4683
 
      char       user_name_str[USERNAME_LENGTH + 1];
4684
 
      char       quoted_user_name_str[USERNAME_LENGTH * 2 + 3];
4685
 
      size_t     host_name_len;
4686
 
      char       host_name_str[HOSTNAME_LENGTH + 1];
4687
 
      char       quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3];
4688
 
 
4689
 
      parse_user(row[1], lengths[1], user_name_str, &user_name_len,
4690
 
                 host_name_str, &host_name_len);
4691
 
 
4692
 
      ptr= search_buf;
4693
 
      search_len=
4694
 
        (ulong)(strxmov(ptr, "DEFINER=",
4695
 
                        quote_name(user_name_str, quoted_user_name_str, FALSE),
4696
 
                        "@",
4697
 
                        quote_name(host_name_str, quoted_host_name_str, FALSE),
4698
 
                        " SQL SECURITY ", row[2], NullS) - ptr);
4699
 
      ptr= replace_buf;
4700
 
      replace_len=
4701
 
        (ulong)(strxmov(ptr, "*/\n/*!50013 DEFINER=",
4702
 
                        quote_name(user_name_str, quoted_user_name_str, FALSE),
4703
 
                        "@",
4704
 
                        quote_name(host_name_str, quoted_host_name_str, FALSE),
4705
 
                        " SQL SECURITY ", row[2],
4706
 
                        " */\n/*!50001", NullS) - ptr);
4707
 
      replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
4708
 
    }
4709
 
 
4710
 
    /* Dump view structure to file */
4711
 
 
4712
 
    fprintf(sql_file,
4713
 
            "/*!50001 SET @saved_cs_client          = @@character_set_client */;\n"
4714
 
            "/*!50001 SET @saved_cs_results         = @@character_set_results */;\n"
4715
 
            "/*!50001 SET @saved_col_connection     = @@collation_connection */;\n"
4716
 
            "/*!50001 SET character_set_client      = %s */;\n"
4717
 
            "/*!50001 SET character_set_results     = %s */;\n"
4718
 
            "/*!50001 SET collation_connection      = %s */;\n"
4719
 
            "/*!50001 %s */;\n"
4720
 
            "/*!50001 SET character_set_client      = @saved_cs_client */;\n"
4721
 
            "/*!50001 SET character_set_results     = @saved_cs_results */;\n"
4722
 
            "/*!50001 SET collation_connection      = @saved_col_connection */;\n",
4723
 
            (const char *) row[3],
4724
 
            (const char *) row[3],
4725
 
            (const char *) row[4],
4726
 
            (const char *) ds_view.str);
4727
 
 
4728
 
    check_io(sql_file);
4729
 
    mysql_free_result(table_res);
4730
 
    dynstr_free(&ds_view);
4731
 
  }
4732
 
 
4733
 
  if (switch_character_set_results(mysql, default_charset))
4734
 
    DBUG_RETURN(1);
4735
 
 
4736
 
  /* If a separate .sql file was opened, close it now */
4737
 
  if (sql_file != md_result_file)
4738
 
  {
4739
 
    fputs("\n", sql_file);
4740
 
    write_footer(sql_file);
4741
 
    my_fclose(sql_file, MYF(MY_WME));
4742
 
  }
4743
 
  DBUG_RETURN(0);
4744
 
}
4745
 
 
4746
3447
/*
4747
3448
  The following functions are wrappers for the dynamic string functions
4748
3449
  and if they fail, the wrappers will terminate the current process.
4848
3549
  if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */
4849
3550
    goto err;
4850
3551
 
4851
 
  if (opt_alltspcs)
4852
 
    dump_all_tablespaces();
4853
 
 
4854
3552
  if (opt_alldbs)
4855
3553
  {
4856
 
    if (!opt_alltspcs && !opt_notspcs)
4857
 
      dump_all_tablespaces();
4858
3554
    dump_all_databases();
4859
3555
  }
4860
3556
  else if (argc > 1 && !opt_databases)
4861
3557
  {
4862
3558
    /* Only one database and selected table(s) */
4863
 
    if (!opt_alltspcs && !opt_notspcs)
4864
 
      dump_tablespaces_for_tables(*argv, (argv + 1), (argc -1));
4865
3559
    dump_selected_tables(*argv, (argv + 1), (argc - 1));
4866
3560
  }
4867
3561
  else
4868
3562
  {
4869
 
    /* One or more databases, all tables */
4870
 
    if (!opt_alltspcs && !opt_notspcs)
4871
 
      dump_tablespaces_for_databases(argv);
4872
3563
    dump_databases(argv);
4873
3564
  }
4874
3565