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 
00037 #include <sys/stat.h>
00038 
00039 #include <string>
00040 #include <iostream>
00041 #include <sstream>
00042 #include <vector>
00043 #include <algorithm>
00044 
00045 using namespace std;
00046 
00047 namespace drizzled
00048 {
00049 
00050 inline const char *
00051 str_or_nil(const char *str)
00052 {
00053   return str ? str : "<nil>";
00054 }
00055 
00056 int wild_case_compare(const charset_info_st * const cs, const char *str, const char *wildstr)
00057 {
00058   int flag;
00059 
00060   while (*wildstr)
00061   {
00062     while (*wildstr && *wildstr != internal::wild_many && *wildstr != internal::wild_one)
00063     {
00064       if (*wildstr == internal::wild_prefix && wildstr[1])
00065         wildstr++;
00066 
00067       if (my_toupper(cs, *wildstr++) != my_toupper(cs, *str++))
00068         return (1);
00069     }
00070 
00071     if (! *wildstr )
00072       return (*str != 0);
00073 
00074     if (*wildstr++ == internal::wild_one)
00075     {
00076       if (! *str++)
00077         return (1); /* One char; skip */
00078     }
00079     else
00080     {           /* Found '*' */
00081       if (! *wildstr)
00082         return (0);   /* '*' as last char: OK */
00083 
00084       flag=(*wildstr != internal::wild_many && *wildstr != internal::wild_one);
00085       do
00086       {
00087         if (flag)
00088         {
00089           char cmp;
00090           if ((cmp= *wildstr) == internal::wild_prefix && wildstr[1])
00091             cmp= wildstr[1];
00092 
00093           cmp= my_toupper(cs, cmp);
00094 
00095           while (*str && my_toupper(cs, *str) != cmp)
00096             str++;
00097 
00098           if (! *str)
00099             return (1);
00100         }
00101 
00102         if (wild_case_compare(cs, str, wildstr) == 0)
00103           return (0);
00104 
00105       } while (*str++);
00106 
00107       return (1);
00108     }
00109   }
00110 
00111   return (*str != '\0');
00112 }
00113 
00114 /*
00115   Get the quote character for displaying an identifier.
00116 
00117   SYNOPSIS
00118     get_quote_char_for_identifier()
00119 
00120   IMPLEMENTATION
00121     Force quoting in the following cases:
00122       - name is empty (for one, it is possible when we use this function for
00123         quoting user and host names for DEFINER clause);
00124       - name is a keyword;
00125       - name includes a special character;
00126     Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
00127     is set.
00128 
00129   RETURN
00130     EOF   No quote character is needed
00131     #   Quote character
00132 */
00133 
00134 int get_quote_char_for_identifier()
00135 {
00136   return '`';
00137 }
00138 
00139 namespace show {
00140 
00141 bool buildScemas(Session *session)
00142 {
00143   session->lex().sql_command= SQLCOM_SELECT;
00144   session->lex().statement= new statement::Show(session);
00145 
00146   std::string column_name= "Database";
00147   if (session->lex().wild)
00148   {
00149     column_name.append(" (");
00150     column_name.append(session->lex().wild->ptr());
00151     column_name.append(")");
00152   }
00153 
00154   if (session->lex().current_select->where)
00155   {
00156     if (prepare_new_schema_table(session, session->lex(), "SCHEMAS"))
00157       return false;
00158   }
00159   else
00160   {
00161     if (prepare_new_schema_table(session, session->lex(), "SHOW_SCHEMAS"))
00162       return false;
00163   }
00164 
00165   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "SCHEMA_NAME");
00166   my_field->is_autogenerated_name= false;
00167   my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
00168 
00169   if (session->add_item_to_list(my_field))
00170     return false;
00171 
00172   if (session->add_order_to_list(my_field, true))
00173     return false;
00174 
00175   return true;
00176 }
00177 
00178 bool buildTables(Session *session, const char *ident)
00179 {
00180   session->lex().sql_command= SQLCOM_SELECT;
00181 
00182   drizzled::statement::Show *select= new statement::Show(session);
00183   session->lex().statement= select;
00184 
00185   std::string column_name= "Tables_in_";
00186 
00187   util::string::const_shared_ptr schema(session->schema());
00188   if (ident)
00189   {
00190     identifier::Schema identifier(ident);
00191     column_name.append(ident);
00192     session->lex().select_lex.db= const_cast<char *>(ident);
00193     if (not plugin::StorageEngine::doesSchemaExist(identifier))
00194     {
00195       my_error(ER_BAD_DB_ERROR, identifier);
00196     }
00197     select->setShowPredicate(ident, "");
00198   }
00199   else if (schema and not schema->empty())
00200   {
00201     column_name.append(*schema);
00202     select->setShowPredicate(*schema, "");
00203   }
00204   else
00205   {
00206     my_error(ER_NO_DB_ERROR, MYF(0));
00207     return false;
00208   }
00209 
00210 
00211   if (session->lex().wild)
00212   {
00213     column_name.append(" (");
00214     column_name.append(session->lex().wild->ptr());
00215     column_name.append(")");
00216   }
00217 
00218   if (prepare_new_schema_table(session, session->lex(), "SHOW_TABLES"))
00219     return false;
00220 
00221   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "TABLE_NAME");
00222   my_field->is_autogenerated_name= false;
00223   my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
00224 
00225   if (session->add_item_to_list(my_field))
00226     return false;
00227 
00228   if (session->add_order_to_list(my_field, true))
00229     return false;
00230 
00231   return true;
00232 }
00233 
00234 bool buildTemporaryTables(Session *session)
00235 {
00236   session->lex().sql_command= SQLCOM_SELECT;
00237 
00238   session->lex().statement= new statement::Show(session);
00239 
00240 
00241   if (prepare_new_schema_table(session, session->lex(), "SHOW_TEMPORARY_TABLES"))
00242     return false;
00243 
00244   if (session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*")))
00245     return false;
00246 
00247   (session->lex().current_select->with_wild)++;
00248 
00249   return true;
00250 }
00251 
00252 bool buildTableStatus(Session *session, const char *ident)
00253 {
00254   session->lex().sql_command= SQLCOM_SELECT;
00255   drizzled::statement::Show *select= new statement::Show(session);
00256   session->lex().statement= select;
00257 
00258   std::string column_name= "Tables_in_";
00259 
00260   util::string::const_shared_ptr schema(session->schema());
00261   if (ident)
00262   {
00263     session->lex().select_lex.db= const_cast<char *>(ident);
00264 
00265     identifier::Schema identifier(ident);
00266     if (not plugin::StorageEngine::doesSchemaExist(identifier))
00267     {
00268       my_error(ER_BAD_DB_ERROR, identifier);
00269     }
00270 
00271     select->setShowPredicate(ident, "");
00272   }
00273   else if (schema)
00274   {
00275     select->setShowPredicate(*schema, "");
00276   }
00277   else
00278   {
00279     my_error(ER_NO_DB_ERROR, MYF(0));
00280     return false;
00281   }
00282 
00283   if (prepare_new_schema_table(session, session->lex(), "SHOW_TABLE_STATUS"))
00284     return false;
00285 
00286   if (session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*")))
00287     return false;
00288 
00289   (session->lex().current_select->with_wild)++;
00290 
00291   return true;
00292 }
00293 
00294 bool buildEngineStatus(Session *session, LEX_STRING)
00295 {
00296   session->lex().sql_command= SQLCOM_SELECT;
00297   drizzled::statement::Show *select= new statement::Show(session);
00298   session->lex().statement= select;
00299 
00300   my_error(ER_USE_DATA_DICTIONARY);
00301   return false;
00302 }
00303 
00304 bool buildColumns(Session *session, const char *schema_ident, Table_ident *table_ident)
00305 {
00306   session->lex().sql_command= SQLCOM_SELECT;
00307 
00308   drizzled::statement::Show *select= new statement::Show(session);
00309   session->lex().statement= select;
00310 
00311   util::string::const_shared_ptr schema(session->schema());
00312   if (schema_ident)
00313   {
00314     select->setShowPredicate(schema_ident, table_ident->table.str);
00315   }
00316   else if (table_ident->db.str)
00317   {
00318     select->setShowPredicate(table_ident->db.str, table_ident->table.str);
00319   }
00320   else if (schema)
00321   {
00322     select->setShowPredicate(*schema, table_ident->table.str);
00323   }
00324   else
00325   {
00326     my_error(ER_NO_DB_ERROR, MYF(0));
00327     return false;
00328   }
00329 
00330   {
00331     drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
00332     if (not plugin::StorageEngine::doesTableExist(*session, identifier))
00333     {
00334       my_error(ER_TABLE_UNKNOWN, identifier);
00335     }
00336   }
00337 
00338   if (prepare_new_schema_table(session, session->lex(), "SHOW_COLUMNS"))
00339     return false;
00340 
00341   if (session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*")))
00342     return false;
00343 
00344   (session->lex().current_select->with_wild)++;
00345 
00346   return true;
00347 }
00348 
00349 void buildSelectWarning(Session *session)
00350 {
00351   (void) create_select_for_variable(session, "warning_count");
00352   session->lex().statement= new statement::Show(session);
00353 }
00354 
00355 void buildSelectError(Session *session)
00356 {
00357   (void) create_select_for_variable(session, "error_count");
00358   session->lex().statement= new statement::Show(session);
00359 }
00360 
00361 void buildWarnings(Session *session)
00362 {
00363   session->lex().statement= new statement::ShowWarnings(session);
00364 }
00365 
00366 void buildErrors(Session *session)
00367 {
00368   session->lex().statement= new statement::ShowErrors(session);
00369 }
00370 
00371 bool buildIndex(Session *session, const char *schema_ident, Table_ident *table_ident)
00372 {
00373   session->lex().sql_command= SQLCOM_SELECT;
00374   drizzled::statement::Show *select= new statement::Show(session);
00375   session->lex().statement= select;
00376 
00377   util::string::const_shared_ptr schema(session->schema());
00378   if (schema_ident)
00379   {
00380     select->setShowPredicate(schema_ident, table_ident->table.str);
00381   }
00382   else if (table_ident->db.str)
00383   {
00384     select->setShowPredicate(table_ident->db.str, table_ident->table.str);
00385   }
00386   else if (schema)
00387   {
00388     select->setShowPredicate(*schema, table_ident->table.str);
00389   }
00390   else
00391   {
00392     my_error(ER_NO_DB_ERROR, MYF(0));
00393     return false;
00394   }
00395 
00396   {
00397     drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
00398     if (not plugin::StorageEngine::doesTableExist(*session, identifier))
00399     {
00400       my_error(ER_TABLE_UNKNOWN, identifier);
00401     }
00402   }
00403 
00404   if (prepare_new_schema_table(session, session->lex(), "SHOW_INDEXES"))
00405     return false;
00406 
00407   if (session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*")))
00408     return false;
00409 
00410   (session->lex().current_select->with_wild)++;
00411 
00412   return true;
00413 }
00414 
00415 bool buildStatus(Session *session, const drizzled::sql_var_t is_global)
00416 {
00417   session->lex().sql_command= SQLCOM_SELECT;
00418   session->lex().statement= new statement::Show(session);
00419 
00420   if (is_global == OPT_GLOBAL)
00421   {
00422     if (prepare_new_schema_table(session, session->lex(), "GLOBAL_STATUS"))
00423       return false;
00424   }
00425   else
00426   {
00427     if (prepare_new_schema_table(session, session->lex(), "SESSION_STATUS"))
00428       return false;
00429   }
00430 
00431   std::string key("Variable_name");
00432   std::string value("Value");
00433 
00434   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_NAME");
00435   my_field->is_autogenerated_name= false;
00436   my_field->set_name(key.c_str(), key.length(), system_charset_info);
00437 
00438   if (session->add_item_to_list(my_field))
00439     return false;
00440 
00441   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_VALUE");
00442   my_field->is_autogenerated_name= false;
00443   my_field->set_name(value.c_str(), value.length(), system_charset_info);
00444 
00445   if (session->add_item_to_list(my_field))
00446     return false;
00447 
00448   return true;
00449 }
00450 
00451 bool buildCreateTable(Session *session, Table_ident *ident)
00452 {
00453   session->lex().sql_command= SQLCOM_SELECT;
00454   statement::Show *select= new statement::Show(session);
00455   session->lex().statement= select;
00456 
00457   if (session->lex().statement == NULL)
00458     return false;
00459 
00460   if (prepare_new_schema_table(session, session->lex(), "TABLE_SQL_DEFINITION"))
00461     return false;
00462 
00463   util::string::const_shared_ptr schema(session->schema());
00464   if (ident->db.str)
00465   {
00466     select->setShowPredicate(ident->db.str, ident->table.str);
00467   }
00468   else if (schema)
00469   {
00470     select->setShowPredicate(*schema, ident->table.str);
00471   }
00472   else
00473   {
00474     my_error(ER_NO_DB_ERROR, MYF(0));
00475     return false;
00476   }
00477 
00478   std::string key("Table");
00479   std::string value("Create Table");
00480 
00481   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "TABLE_NAME");
00482   my_field->is_autogenerated_name= false;
00483   my_field->set_name(key.c_str(), key.length(), system_charset_info);
00484 
00485   if (session->add_item_to_list(my_field))
00486     return false;
00487 
00488   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "TABLE_SQL_DEFINITION");
00489   my_field->is_autogenerated_name= false;
00490   my_field->set_name(value.c_str(), value.length(), system_charset_info);
00491 
00492   if (session->add_item_to_list(my_field))
00493     return false;
00494 
00495   return true;
00496 }
00497 
00498 bool buildProcesslist(Session *session)
00499 {
00500   session->lex().sql_command= SQLCOM_SELECT;
00501   session->lex().statement= new statement::Show(session);
00502 
00503   if (prepare_new_schema_table(session, session->lex(), "PROCESSLIST"))
00504     return false;
00505 
00506   if (session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*")))
00507     return false;
00508 
00509   (session->lex().current_select->with_wild)++;
00510 
00511   return true;
00512 }
00513 
00514 bool buildVariables(Session *session, const drizzled::sql_var_t is_global)
00515 {
00516   session->lex().sql_command= SQLCOM_SELECT;
00517   session->lex().statement= new statement::Show(session);
00518 
00519   if (is_global == OPT_GLOBAL)
00520   {
00521     if (prepare_new_schema_table(session, session->lex(), "GLOBAL_VARIABLES"))
00522       return false;
00523   }
00524   else
00525   {
00526     if (prepare_new_schema_table(session, session->lex(), "SESSION_VARIABLES"))
00527       return false;
00528   }
00529 
00530   std::string key("Variable_name");
00531   std::string value("Value");
00532 
00533   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_NAME");
00534   my_field->is_autogenerated_name= false;
00535   my_field->set_name(key.c_str(), key.length(), system_charset_info);
00536 
00537   if (session->add_item_to_list(my_field))
00538     return false;
00539 
00540   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "VARIABLE_VALUE");
00541   my_field->is_autogenerated_name= false;
00542   my_field->set_name(value.c_str(), value.length(), system_charset_info);
00543 
00544   if (session->add_item_to_list(my_field))
00545     return false;
00546 
00547   return true;
00548 }
00549 
00550 bool buildCreateSchema(Session *session, LEX_STRING &ident)
00551 {
00552   session->lex().sql_command= SQLCOM_SELECT;
00553   drizzled::statement::Show *select= new statement::Show(session);
00554   session->lex().statement= select;
00555 
00556   if (prepare_new_schema_table(session, session->lex(), "SCHEMA_SQL_DEFINITION"))
00557     return false;
00558 
00559   util::string::const_shared_ptr schema(session->schema());
00560   if (ident.str)
00561   {
00562     select->setShowPredicate(ident.str);
00563   }
00564   else if (schema)
00565   {
00566     select->setShowPredicate(*schema);
00567   }
00568   else
00569   {
00570     my_error(ER_NO_DB_ERROR, MYF(0));
00571     return false;
00572   }
00573 
00574   std::string key("Database");
00575   std::string value("Create Database");
00576 
00577   Item_field *my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "SCHEMA_NAME");
00578   my_field->is_autogenerated_name= false;
00579   my_field->set_name(key.c_str(), key.length(), system_charset_info);
00580 
00581   if (session->add_item_to_list(my_field))
00582     return false;
00583 
00584   my_field= new Item_field(&session->lex().current_select->context, NULL, NULL, "SCHEMA_SQL_DEFINITION");
00585   my_field->is_autogenerated_name= false;
00586   my_field->set_name(value.c_str(), value.length(), system_charset_info);
00587 
00588   if (session->add_item_to_list(my_field))
00589     return false;
00590 
00591   return true;
00592 }
00593 
00594 bool buildDescribe(Session *session, Table_ident *ident)
00595 {
00596   session->lex().lock_option= TL_READ;
00597   init_select(&session->lex());
00598   session->lex().current_select->parsing_place= SELECT_LIST;
00599   session->lex().sql_command= SQLCOM_SELECT;
00600   drizzled::statement::Show *select= new statement::Show(session);
00601   session->lex().statement= select;
00602   session->lex().select_lex.db= 0;
00603 
00604   util::string::const_shared_ptr schema(session->schema());
00605   if (ident->db.str)
00606   {
00607     select->setShowPredicate(ident->db.str, ident->table.str);
00608   }
00609   else if (schema)
00610   {
00611     select->setShowPredicate(*schema, ident->table.str);
00612   }
00613   else
00614   {
00615     my_error(ER_NO_DB_ERROR, MYF(0));
00616     return false;
00617   }
00618 
00619   {
00620     drizzled::identifier::Table identifier(select->getShowSchema().c_str(), ident->table.str);
00621     if (not plugin::StorageEngine::doesTableExist(*session, identifier))
00622     {
00623       my_error(ER_TABLE_UNKNOWN, identifier);
00624     }
00625   }
00626 
00627   if (prepare_new_schema_table(session, session->lex(), "SHOW_COLUMNS"))
00628   {
00629     return false;
00630   }
00631 
00632   if (session->add_item_to_list( new Item_field(&session->lex().current_select->context, NULL, NULL, "*")))
00633   {
00634     return false;
00635   }
00636 
00637   (session->lex().current_select->with_wild)++;
00638 
00639   return true;
00640 }
00641 
00642 } /* namespace drizzled */
00643 
00644 } /* namespace drizzled */