Drizzled Public API Documentation

show.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2010 Brian Aker
00005  *  Copyright (C) 2008 Sun Microsystems, Inc.
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; version 2 of the License.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 
00022 /* Function with list databases, tables or fields */
00023 #include <config.h>
00024 
00025 #include <drizzled/data_home.h>
00026 #include <drizzled/error.h>
00027 #include <drizzled/internal/my_sys.h>
00028 #include <drizzled/plugin/storage_engine.h>
00029 #include <drizzled/session.h>
00030 #include <drizzled/show.h>
00031 #include <drizzled/sql_select.h>
00032 #include <drizzled/statement/show.h>
00033 #include <drizzled/statement/show_errors.h>
00034 #include <drizzled/statement/show_warnings.h>
00035 #include <drizzled/sql_lex.h>
00036 #include <drizzled/table_ident.h>
00037 
00038 #include <sys/stat.h>
00039 
00040 #include <string>
00041 #include <iostream>
00042 #include <sstream>
00043 #include <vector>
00044 #include <algorithm>
00045 
00046 using namespace std;
00047 
00048 namespace drizzled {
00049 
00050 inline const char* str_or_nil(const char *str)
00051 {
00052   return str ? str : "<nil>";
00053 }
00054 
00055 int wild_case_compare(const charset_info_st * const cs, const char *str, const char *wildstr)
00056 {
00057   int flag;
00058 
00059   while (*wildstr)
00060   {
00061     while (*wildstr && *wildstr != internal::wild_many && *wildstr != internal::wild_one)
00062     {
00063       if (*wildstr == internal::wild_prefix && wildstr[1])
00064         wildstr++;
00065 
00066       if (cs->toupper(*wildstr++) != cs->toupper(*str++))
00067         return (1);
00068     }
00069 
00070     if (! *wildstr )
00071       return (*str != 0);
00072 
00073     if (*wildstr++ == internal::wild_one)
00074     {
00075       if (! *str++)
00076         return (1); /* One char; skip */
00077     }
00078     else
00079     {           /* Found '*' */
00080       if (! *wildstr)
00081         return (0);   /* '*' as last char: OK */
00082 
00083       flag=(*wildstr != internal::wild_many && *wildstr != internal::wild_one);
00084       do
00085       {
00086         if (flag)
00087         {
00088           char cmp;
00089           if ((cmp= *wildstr) == internal::wild_prefix && wildstr[1])
00090             cmp= wildstr[1];
00091 
00092           cmp= cs->toupper(cmp);
00093 
00094           while (*str && cs->toupper(*str) != cmp)
00095             str++;
00096 
00097           if (! *str)
00098             return (1);
00099         }
00100 
00101         if (wild_case_compare(cs, str, wildstr) == 0)
00102           return (0);
00103 
00104       } while (*str++);
00105 
00106       return (1);
00107     }
00108   }
00109 
00110   return (*str != '\0');
00111 }
00112 
00113 /*
00114   Get the quote character for displaying an identifier.
00115 
00116   SYNOPSIS
00117     get_quote_char_for_identifier()
00118 
00119   IMPLEMENTATION
00120     Force quoting in the following cases:
00121       - name is empty (for one, it is possible when we use this function for
00122         quoting user and host names for DEFINER clause);
00123       - name is a keyword;
00124       - name includes a special character;
00125     Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
00126     is set.
00127 
00128   RETURN
00129     EOF   No quote character is needed
00130     #   Quote character
00131 */
00132 
00133 int get_quote_char_for_identifier()
00134 {
00135   return '`';
00136 }
00137 
00138 namespace show {
00139 
00140 bool buildSchemas(Session *session)
00141 {
00142   session->lex().sql_command= SQLCOM_SELECT;
00143   session->lex().statement= new statement::Show(session);
00144 
00145   std::string column_name= "Database";
00146   if (session->lex().wild)
00147   {
00148     column_name.append(" (");
00149     column_name.append(session->lex().wild->ptr());
00150     column_name.append(")");
00151   }
00152 
00153   if (prepare_new_schema_table(session, session->lex(), session->lex().current_select->where ? "SCHEMAS" : "SHOW_SCHEMAS"))
00154     return false;
00155 
00156   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "SCHEMA_NAME");
00157   my_field->is_autogenerated_name= false;
00158   my_field->set_name(column_name);
00159 
00160   session->add_item_to_list(my_field);
00161   session->add_order_to_list(my_field, true);
00162   return true;
00163 }
00164 
00165 bool buildTables(Session *session, const char *ident)
00166 {
00167   session->lex().sql_command= SQLCOM_SELECT;
00168 
00169   drizzled::statement::Show *select= new statement::Show(session);
00170   session->lex().statement= select;
00171 
00172   std::string column_name= "Tables_in_";
00173 
00174   util::string::ptr schema(session->schema());
00175   if (ident)
00176   {
00177     identifier::Schema identifier= str_ref(ident);
00178     column_name.append(ident);
00179     session->lex().select_lex.db= ident;
00180     if (not plugin::StorageEngine::doesSchemaExist(identifier))
00181     {
00182       my_error(ER_BAD_DB_ERROR, identifier);
00183     }
00184     select->setShowPredicate(ident, "");
00185   }
00186   else if (schema and not schema->empty())
00187   {
00188     column_name.append(*schema);
00189     select->setShowPredicate(*schema, "");
00190   }
00191   else
00192   {
00193     my_error(ER_NO_DB_ERROR, MYF(0));
00194     return false;
00195   }
00196 
00197 
00198   if (session->lex().wild)
00199   {
00200     column_name.append(" (");
00201     column_name.append(session->lex().wild->ptr());
00202     column_name.append(")");
00203   }
00204 
00205   if (prepare_new_schema_table(session, session->lex(), "SHOW_TABLES"))
00206     return false;
00207 
00208   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "TABLE_NAME");
00209   my_field->is_autogenerated_name= false;
00210   my_field->set_name(column_name);
00211 
00212   session->add_item_to_list(my_field);
00213   session->add_order_to_list(my_field, true);
00214   return true;
00215 }
00216 
00217 bool buildTemporaryTables(Session *session)
00218 {
00219   session->lex().sql_command= SQLCOM_SELECT;
00220   session->lex().statement= new statement::Show(session);
00221 
00222   if (prepare_new_schema_table(session, session->lex(), "SHOW_TEMPORARY_TABLES"))
00223     return false;
00224 
00225   session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*"));
00226   session->lex().current_select->with_wild++;
00227   return true;
00228 }
00229 
00230 bool buildTableStatus(Session *session, const char *ident)
00231 {
00232   session->lex().sql_command= SQLCOM_SELECT;
00233   drizzled::statement::Show *select= new statement::Show(session);
00234   session->lex().statement= select;
00235 
00236   std::string column_name= "Tables_in_";
00237 
00238   util::string::ptr schema(session->schema());
00239   if (ident)
00240   {
00241     session->lex().select_lex.db= ident;
00242 
00243     identifier::Schema identifier= str_ref(ident);
00244     if (not plugin::StorageEngine::doesSchemaExist(identifier))
00245     {
00246       my_error(ER_BAD_DB_ERROR, identifier);
00247     }
00248 
00249     select->setShowPredicate(ident, "");
00250   }
00251   else if (schema)
00252   {
00253     select->setShowPredicate(*schema, "");
00254   }
00255   else
00256   {
00257     my_error(ER_NO_DB_ERROR, MYF(0));
00258     return false;
00259   }
00260 
00261   if (prepare_new_schema_table(session, session->lex(), "SHOW_TABLE_STATUS"))
00262     return false;
00263 
00264   session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*"));
00265   session->lex().current_select->with_wild++;
00266   return true;
00267 }
00268 
00269 bool buildEngineStatus(Session *session, str_ref)
00270 {
00271   session->lex().sql_command= SQLCOM_SELECT;
00272   drizzled::statement::Show *select= new statement::Show(session);
00273   session->lex().statement= select;
00274 
00275   my_error(ER_USE_DATA_DICTIONARY);
00276   return false;
00277 }
00278 
00279 bool buildColumns(Session *session, const char *schema_ident, Table_ident *table_ident)
00280 {
00281   session->lex().sql_command= SQLCOM_SELECT;
00282 
00283   drizzled::statement::Show *select= new statement::Show(session);
00284   session->lex().statement= select;
00285 
00286   util::string::ptr schema(session->schema());
00287   if (schema_ident)
00288   {
00289     select->setShowPredicate(schema_ident, table_ident->table.data());
00290   }
00291   else if (table_ident->db.data())
00292   {
00293     select->setShowPredicate(table_ident->db.data(), table_ident->table.data());
00294   }
00295   else if (schema)
00296   {
00297     select->setShowPredicate(*schema, table_ident->table.data());
00298   }
00299   else
00300   {
00301     my_error(ER_NO_DB_ERROR, MYF(0));
00302     return false;
00303   }
00304 
00305   {
00306     drizzled::identifier::Table identifier(select->getShowSchema(), table_ident->table.data());
00307     if (not plugin::StorageEngine::doesTableExist(*session, identifier))
00308     {
00309       my_error(ER_TABLE_UNKNOWN, identifier);
00310     }
00311   }
00312 
00313   if (prepare_new_schema_table(session, session->lex(), "SHOW_COLUMNS"))
00314     return false;
00315 
00316   session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*"));
00317   session->lex().current_select->with_wild++;
00318   return true;
00319 }
00320 
00321 void buildSelectWarning(Session *session)
00322 {
00323   (void) create_select_for_variable(session, "warning_count");
00324   session->lex().statement= new statement::Show(session);
00325 }
00326 
00327 void buildSelectError(Session *session)
00328 {
00329   (void) create_select_for_variable(session, "error_count");
00330   session->lex().statement= new statement::Show(session);
00331 }
00332 
00333 void buildWarnings(Session *session)
00334 {
00335   session->lex().statement= new statement::ShowWarnings(session);
00336 }
00337 
00338 void buildErrors(Session *session)
00339 {
00340   session->lex().statement= new statement::ShowErrors(session);
00341 }
00342 
00343 bool buildIndex(Session *session, const char *schema_ident, Table_ident *table_ident)
00344 {
00345   session->lex().sql_command= SQLCOM_SELECT;
00346   drizzled::statement::Show *select= new statement::Show(session);
00347   session->lex().statement= select;
00348 
00349   util::string::ptr schema(session->schema());
00350   if (schema_ident)
00351   {
00352     select->setShowPredicate(schema_ident, table_ident->table.data());
00353   }
00354   else if (table_ident->db.data())
00355   {
00356     select->setShowPredicate(table_ident->db.data(), table_ident->table.data());
00357   }
00358   else if (schema)
00359   {
00360     select->setShowPredicate(*schema, table_ident->table.data());
00361   }
00362   else
00363   {
00364     my_error(ER_NO_DB_ERROR, MYF(0));
00365     return false;
00366   }
00367 
00368   {
00369     drizzled::identifier::Table identifier(select->getShowSchema(), table_ident->table.data());
00370     if (not plugin::StorageEngine::doesTableExist(*session, identifier))
00371     {
00372       my_error(ER_TABLE_UNKNOWN, identifier);
00373     }
00374   }
00375 
00376   if (prepare_new_schema_table(session, session->lex(), "SHOW_INDEXES"))
00377     return false;
00378 
00379   session->add_item_to_list(new Item_field(&session->lex().current_select->context, NULL, NULL, "*"));
00380   session->lex().current_select->with_wild++;
00381   return true;
00382 }
00383 
00384 bool buildStatus(Session *session, const drizzled::sql_var_t is_global)
00385 {
00386   session->lex().sql_command= SQLCOM_SELECT;
00387   session->lex().statement= new statement::Show(session);
00388 
00389   if (prepare_new_schema_table(session, session->lex(), is_global == OPT_GLOBAL ? "GLOBAL_STATUS" : "SESSION_STATUS"))
00390     return false;
00391 
00392   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_NAME");
00393   my_field->is_autogenerated_name= false;
00394   my_field->set_name("Variable_name");
00395   session->add_item_to_list(my_field);
00396   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_VALUE");
00397   my_field->is_autogenerated_name= false;
00398   my_field->set_name("Value");
00399   session->add_item_to_list(my_field);
00400   return true;
00401 }
00402 
00403 bool buildCreateTable(Session *session, Table_ident *ident)
00404 {
00405   session->lex().sql_command= SQLCOM_SELECT;
00406   statement::Show *select= new statement::Show(session);
00407   session->lex().statement= select;
00408 
00409   if (session->lex().statement == NULL)
00410     return false;
00411 
00412   if (prepare_new_schema_table(session, session->lex(), "TABLE_SQL_DEFINITION"))
00413     return false;
00414 
00415   util::string::ptr schema(session->schema());
00416   if (ident->db.data())
00417   {
00418     select->setShowPredicate(ident->db.data(), ident->table.data());
00419   }
00420   else if (schema)
00421   {
00422     select->setShowPredicate(*schema, ident->table.data());
00423   }
00424   else
00425   {
00426     my_error(ER_NO_DB_ERROR, MYF(0));
00427     return false;
00428   }
00429 
00430   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "TABLE_NAME");
00431   my_field->is_autogenerated_name= false;
00432   my_field->set_name("Table");
00433   session->add_item_to_list(my_field);
00434   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "TABLE_SQL_DEFINITION");
00435   my_field->is_autogenerated_name= false;
00436   my_field->set_name("Create Table");
00437   session->add_item_to_list(my_field);
00438   return true;
00439 }
00440 
00441 bool buildProcesslist(Session *session)
00442 {
00443   session->lex().sql_command= SQLCOM_SELECT;
00444   session->lex().statement= new statement::Show(session);
00445 
00446   if (prepare_new_schema_table(session, session->lex(), "PROCESSLIST"))
00447     return false;
00448 
00449   session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*"));
00450   session->lex().current_select->with_wild++;
00451   return true;
00452 }
00453 
00454 bool buildVariables(Session *session, const drizzled::sql_var_t is_global)
00455 {
00456   session->lex().sql_command= SQLCOM_SELECT;
00457   session->lex().statement= new statement::Show(session);
00458 
00459   if (is_global == OPT_GLOBAL)
00460   {
00461     if (prepare_new_schema_table(session, session->lex(), "GLOBAL_VARIABLES"))
00462       return false;
00463   }
00464   else
00465   {
00466     if (prepare_new_schema_table(session, session->lex(), "SESSION_VARIABLES"))
00467       return false;
00468   }
00469 
00470   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_NAME");
00471   my_field->is_autogenerated_name= false;
00472   my_field->set_name("Variable_name");
00473   session->add_item_to_list(my_field);
00474   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_VALUE");
00475   my_field->is_autogenerated_name= false;
00476   my_field->set_name("Value");
00477 
00478   session->add_item_to_list(my_field);
00479   return true;
00480 }
00481 
00482 bool buildCreateSchema(Session *session, str_ref ident)
00483 {
00484   session->lex().sql_command= SQLCOM_SELECT;
00485   drizzled::statement::Show *select= new statement::Show(session);
00486   session->lex().statement= select;
00487 
00488   if (prepare_new_schema_table(session, session->lex(), "SCHEMA_SQL_DEFINITION"))
00489     return false;
00490 
00491   util::string::ptr schema(session->schema());
00492   if (ident.data())
00493   {
00494     select->setShowPredicate(ident.data());
00495   }
00496   else if (schema)
00497   {
00498     select->setShowPredicate(*schema);
00499   }
00500   else
00501   {
00502     my_error(ER_NO_DB_ERROR, MYF(0));
00503     return false;
00504   }
00505 
00506   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "SCHEMA_NAME");
00507   my_field->is_autogenerated_name= false;
00508   my_field->set_name("Database");
00509   session->add_item_to_list(my_field);
00510 
00511   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "SCHEMA_SQL_DEFINITION");
00512   my_field->is_autogenerated_name= false;
00513   my_field->set_name("Create Database");
00514   session->add_item_to_list(my_field);
00515   return true;
00516 }
00517 
00518 bool buildDescribe(Session *session, Table_ident *ident)
00519 {
00520   session->lex().lock_option= TL_READ;
00521   init_select(&session->lex());
00522   session->lex().current_select->parsing_place= SELECT_LIST;
00523   session->lex().sql_command= SQLCOM_SELECT;
00524   drizzled::statement::Show *select= new statement::Show(session);
00525   session->lex().statement= select;
00526   session->lex().select_lex.db= 0;
00527 
00528   util::string::ptr schema(session->schema());
00529   if (ident->db.data())
00530   {
00531     select->setShowPredicate(ident->db.data(), ident->table.data());
00532   }
00533   else if (schema)
00534   {
00535     select->setShowPredicate(*schema, ident->table.data());
00536   }
00537   else
00538   {
00539     my_error(ER_NO_DB_ERROR, MYF(0));
00540     return false;
00541   }
00542 
00543   {
00544     drizzled::identifier::Table identifier(select->getShowSchema(), ident->table.data());
00545     if (not plugin::StorageEngine::doesTableExist(*session, identifier))
00546     {
00547       my_error(ER_TABLE_UNKNOWN, identifier);
00548     }
00549   }
00550 
00551   if (prepare_new_schema_table(session, session->lex(), "SHOW_COLUMNS"))
00552   {
00553     return false;
00554   }
00555   session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*"));
00556   session->lex().current_select->with_wild++;
00557   return true;
00558 }
00559 
00560 }
00561 } /* namespace drizzled */