00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <config.h>
00019 #include <assert.h>
00020
00021 #include <signal.h>
00022
00023 #if TIME_WITH_SYS_TIME
00024 # include <sys/time.h>
00025 # include <time.h>
00026 #else
00027 # if HAVE_SYS_TIME_H
00028 # include <sys/time.h>
00029 # else
00030 # include <time.h>
00031 # endif
00032 #endif
00033 #include <drizzled/internal/my_pthread.h>
00034 #include <drizzled/internal/thread_var.h>
00035
00036 #include <drizzled/sql_select.h>
00037 #include <drizzled/error.h>
00038 #include <drizzled/gettext.h>
00039 #include <drizzled/nested_join.h>
00040 #include <drizzled/sql_base.h>
00041 #include <drizzled/show.h>
00042 #include <drizzled/item/cmpfunc.h>
00043 #include <drizzled/replication_services.h>
00044 #include <drizzled/check_stack_overrun.h>
00045 #include <drizzled/lock.h>
00046 #include <drizzled/plugin/listen.h>
00047 #include <drizzled/cached_directory.h>
00048 #include <drizzled/field/epoch.h>
00049 #include <drizzled/field/null.h>
00050 #include <drizzled/sql_table.h>
00051 #include <drizzled/global_charset_info.h>
00052 #include <drizzled/pthread_globals.h>
00053 #include <drizzled/internal/iocache.h>
00054 #include <drizzled/drizzled.h>
00055 #include <drizzled/plugin/authorization.h>
00056 #include <drizzled/table/temporary.h>
00057 #include <drizzled/table/placeholder.h>
00058 #include <drizzled/table/unused.h>
00059 #include <drizzled/plugin/storage_engine.h>
00060 #include <drizzled/session.h>
00061 #include <drizzled/item/subselect.h>
00062 #include <drizzled/sql_lex.h>
00063
00064 #include <drizzled/refresh_version.h>
00065
00066 using namespace std;
00067
00068 namespace drizzled
00069 {
00070
00071 extern bool volatile shutdown_in_progress;
00072
00073 bool table_cache_init(void)
00074 {
00075 return false;
00076 }
00077
00078 uint32_t cached_open_tables(void)
00079 {
00080 return table::getCache().size();
00081 }
00082
00083 void table_cache_free(void)
00084 {
00085 refresh_version++;
00086
00087 table::getUnused().clear();
00088 table::getCache().clear();
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 void close_handle_and_leave_table_as_lock(Table *table)
00110 {
00111 assert(table->db_stat);
00112 assert(table->getShare()->getType() == message::Table::STANDARD);
00113
00114
00115
00116
00117
00118
00119 identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName(), message::Table::INTERNAL);
00120 const identifier::Table::Key &key(identifier.getKey());
00121 TableShare *share= new TableShare(identifier.getType(),
00122 identifier,
00123 const_cast<char *>(key.vector()), static_cast<uint32_t>(table->getShare()->getCacheKeySize()));
00124
00125 table->cursor->close();
00126 table->db_stat= 0;
00127 table::instance::release(table->getMutableShare());
00128 table->setShare(share);
00129 }
00130
00131
00132
00133
00134
00135
00136
00137 void Table::intern_close_table()
00138 {
00139 free_io_cache();
00140 if (cursor)
00141 {
00142 delete_table(true);
00143 }
00144 }
00145
00146
00147
00148 void Table::free_io_cache()
00149 {
00150 if (sort.io_cache)
00151 {
00152 sort.io_cache->close_cached_file();
00153 safe_delete(sort.io_cache);
00154 }
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 bool Session::close_cached_tables(TableList *tables, bool wait_for_refresh, bool wait_for_placeholders)
00174 {
00175 bool result= false;
00176 Session *session= this;
00177
00178 {
00179 boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
00180
00181 if (tables == NULL)
00182 {
00183 refresh_version++;
00184
00185 table::getUnused().clear();
00186
00187 if (wait_for_refresh)
00188 {
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 for (table::CacheMap::const_iterator iter= table::getCache().begin();
00227 iter != table::getCache().end();
00228 iter++)
00229 {
00230 Table *table= iter->second;
00231 if (table->in_use)
00232 table->in_use->some_tables_deleted= false;
00233 }
00234 }
00235 }
00236 else
00237 {
00238 bool found= false;
00239 for (TableList *table= tables; table; table= table->next_local)
00240 {
00241 identifier::Table identifier(table->getSchemaName(), table->getTableName());
00242 if (table::Cache::singleton().removeTable(session, identifier,
00243 RTFC_OWNED_BY_Session_FLAG))
00244 {
00245 found= true;
00246 }
00247 }
00248 if (!found)
00249 wait_for_refresh= false;
00250 }
00251
00252 if (wait_for_refresh)
00253 {
00254
00255
00256
00257
00258 session->mysys_var->current_mutex= &table::Cache::singleton().mutex();
00259 session->mysys_var->current_cond= &COND_refresh;
00260 session->set_proc_info("Flushing tables");
00261
00262 session->close_old_data_files();
00263
00264 bool found= true;
00265
00266 while (found && ! session->getKilled())
00267 {
00268 found= false;
00269 for (table::CacheMap::const_iterator iter= table::getCache().begin();
00270 iter != table::getCache().end();
00271 iter++)
00272 {
00273 Table *table= iter->second;
00274
00275 if (table->in_use == session)
00276 continue;
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 if (table->needs_reopen_or_name_lock() && (table->db_stat ||
00292 (table->open_placeholder && wait_for_placeholders)))
00293 {
00294 found= true;
00295 COND_refresh.wait(scopedLock);
00296 break;
00297 }
00298 }
00299 }
00300
00301
00302
00303
00304
00305 result= session->reopen_tables();
00306
00307
00308 for (Table *table= session->open_tables; table ; table= table->getNext())
00309 {
00310
00311
00312
00313
00314 if (table->reginfo.lock_type < TL_WRITE_ALLOW_WRITE)
00315 table->getMutableShare()->refreshVersion();
00316 }
00317 }
00318 }
00319
00320 if (wait_for_refresh)
00321 {
00322 boost_unique_lock_t scopedLock(session->mysys_var->mutex);
00323 session->mysys_var->current_mutex= 0;
00324 session->mysys_var->current_cond= 0;
00325 session->set_proc_info(0);
00326 }
00327
00328 return result;
00329 }
00330
00331
00336 bool Session::free_cached_table(boost::mutex::scoped_lock &scopedLock)
00337 {
00338 bool found_old_table= false;
00339
00340 (void)scopedLock;
00341
00342 table::Concurrent *table= static_cast<table::Concurrent *>(open_tables);
00343
00344 safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
00345 assert(table->key_read == 0);
00346 assert(!table->cursor || table->cursor->inited == Cursor::NONE);
00347
00348 open_tables= table->getNext();
00349
00350 if (table->needs_reopen_or_name_lock() ||
00351 version != refresh_version || !table->db_stat)
00352 {
00353 table::remove_table(table);
00354 found_old_table= true;
00355 }
00356 else
00357 {
00358
00359
00360
00361
00362 assert(not table->open_placeholder);
00363
00364
00365 table->cursor->ha_reset();
00366 table->in_use= NULL;
00367
00368 table::getUnused().link(table);
00369 }
00370
00371 return found_old_table;
00372 }
00373
00374
00383 void Session::close_open_tables()
00384 {
00385 bool found_old_table= false;
00386
00387 safe_mutex_assert_not_owner(table::Cache::singleton().mutex().native_handle());
00388
00389 boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex());
00390
00391 while (open_tables)
00392 {
00393 found_old_table|= free_cached_table(scoped_lock);
00394 }
00395 some_tables_deleted= false;
00396
00397 if (found_old_table)
00398 {
00399
00400 locking::broadcast_refresh();
00401 }
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 TableList *find_table_in_list(TableList *table,
00423 TableList *TableList::*link,
00424 const char *db_name,
00425 const char *table_name)
00426 {
00427 for (; table; table= table->*link )
00428 {
00429 if ((table->table == 0 || table->table->getShare()->getType() == message::Table::STANDARD) and
00430 my_strcasecmp(system_charset_info, table->getSchemaName(), db_name) == 0 and
00431 my_strcasecmp(system_charset_info, table->getTableName(), table_name) == 0)
00432 {
00433 break;
00434 }
00435 }
00436 return table;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 TableList* unique_table(TableList *table, TableList *table_list,
00477 bool check_alias)
00478 {
00479 TableList *res;
00480 const char *d_name, *t_name, *t_alias;
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 if (table->table)
00493 {
00494
00495 if (table->table && table->table->getShare()->getType() != message::Table::STANDARD)
00496 return 0;
00497 table= table->find_underlying_table(table->table);
00498
00499
00500
00501
00502 assert(table);
00503 }
00504 d_name= table->getSchemaName();
00505 t_name= table->getTableName();
00506 t_alias= table->alias;
00507
00508 for (;;)
00509 {
00510 if ((! (res= find_table_in_global_list(table_list, d_name, t_name))) ||
00511 ((!res->table || res->table != table->table) &&
00512 (!check_alias || !(my_strcasecmp(files_charset_info, t_alias, res->alias))) &&
00513 res->select_lex && !res->select_lex->exclude_from_table_unique_test))
00514 break;
00515
00516
00517
00518
00519
00520 table_list= res->next_global;
00521 }
00522 return(res);
00523 }
00524
00525
00526 void Open_tables_state::doGetTableNames(const identifier::Schema &schema_identifier,
00527 std::set<std::string>& set_of_names)
00528 {
00529 for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
00530 {
00531 if (schema_identifier.compare(table->getShare()->getSchemaName()))
00532 {
00533 set_of_names.insert(table->getShare()->getTableName());
00534 }
00535 }
00536 }
00537
00538 void Open_tables_state::doGetTableNames(CachedDirectory &,
00539 const identifier::Schema &schema_identifier,
00540 std::set<std::string> &set_of_names)
00541 {
00542 doGetTableNames(schema_identifier, set_of_names);
00543 }
00544
00545 void Open_tables_state::doGetTableIdentifiers(const identifier::Schema &schema_identifier,
00546 identifier::Table::vector &set_of_identifiers)
00547 {
00548 for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
00549 {
00550 if (schema_identifier.compare(table->getShare()->getSchemaName()))
00551 {
00552 set_of_identifiers.push_back(identifier::Table(table->getShare()->getSchemaName(),
00553 table->getShare()->getTableName(),
00554 table->getShare()->getPath()));
00555 }
00556 }
00557 }
00558
00559 void Open_tables_state::doGetTableIdentifiers(CachedDirectory &,
00560 const identifier::Schema &schema_identifier,
00561 identifier::Table::vector &set_of_identifiers)
00562 {
00563 doGetTableIdentifiers(schema_identifier, set_of_identifiers);
00564 }
00565
00566 bool Open_tables_state::doDoesTableExist(const identifier::Table &identifier)
00567 {
00568 for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
00569 {
00570 if (table->getShare()->getType() == message::Table::TEMPORARY)
00571 {
00572 if (identifier.getKey() == table->getShare()->getCacheKey())
00573 {
00574 return true;
00575 }
00576 }
00577 }
00578
00579 return false;
00580 }
00581
00582 int Open_tables_state::doGetTableDefinition(const identifier::Table &identifier,
00583 message::Table &table_proto)
00584 {
00585 for (Table *table= getTemporaryTables() ; table ; table= table->getNext())
00586 {
00587 if (table->getShare()->getType() == message::Table::TEMPORARY)
00588 {
00589 if (identifier.getKey() == table->getShare()->getCacheKey())
00590 {
00591 table_proto.CopyFrom(*(table->getShare()->getTableMessage()));
00592
00593 return EEXIST;
00594 }
00595 }
00596 }
00597
00598 return ENOENT;
00599 }
00600
00601 Table *Open_tables_state::find_temporary_table(const identifier::Table &identifier)
00602 {
00603 for (Table *table= temporary_tables ; table ; table= table->getNext())
00604 {
00605 if (identifier.getKey() == table->getShare()->getCacheKey())
00606 return table;
00607 }
00608
00609 return NULL;
00610 }
00611
00612
00639 int Open_tables_state::drop_temporary_table(const drizzled::identifier::Table &identifier)
00640 {
00641 Table *table;
00642
00643 if (not (table= find_temporary_table(identifier)))
00644 return 1;
00645
00646
00647 if (table->query_id && table->query_id != getQueryId())
00648 {
00649 my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
00650 return -1;
00651 }
00652
00653 close_temporary_table(table);
00654
00655 return 0;
00656 }
00657
00658
00669 void Session::unlink_open_table(Table *find)
00670 {
00671 const identifier::Table::Key find_key(find->getShare()->getCacheKey());
00672 Table **prev;
00673 safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
00674
00675
00676
00677
00678
00679
00680
00681
00682 for (prev= &open_tables; *prev; )
00683 {
00684 Table *list= *prev;
00685
00686 if (list->getShare()->getCacheKey() == find_key)
00687 {
00688
00689 *prev= list->getNext();
00690
00691
00692 table::remove_table(static_cast<table::Concurrent *>(list));
00693 }
00694 else
00695 {
00696
00697 prev= list->getNextPtr();
00698 }
00699 }
00700
00701
00702 locking::broadcast_refresh();
00703 }
00704
00705
00725 void Session::drop_open_table(Table *table, const identifier::Table &identifier)
00726 {
00727 if (table->getShare()->getType())
00728 {
00729 close_temporary_table(table);
00730 }
00731 else
00732 {
00733 boost_unique_lock_t scoped_lock(table::Cache::singleton().mutex());
00734
00735
00736
00737
00738 unlink_open_table(table);
00739 (void)plugin::StorageEngine::dropTable(*this, identifier);
00740 }
00741 }
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 void Session::wait_for_condition(boost::mutex &mutex, boost::condition_variable_any &cond)
00756 {
00757
00758 const char *saved_proc_info;
00759 mysys_var->current_mutex= &mutex;
00760 mysys_var->current_cond= &cond;
00761 saved_proc_info= get_proc_info();
00762 set_proc_info("Waiting for table");
00763 {
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 boost_unique_lock_t scopedLock(mutex, boost::adopt_lock_t());
00775 if (not getKilled())
00776 {
00777 cond.wait(scopedLock);
00778 }
00779 }
00780 boost_unique_lock_t mysys_scopedLock(mysys_var->mutex);
00781 mysys_var->current_mutex= 0;
00782 mysys_var->current_cond= 0;
00783 set_proc_info(saved_proc_info);
00784 }
00785
00786
00800 table::Placeholder *Session::table_cache_insert_placeholder(const drizzled::identifier::Table &arg)
00801 {
00802 safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
00803
00804
00805
00806
00807 identifier::Table identifier(arg.getSchemaName(), arg.getTableName(), message::Table::INTERNAL);
00808 table::Placeholder *table= new table::Placeholder(this, identifier);
00809
00810 if (not table::Cache::singleton().insert(table))
00811 {
00812 safe_delete(table);
00813
00814 return NULL;
00815 }
00816
00817 return table;
00818 }
00819
00820
00842 bool Session::lock_table_name_if_not_cached(const identifier::Table &identifier, Table **table)
00843 {
00844 const identifier::Table::Key &key(identifier.getKey());
00845
00846 boost_unique_lock_t scope_lock(table::Cache::singleton().mutex());
00847
00848 if (find_ptr(table::getCache(), key))
00849 {
00850 *table= 0;
00851 return false;
00852 }
00853
00854 if (not (*table= table_cache_insert_placeholder(identifier)))
00855 {
00856 return true;
00857 }
00858 (*table)->open_placeholder= true;
00859 (*table)->setNext(open_tables);
00860 open_tables= *table;
00861
00862 return false;
00863 }
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 Table *Session::openTable(TableList *table_list, bool *refresh, uint32_t flags)
00899 {
00900 Table *table;
00901 const char *alias= table_list->alias;
00902
00903
00904 assert(lex().is_lex_started);
00905
00906
00907 if (refresh)
00908 *refresh= false;
00909
00910
00911 if (check_stack_overrun(this, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
00912 return NULL;
00913
00914 if (getKilled())
00915 return NULL;
00916
00917 identifier::Table identifier(table_list->getSchemaName(), table_list->getTableName());
00918 const identifier::Table::Key &key(identifier.getKey());
00919 table::CacheRange ppp;
00920
00921
00922
00923
00924
00925
00926
00927
00928 bool reset= false;
00929 for (table= getTemporaryTables(); table ; table=table->getNext())
00930 {
00931 if (table->getShare()->getCacheKey() == key)
00932 {
00933
00934
00935
00936
00937
00938
00939 if (table->query_id)
00940 {
00941 my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
00942 return NULL;
00943 }
00944 table->query_id= getQueryId();
00945 reset= true;
00946 break;
00947 }
00948 }
00949
00950 if (not reset)
00951 {
00952 if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
00953 {
00954 my_error(ER_TABLE_UNKNOWN, identifier);
00955 return NULL;
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967 if (!open_tables)
00968 {
00969 version= refresh_version;
00970 }
00971 else if ((version != refresh_version) &&
00972 ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
00973 {
00974
00975 if (refresh)
00976 *refresh= true;
00977
00978 return NULL;
00979 }
00980
00981
00982
00983
00984 if (cached_table)
00985 {
00986 assert(false);
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004 {
01005 boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017 ppp= table::getCache().equal_range(key);
01018
01019 table= NULL;
01020 for (table::CacheMap::const_iterator iter= ppp.first;
01021 iter != ppp.second; ++iter, table= NULL)
01022 {
01023 table= iter->second;
01024
01025 if (not table->in_use)
01026 break;
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045 if (table->needs_reopen_or_name_lock())
01046 {
01047 if (flags & DRIZZLE_LOCK_IGNORE_FLUSH)
01048 {
01049
01050 version= table->getShare()->getVersion();
01051 continue;
01052 }
01053
01054
01055 if (table->open_placeholder && table->in_use == this)
01056 {
01057 my_error(ER_UPDATE_TABLE_USED, MYF(0), table->getShare()->getTableName());
01058 return NULL;
01059 }
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070 close_old_data_files(false, false);
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 if (table->in_use != this)
01088 {
01089
01090 wait_for_condition(table::Cache::singleton().mutex(), COND_refresh);
01091 scopedLock.release();
01092 }
01093 else
01094 {
01095 scopedLock.unlock();
01096 }
01097
01098
01099
01100
01101
01102 if (refresh)
01103 *refresh= true;
01104
01105 return NULL;
01106 }
01107 }
01108
01109 if (table)
01110 {
01111 table::getUnused().unlink(static_cast<table::Concurrent *>(table));
01112 table->in_use= this;
01113 }
01114 else
01115 {
01116
01117 int error;
01118
01119 table::getUnused().cull();
01120
01121 if (table_list->isCreate())
01122 {
01123 identifier::Table lock_table_identifier(table_list->getSchemaName(), table_list->getTableName(), message::Table::STANDARD);
01124
01125 if (not plugin::StorageEngine::doesTableExist(*this, lock_table_identifier))
01126 {
01127
01128
01129
01130 if (!(table= table_cache_insert_placeholder(lock_table_identifier)))
01131 {
01132 return NULL;
01133 }
01134
01135
01136
01137
01138
01139 table->open_placeholder= true;
01140 table->setNext(open_tables);
01141 open_tables= table;
01142
01143 return table ;
01144 }
01145
01146 }
01147
01148
01149 {
01150 table::Concurrent *new_table= new table::Concurrent;
01151 table= new_table;
01152 if (new_table == NULL)
01153 {
01154 return NULL;
01155 }
01156
01157 error= new_table->open_unireg_entry(this, alias, identifier);
01158 if (error != 0)
01159 {
01160 delete new_table;
01161 return NULL;
01162 }
01163 (void)table::Cache::singleton().insert(new_table);
01164 }
01165 }
01166 }
01167
01168 if (refresh)
01169 {
01170 table->setNext(open_tables);
01171 open_tables= table;
01172 }
01173 table->reginfo.lock_type= TL_READ;
01174
01175 }
01176 assert(table->getShare()->getTableCount() > 0 || table->getShare()->getType() != message::Table::STANDARD);
01177
01178
01179 if (strcmp(table->getAlias(), alias))
01180 {
01181 table->setAlias(alias);
01182 }
01183
01184
01185 table->tablenr= current_tablenr++;
01186 table->used_fields= 0;
01187 table->const_table= 0;
01188 table->null_row= false;
01189 table->maybe_null= false;
01190 table->force_index= false;
01191 table->status=STATUS_NO_RECORD;
01192 table->insert_values.clear();
01193
01194 assert(!table->auto_increment_field_not_null);
01195 table->auto_increment_field_not_null= false;
01196 if (table->timestamp_field)
01197 {
01198 table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
01199 }
01200 table->pos_in_table_list= table_list;
01201 table->clear_column_bitmaps();
01202 assert(table->key_read == 0);
01203
01204 return table;
01205 }
01206
01207
01225 void Session::close_data_files_and_morph_locks(const identifier::Table &identifier)
01226 {
01227 safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
01228
01229 if (lock)
01230 {
01231
01232
01233
01234
01235 unlockTables(lock);
01236 lock= 0;
01237 }
01238
01239
01240
01241
01242
01243
01244 for (Table *table= open_tables; table ; table=table->getNext())
01245 {
01246 if (table->getShare()->getCacheKey() == identifier.getKey())
01247 {
01248 table->open_placeholder= true;
01249 close_handle_and_leave_table_as_lock(table);
01250 }
01251 }
01252 }
01253
01254
01275 bool Session::reopen_tables()
01276 {
01277 Table *table,*next,**prev;
01278 Table **tables= 0;
01279 Table **tables_ptr= 0;
01280 bool error= false;
01281 const uint32_t flags= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN |
01282 DRIZZLE_LOCK_IGNORE_GLOBAL_READ_LOCK |
01283 DRIZZLE_LOCK_IGNORE_FLUSH;
01284
01285 if (open_tables == NULL)
01286 return false;
01287
01288 safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
01289 {
01290
01291
01292
01293
01294 uint32_t opens= 0;
01295
01296 for (table= open_tables; table ; table=table->getNext())
01297 {
01298 opens++;
01299 }
01300 tables= new Table *[opens];
01301 }
01302
01303 tables_ptr =tables;
01304
01305 prev= &open_tables;
01306 for (table= open_tables; table ; table=next)
01307 {
01308 next= table->getNext();
01309
01310 my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->getAlias());
01311 table::remove_table(static_cast<table::Concurrent *>(table));
01312 error= 1;
01313 }
01314 *prev=0;
01315
01316 if (tables != tables_ptr)
01317 {
01318 DrizzleLock *local_lock;
01319
01320
01321
01322
01323
01324 some_tables_deleted= false;
01325
01326 if ((local_lock= lockTables(tables, (uint32_t) (tables_ptr - tables), flags)))
01327 {
01328
01329 }
01330 else
01331 {
01332
01333
01334
01335
01336
01337 my_error(ER_LOCK_DEADLOCK, MYF(0));
01338 error=1;
01339 }
01340 }
01341
01342 delete [] tables;
01343
01344 locking::broadcast_refresh();
01345
01346 return error;
01347 }
01348
01349
01364 void Session::close_old_data_files(bool morph_locks, bool send_refresh)
01365 {
01366 bool found= send_refresh;
01367
01368 Table *table= open_tables;
01369
01370 for (; table ; table=table->getNext())
01371 {
01372
01373
01374
01375 if (table->needs_reopen_or_name_lock())
01376 {
01377 found= true;
01378 if (table->db_stat)
01379 {
01380 if (morph_locks)
01381 {
01382 Table *ulcktbl= table;
01383 if (ulcktbl->lock_count)
01384 {
01385
01386
01387
01388
01389
01390
01391 abortLock(ulcktbl);
01392 removeLock(ulcktbl);
01393 ulcktbl->lock_count= 0;
01394 }
01395 if ((ulcktbl != table) && ulcktbl->db_stat)
01396 {
01397
01398
01399
01400
01401
01402
01403 ulcktbl->open_placeholder= true;
01404 close_handle_and_leave_table_as_lock(ulcktbl);
01405 }
01406
01407
01408
01409
01410 table->open_placeholder= true;
01411 }
01412 close_handle_and_leave_table_as_lock(table);
01413 }
01414 else if (table->open_placeholder && !morph_locks)
01415 {
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427 table->open_placeholder= false;
01428 }
01429 }
01430 }
01431 if (found)
01432 locking::broadcast_refresh();
01433 }
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
01461 {
01462 Table *table,*next,**prev, *found= 0;
01463 prev= &session->open_tables;
01464
01465
01466
01467
01468
01469
01470
01471
01472 for (table= session->open_tables; table ; table=next)
01473 {
01474 next=table->getNext();
01475 if (table->getShare()->getCacheKey() == identifier.getKey())
01476 {
01477 session->removeLock(table);
01478
01479 if (!found)
01480 {
01481 found= table;
01482
01483 if (table->db_stat)
01484 {
01485 table->db_stat= 0;
01486 table->cursor->close();
01487 }
01488 }
01489 else
01490 {
01491
01492 table::remove_table(static_cast<table::Concurrent *>(table));
01493 }
01494 }
01495 else
01496 {
01497 *prev=table;
01498 prev= table->getNextPtr();
01499 }
01500 }
01501 *prev=0;
01502
01503 if (found)
01504 locking::broadcast_refresh();
01505
01506 return found;
01507 }
01508
01509
01510
01511
01512
01513
01514
01515
01516 void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier)
01517 {
01518 Table *table;
01519 for (table= session->open_tables; table ; table= table->getNext())
01520 {
01521 if (table->getShare()->getCacheKey() == identifier.getKey())
01522 {
01523
01524 session->abortLock(table);
01525 assert(0);
01526 break;
01527 }
01528 }
01529 }
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560 int Session::open_tables_from_list(TableList **start, uint32_t *counter, uint32_t flags)
01561 {
01562 TableList *tables= NULL;
01563 bool refresh;
01564 int result= 0;
01565
01566 bool safe_to_ignore_table;
01567
01568 current_tablenr= 0;
01569 restart:
01570 *counter= 0;
01571 set_proc_info("Opening tables");
01572
01573
01574
01575
01576
01577 for (tables= *start; tables ;tables= tables->next_global)
01578 {
01579 safe_to_ignore_table= false;
01580
01581
01582
01583
01584
01585
01586
01587 if (tables->derived)
01588 {
01589 continue;
01590 }
01591 (*counter)++;
01592
01593
01594
01595
01596
01597
01598 identifier::Table the_table(tables->getSchemaName(), tables->getTableName());
01599 if (not plugin::Authorization::isAuthorized(*user(), the_table))
01600 {
01601 result= -1;
01602 break;
01603 }
01604
01605
01606
01607
01608
01609
01610 if (tables->table == NULL)
01611 tables->table= openTable(tables, &refresh, flags);
01612
01613 if (tables->table == NULL)
01614 {
01615 if (refresh)
01616 {
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631 close_tables_for_reopen(start);
01632 goto restart;
01633 }
01634
01635 if (safe_to_ignore_table)
01636 continue;
01637
01638 result= -1;
01639 break;
01640 }
01641 if (tables->lock_type != TL_UNLOCK)
01642 {
01643 if (tables->lock_type == TL_WRITE_DEFAULT)
01644 tables->table->reginfo.lock_type= update_lock_default;
01645 else if (tables->table->getShare()->getType() == message::Table::STANDARD)
01646 tables->table->reginfo.lock_type= tables->lock_type;
01647 }
01648 }
01649
01650 set_proc_info(0);
01651
01652 if (result && tables)
01653 {
01654
01655
01656
01657
01658 tables->table= NULL;
01659 }
01660
01661 return(result);
01662 }
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 Table *Session::openTableLock(TableList *table_list, thr_lock_type lock_type)
01690 {
01691 Table *table;
01692 bool refresh;
01693
01694 set_proc_info("Opening table");
01695 current_tablenr= 0;
01696 while (!(table= openTable(table_list, &refresh)) && refresh) ;
01697
01698 if (table)
01699 {
01700 table_list->lock_type= lock_type;
01701 table_list->table= table;
01702
01703 assert(lock == 0);
01704 if ((table->reginfo.lock_type= lock_type) != TL_UNLOCK)
01705 {
01706 if (not (lock= lockTables(&table_list->table, 1, 0)))
01707 table= NULL;
01708 }
01709 }
01710
01711 set_proc_info(0);
01712
01713 return table;
01714 }
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744 int Session::lock_tables(TableList *tables, uint32_t count, bool *need_reopen)
01745 {
01746 TableList *table;
01747 Session *session= this;
01748
01749
01750
01751
01752
01753 *need_reopen= false;
01754
01755 if (tables == NULL)
01756 return 0;
01757
01758 assert(session->lock == 0);
01759 Table **start,**ptr;
01760 uint32_t lock_flag= DRIZZLE_LOCK_NOTIFY_IF_NEED_REOPEN;
01761
01762 if (!(ptr=start=(Table**) session->getMemRoot()->allocate(sizeof(Table*)*count)))
01763 return -1;
01764
01765 for (table= tables; table; table= table->next_global)
01766 {
01767 if (!table->placeholder())
01768 *(ptr++)= table->table;
01769 }
01770
01771 if (not (session->lock= session->lockTables(start, (uint32_t) (ptr - start), lock_flag)))
01772 {
01773 return -1;
01774 }
01775
01776 return 0;
01777 }
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800 Table *Open_tables_state::open_temporary_table(const identifier::Table &identifier,
01801 bool link_in_list)
01802 {
01803 assert(identifier.isTmp());
01804
01805
01806 table::Temporary *new_tmp_table= new table::Temporary(identifier.getType(),
01807 identifier,
01808 const_cast<char *>(const_cast<identifier::Table&>(identifier).getPath().c_str()),
01809 static_cast<uint32_t>(identifier.getPath().length()));
01810 if (not new_tmp_table)
01811 return NULL;
01812
01813
01814
01815
01816 if (new_tmp_table->getMutableShare()->open_table_def(*static_cast<Session *>(this), identifier) ||
01817 new_tmp_table->getMutableShare()->open_table_from_share(static_cast<Session *>(this), identifier, identifier.getTableName().c_str(),
01818 (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
01819 HA_GET_INDEX),
01820 ha_open_options,
01821 *new_tmp_table))
01822 {
01823
01824 delete new_tmp_table->getMutableShare();
01825 delete new_tmp_table;
01826
01827 return 0;
01828 }
01829
01830 new_tmp_table->reginfo.lock_type= TL_WRITE;
01831
01832 if (link_in_list)
01833 {
01834
01835 new_tmp_table->setNext(this->temporary_tables);
01836 if (new_tmp_table->getNext())
01837 {
01838 new_tmp_table->getNext()->setPrev(new_tmp_table);
01839 }
01840 this->temporary_tables= new_tmp_table;
01841 this->temporary_tables->setPrev(0);
01842 }
01843 new_tmp_table->pos_in_table_list= 0;
01844
01845 return new_tmp_table;
01846 }
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859 Field *not_found_field= (Field*) 0x1;
01860 Field *view_ref_found= (Field*) 0x2;
01861
01862 static void update_field_dependencies(Session *session, Field *field, Table *table)
01863 {
01864 if (session->mark_used_columns != MARK_COLUMNS_NONE)
01865 {
01866 boost::dynamic_bitset<> *current_bitmap= NULL;
01867
01868
01869
01870
01871
01872
01873 table->covering_keys&= field->part_of_key;
01874 table->merge_keys|= field->part_of_key;
01875
01876 if (session->mark_used_columns == MARK_COLUMNS_READ)
01877 {
01878 current_bitmap= table->read_set;
01879 }
01880 else
01881 {
01882 current_bitmap= table->write_set;
01883 }
01884
01885
01886 if (current_bitmap->test(field->position()))
01887 {
01888 if (session->mark_used_columns == MARK_COLUMNS_WRITE)
01889 session->dup_field= field;
01890 return;
01891 }
01892 table->used_fields++;
01893 }
01894 }
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925 static Field *
01926 find_field_in_natural_join(Session *session, TableList *table_ref,
01927 const char *name, uint32_t , Item **,
01928 bool, TableList **actual_table)
01929 {
01930 List<Natural_join_column>::iterator
01931 field_it(table_ref->join_columns->begin());
01932 Natural_join_column *nj_col, *curr_nj_col;
01933 Field *found_field;
01934
01935 assert(table_ref->is_natural_join && table_ref->join_columns);
01936 assert(*actual_table == NULL);
01937
01938 for (nj_col= NULL, curr_nj_col= field_it++; curr_nj_col;
01939 curr_nj_col= field_it++)
01940 {
01941 if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name))
01942 {
01943 if (nj_col)
01944 {
01945 my_error(ER_NON_UNIQ_ERROR, MYF(0), name, session->where());
01946 return NULL;
01947 }
01948 nj_col= curr_nj_col;
01949 }
01950 }
01951 if (!nj_col)
01952 return NULL;
01953 {
01954
01955 assert(nj_col->table_ref->table == nj_col->table_field->getTable());
01956 found_field= nj_col->table_field;
01957 update_field_dependencies(session, found_field, nj_col->table_ref->table);
01958 }
01959
01960 *actual_table= nj_col->table_ref;
01961
01962 return(found_field);
01963 }
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984 Field *
01985 find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
01986 bool allow_rowid, uint32_t *cached_field_index_ptr)
01987 {
01988 Field **field_ptr, *field;
01989 uint32_t cached_field_index= *cached_field_index_ptr;
01990
01991
01992 if (cached_field_index < table->getShare()->sizeFields() &&
01993 !my_strcasecmp(system_charset_info,
01994 table->getField(cached_field_index)->field_name, name))
01995 {
01996 field_ptr= table->getFields() + cached_field_index;
01997 }
01998 else if (table->getShare()->getNamedFieldSize())
01999 {
02000 field_ptr= table->getMutableShare()->getNamedField(std::string(name, length));
02001 if (field_ptr)
02002 {
02003
02004
02005
02006
02007 field_ptr= (table->getFields() + table->getShare()->positionFields(field_ptr));
02008 }
02009 }
02010 else
02011 {
02012 if (!(field_ptr= table->getFields()))
02013 return((Field *)0);
02014 for (; *field_ptr; ++field_ptr)
02015 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
02016 break;
02017 }
02018
02019 if (field_ptr && *field_ptr)
02020 {
02021 *cached_field_index_ptr= field_ptr - table->getFields();
02022 field= *field_ptr;
02023 }
02024 else
02025 {
02026 if (!allow_rowid ||
02027 my_strcasecmp(system_charset_info, name, "_rowid") ||
02028 table->getShare()->rowid_field_offset == 0)
02029 return((Field*) 0);
02030 field= table->getField(table->getShare()->rowid_field_offset-1);
02031 }
02032
02033 update_field_dependencies(session, field, table);
02034
02035 return field;
02036 }
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080 Field *
02081 find_field_in_table_ref(Session *session, TableList *table_list,
02082 const char *name, uint32_t length,
02083 const char *item_name, const char *db_name,
02084 const char *table_name, Item **ref,
02085 bool allow_rowid,
02086 uint32_t *cached_field_index_ptr,
02087 bool register_tree_change, TableList **actual_table)
02088 {
02089 Field *fld= NULL;
02090
02091 assert(table_list->alias);
02092 assert(name);
02093 assert(item_name);
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 if (
02112 (!table_list->getNestedJoin()) &&
02113
02114
02115
02116
02117
02118 table_name && table_name[0] &&
02119 (my_strcasecmp(table_alias_charset, table_list->alias, table_name) ||
02120 (db_name && db_name[0] && table_list->getSchemaName() && table_list->getSchemaName()[0] &&
02121 strcmp(db_name, table_list->getSchemaName()))))
02122 return 0;
02123
02124 *actual_table= NULL;
02125
02126 if (!table_list->getNestedJoin())
02127 {
02128
02129 assert(table_list->table);
02130 if ((fld= find_field_in_table(session, table_list->table, name, length,
02131 allow_rowid,
02132 cached_field_index_ptr)))
02133 *actual_table= table_list;
02134 }
02135 else
02136 {
02137
02138
02139
02140
02141
02142
02143
02144 if (table_name && table_name[0])
02145 {
02146 List<TableList>::iterator it(table_list->getNestedJoin()->join_list.begin());
02147 TableList *table;
02148 while ((table= it++))
02149 {
02150 if ((fld= find_field_in_table_ref(session, table, name, length, item_name,
02151 db_name, table_name, ref,
02152 allow_rowid,
02153 cached_field_index_ptr,
02154 register_tree_change, actual_table)))
02155 return fld;
02156 }
02157 return NULL;
02158 }
02159
02160
02161
02162
02163
02164
02165 fld= find_field_in_natural_join(session, table_list, name, length, ref,
02166 register_tree_change, actual_table);
02167 }
02168
02169 if (fld)
02170 {
02171 if (session->mark_used_columns != MARK_COLUMNS_NONE)
02172 {
02173
02174
02175
02176
02177
02178 Field *field_to_set= NULL;
02179 if (fld == view_ref_found)
02180 {
02181 Item *it= (*ref)->real_item();
02182 if (it->type() == Item::FIELD_ITEM)
02183 field_to_set= ((Item_field*)it)->field;
02184 else
02185 {
02186 if (session->mark_used_columns == MARK_COLUMNS_READ)
02187 it->walk(&Item::register_field_in_read_map, 1, (unsigned char *) 0);
02188 }
02189 }
02190 else
02191 field_to_set= fld;
02192 if (field_to_set)
02193 {
02194 Table *table= field_to_set->getTable();
02195 if (session->mark_used_columns == MARK_COLUMNS_READ)
02196 table->setReadSet(field_to_set->position());
02197 else
02198 table->setWriteSet(field_to_set->position());
02199 }
02200 }
02201 }
02202 return(fld);
02203 }
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239 Field *
02240 find_field_in_tables(Session *session, Item_ident *item,
02241 TableList *first_table, TableList *last_table,
02242 Item **ref, find_item_error_report_type report_error,
02243 bool register_tree_change)
02244 {
02245 Field *found=0;
02246 const char *db= item->db_name;
02247 const char *table_name= item->table_name;
02248 const char *name= item->field_name;
02249 uint32_t length=(uint32_t) strlen(name);
02250 char name_buff[NAME_LEN+1];
02251 TableList *cur_table= first_table;
02252 TableList *actual_table;
02253 bool allow_rowid;
02254
02255 if (!table_name || !table_name[0])
02256 {
02257 table_name= 0;
02258 db= 0;
02259 }
02260
02261 allow_rowid= table_name || (cur_table && !cur_table->next_local);
02262
02263 if (item->cached_table)
02264 {
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274 TableList *table_ref= item->cached_table;
02275
02276
02277
02278
02279
02280 if (table_ref->table)
02281 found= find_field_in_table(session, table_ref->table, name, length,
02282 true, &(item->cached_field_index));
02283 else
02284 found= find_field_in_table_ref(session, table_ref, name, length, item->name,
02285 NULL, NULL, ref,
02286 true, &(item->cached_field_index),
02287 register_tree_change,
02288 &actual_table);
02289 if (found)
02290 {
02291
02292
02293
02294
02295 {
02296 Select_Lex *current_sel= session->lex().current_select;
02297 Select_Lex *last_select= table_ref->select_lex;
02298
02299
02300
02301
02302 if (current_sel != last_select)
02303 mark_select_range_as_dependent(session, last_select, current_sel,
02304 found, *ref, item);
02305 }
02306 return found;
02307 }
02308 }
02309
02310 if (db)
02311 {
02312
02313
02314
02315
02316
02317 strncpy(name_buff, db, sizeof(name_buff)-1);
02318 my_casedn_str(files_charset_info, name_buff);
02319 db= name_buff;
02320 }
02321
02322 if (last_table)
02323 last_table= last_table->next_name_resolution_table;
02324
02325 for (; cur_table != last_table ;
02326 cur_table= cur_table->next_name_resolution_table)
02327 {
02328 Field *cur_field= find_field_in_table_ref(session, cur_table, name, length,
02329 item->name, db, table_name, ref,
02330 allow_rowid,
02331 &(item->cached_field_index),
02332 register_tree_change,
02333 &actual_table);
02334 if (cur_field)
02335 {
02336
02337
02338
02339
02340 item->cached_table= found ? 0 : actual_table;
02341
02342 assert(session->where());
02343
02344
02345
02346
02347 if (db)
02348 return cur_field;
02349
02350 if (found)
02351 {
02352 if (report_error == REPORT_ALL_ERRORS ||
02353 report_error == IGNORE_EXCEPT_NON_UNIQUE)
02354 my_error(ER_NON_UNIQ_ERROR, MYF(0),
02355 table_name ? item->full_name() : name, session->where());
02356 return (Field*) 0;
02357 }
02358 found= cur_field;
02359 }
02360 }
02361
02362 if (found)
02363 return found;
02364
02365
02366
02367
02368
02369
02370
02371
02372 if (table_name && (cur_table == first_table) &&
02373 (report_error == REPORT_ALL_ERRORS ||
02374 report_error == REPORT_EXCEPT_NON_UNIQUE))
02375 {
02376 char buff[NAME_LEN*2+1];
02377 if (db && db[0])
02378 {
02379
02380
02381 assert(strlen(db) <= NAME_LEN);
02382 assert(strlen(table_name) <= NAME_LEN);
02383 strcpy(buff, db);
02384 strcat(buff,".");
02385 strcat(buff, table_name);
02386 table_name=buff;
02387 }
02388 my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, session->where());
02389 }
02390 else
02391 {
02392 if (report_error == REPORT_ALL_ERRORS ||
02393 report_error == REPORT_EXCEPT_NON_UNIQUE)
02394 my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), session->where());
02395 else
02396 found= not_found_field;
02397 }
02398 return found;
02399 }
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436 Item **not_found_item= (Item**) 0x1;
02437
02438
02439 Item **
02440 find_item_in_list(Session *session,
02441 Item *find, List<Item> &items, uint32_t *counter,
02442 find_item_error_report_type report_error,
02443 enum_resolution_type *resolution)
02444 {
02445 List<Item>::iterator li(items.begin());
02446 Item **found=0, **found_unaliased= 0, *item;
02447 const char *db_name=0;
02448 const char *field_name=0;
02449 const char *table_name=0;
02450 bool found_unaliased_non_uniq= 0;
02451
02452
02453
02454
02455 bool is_ref_by_name= 0;
02456 uint32_t unaliased_counter= 0;
02457
02458 *resolution= NOT_RESOLVED;
02459
02460 is_ref_by_name= (find->type() == Item::FIELD_ITEM ||
02461 find->type() == Item::REF_ITEM);
02462 if (is_ref_by_name)
02463 {
02464 field_name= ((Item_ident*) find)->field_name;
02465 table_name= ((Item_ident*) find)->table_name;
02466 db_name= ((Item_ident*) find)->db_name;
02467 }
02468
02469 for (uint32_t i= 0; (item=li++); i++)
02470 {
02471 if (field_name && item->real_item()->type() == Item::FIELD_ITEM)
02472 {
02473 Item_ident *item_field= (Item_ident*) item;
02474
02475
02476
02477
02478
02479
02480
02481 if (!item_field->name)
02482 continue;
02483
02484 if (table_name)
02485 {
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502 if (item_field->field_name && item_field->table_name &&
02503 !my_strcasecmp(system_charset_info, item_field->field_name,
02504 field_name) &&
02505 !my_strcasecmp(table_alias_charset, item_field->table_name,
02506 table_name) &&
02507 (!db_name || (item_field->db_name &&
02508 !strcmp(item_field->db_name, db_name))))
02509 {
02510 if (found_unaliased)
02511 {
02512 if ((*found_unaliased)->eq(item, 0))
02513 continue;
02514
02515
02516
02517
02518
02519 if (report_error != IGNORE_ERRORS)
02520 my_error(ER_NON_UNIQ_ERROR, MYF(0),
02521 find->full_name(), session->where());
02522 return (Item**) 0;
02523 }
02524 found_unaliased= li.ref();
02525 unaliased_counter= i;
02526 *resolution= RESOLVED_IGNORING_ALIAS;
02527 if (db_name)
02528 break;
02529 }
02530 }
02531 else
02532 {
02533 int fname_cmp= my_strcasecmp(system_charset_info,
02534 item_field->field_name,
02535 field_name);
02536 if (!my_strcasecmp(system_charset_info,
02537 item_field->name,field_name))
02538 {
02539
02540
02541
02542
02543
02544
02545
02546 if (found)
02547 {
02548 if ((*found)->eq(item, 0))
02549 continue;
02550 if (report_error != IGNORE_ERRORS)
02551 my_error(ER_NON_UNIQ_ERROR, MYF(0),
02552 find->full_name(), session->where());
02553 return (Item**) 0;
02554 }
02555 found= li.ref();
02556 *counter= i;
02557 *resolution= fname_cmp ? RESOLVED_AGAINST_ALIAS:
02558 RESOLVED_WITH_NO_ALIAS;
02559 }
02560 else if (!fname_cmp)
02561 {
02562
02563
02564
02565
02566
02567
02568 if (found_unaliased)
02569 {
02570 if ((*found_unaliased)->eq(item, 0))
02571 continue;
02572 found_unaliased_non_uniq= 1;
02573 }
02574 found_unaliased= li.ref();
02575 unaliased_counter= i;
02576 }
02577 }
02578 }
02579 else if (!table_name)
02580 {
02581 if (is_ref_by_name && find->name && item->name &&
02582 !my_strcasecmp(system_charset_info,item->name,find->name))
02583 {
02584 found= li.ref();
02585 *counter= i;
02586 *resolution= RESOLVED_AGAINST_ALIAS;
02587 break;
02588 }
02589 else if (find->eq(item,0))
02590 {
02591 found= li.ref();
02592 *counter= i;
02593 *resolution= RESOLVED_IGNORING_ALIAS;
02594 break;
02595 }
02596 }
02597 }
02598 if (!found)
02599 {
02600 if (found_unaliased_non_uniq)
02601 {
02602 if (report_error != IGNORE_ERRORS)
02603 my_error(ER_NON_UNIQ_ERROR, MYF(0),
02604 find->full_name(), session->where());
02605 return (Item **) 0;
02606 }
02607 if (found_unaliased)
02608 {
02609 found= found_unaliased;
02610 *counter= unaliased_counter;
02611 *resolution= RESOLVED_BEHIND_ALIAS;
02612 }
02613 }
02614 if (found)
02615 return found;
02616 if (report_error != REPORT_EXCEPT_NOT_FOUND)
02617 {
02618 if (report_error == REPORT_ALL_ERRORS)
02619 my_error(ER_BAD_FIELD_ERROR, MYF(0),
02620 find->full_name(), session->where());
02621 return (Item **) 0;
02622 }
02623 else
02624 return (Item **) not_found_item;
02625 }
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645 static bool
02646 test_if_string_in_list(const char *find, List<String> *str_list)
02647 {
02648 List<String>::iterator str_list_it(str_list->begin());
02649 String *curr_str;
02650 size_t find_length= strlen(find);
02651 while ((curr_str= str_list_it++))
02652 {
02653 if (find_length != curr_str->length())
02654 continue;
02655 if (!my_strcasecmp(system_charset_info, find, curr_str->ptr()))
02656 return true;
02657 }
02658 return false;
02659 }
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681 static bool
02682 set_new_item_local_context(Session *session, Item_ident *item, TableList *table_ref)
02683 {
02684 Name_resolution_context *context;
02685 if (!(context= new (session->mem_root) Name_resolution_context))
02686 return true;
02687 context->init();
02688 context->first_name_resolution_table=
02689 context->last_name_resolution_table= table_ref;
02690 item->context= context;
02691 return false;
02692 }
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726 static bool
02727 mark_common_columns(Session *session, TableList *table_ref_1, TableList *table_ref_2,
02728 List<String> *using_fields, uint32_t *found_using_fields)
02729 {
02730 Field_iterator_table_ref it_1, it_2;
02731 Natural_join_column *nj_col_1, *nj_col_2;
02732 bool result= true;
02733 bool first_outer_loop= true;
02734
02735
02736
02737
02738 TableList *leaf_1= (table_ref_1->getNestedJoin() &&
02739 ! table_ref_1->is_natural_join) ?
02740 NULL : table_ref_1;
02741 TableList *leaf_2= (table_ref_2->getNestedJoin() &&
02742 ! table_ref_2->is_natural_join) ?
02743 NULL : table_ref_2;
02744
02745 *found_using_fields= 0;
02746
02747 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
02748 {
02749 bool found= false;
02750 const char *field_name_1;
02751
02752 bool is_using_column_1;
02753 if (!(nj_col_1= it_1.get_or_create_column_ref(leaf_1)))
02754 return(result);
02755 field_name_1= nj_col_1->name();
02756 is_using_column_1= using_fields &&
02757 test_if_string_in_list(field_name_1, using_fields);
02758
02759
02760
02761
02762
02763
02764
02765
02766 nj_col_2= NULL;
02767 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next())
02768 {
02769 Natural_join_column *cur_nj_col_2;
02770 const char *cur_field_name_2;
02771 if (!(cur_nj_col_2= it_2.get_or_create_column_ref(leaf_2)))
02772 return(result);
02773 cur_field_name_2= cur_nj_col_2->name();
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786 if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2))
02787 {
02788 if (cur_nj_col_2->is_common ||
02789 (found && (!using_fields || is_using_column_1)))
02790 {
02791 my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, session->where());
02792 return(result);
02793 }
02794 nj_col_2= cur_nj_col_2;
02795 found= true;
02796 }
02797 }
02798 if (first_outer_loop && leaf_2)
02799 {
02800
02801
02802
02803
02804 leaf_2->is_join_columns_complete= true;
02805 first_outer_loop= false;
02806 }
02807 if (!found)
02808 continue;
02809
02810
02811
02812
02813
02814
02815 if (nj_col_2 && (!using_fields ||is_using_column_1))
02816 {
02817 Item *item_1= nj_col_1->create_item(session);
02818 Item *item_2= nj_col_2->create_item(session);
02819 Field *field_1= nj_col_1->field();
02820 Field *field_2= nj_col_2->field();
02821 Item_ident *item_ident_1, *item_ident_2;
02822 Item_func_eq *eq_cond;
02823
02824 if (!item_1 || !item_2)
02825 return(result);
02826
02827
02828
02829
02830
02831 assert(item_1->type() == Item::FIELD_ITEM ||
02832 item_1->type() == Item::REF_ITEM);
02833 assert(item_2->type() == Item::FIELD_ITEM ||
02834 item_2->type() == Item::REF_ITEM);
02835
02836
02837
02838
02839
02840 item_ident_1= (Item_ident*) item_1;
02841 item_ident_2= (Item_ident*) item_2;
02842
02843
02844
02845
02846
02847
02848 if (set_new_item_local_context(session, item_ident_1, nj_col_1->table_ref) ||
02849 set_new_item_local_context(session, item_ident_2, nj_col_2->table_ref))
02850 return(result);
02851
02852 if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2)))
02853 return(result);
02854
02855
02856
02857
02858
02859
02860 add_join_on((table_ref_1->outer_join & JOIN_TYPE_RIGHT ?
02861 table_ref_1 : table_ref_2),
02862 eq_cond);
02863
02864 nj_col_1->is_common= nj_col_2->is_common= true;
02865
02866 if (field_1)
02867 {
02868 Table *table_1= nj_col_1->table_ref->table;
02869
02870 table_1->setReadSet(field_1->position());
02871 table_1->covering_keys&= field_1->part_of_key;
02872 table_1->merge_keys|= field_1->part_of_key;
02873 }
02874 if (field_2)
02875 {
02876 Table *table_2= nj_col_2->table_ref->table;
02877
02878 table_2->setReadSet(field_2->position());
02879 table_2->covering_keys&= field_2->part_of_key;
02880 table_2->merge_keys|= field_2->part_of_key;
02881 }
02882
02883 if (using_fields != NULL)
02884 ++(*found_using_fields);
02885 }
02886 }
02887 if (leaf_1)
02888 leaf_1->is_join_columns_complete= true;
02889
02890
02891
02892
02893
02894
02895
02896
02897 result= false;
02898
02899 return(result);
02900 }
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939 static bool
02940 store_natural_using_join_columns(Session *session,
02941 TableList *natural_using_join,
02942 TableList *table_ref_1,
02943 TableList *table_ref_2,
02944 List<String> *using_fields,
02945 uint32_t found_using_fields)
02946 {
02947 Field_iterator_table_ref it_1, it_2;
02948 Natural_join_column *nj_col_1, *nj_col_2;
02949 bool result= true;
02950 List<Natural_join_column> *non_join_columns;
02951
02952 assert(!natural_using_join->join_columns);
02953
02954 if (!(non_join_columns= new List<Natural_join_column>) ||
02955 !(natural_using_join->join_columns= new List<Natural_join_column>))
02956 {
02957 return(result);
02958 }
02959
02960
02961 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
02962 {
02963 nj_col_1= it_1.get_natural_column_ref();
02964 if (nj_col_1->is_common)
02965 {
02966 natural_using_join->join_columns->push_back(nj_col_1);
02967
02968 nj_col_1->is_common= false;
02969 }
02970 else
02971 non_join_columns->push_back(nj_col_1);
02972 }
02973
02974
02975
02976
02977
02978
02979 if (using_fields && found_using_fields < using_fields->size())
02980 {
02981 String *using_field_name;
02982 List<String>::iterator using_fields_it(using_fields->begin());
02983 while ((using_field_name= using_fields_it++))
02984 {
02985 const char *using_field_name_ptr= using_field_name->c_ptr();
02986 List<Natural_join_column>::iterator
02987 it(natural_using_join->join_columns->begin());
02988 Natural_join_column *common_field;
02989
02990 for (;;)
02991 {
02992
02993 if (!(common_field= it++))
02994 {
02995 my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
02996 session->where());
02997 return(result);
02998 }
02999 if (!my_strcasecmp(system_charset_info,
03000 common_field->name(), using_field_name_ptr))
03001 break;
03002 }
03003 }
03004 }
03005
03006
03007 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next())
03008 {
03009 nj_col_2= it_2.get_natural_column_ref();
03010 if (!nj_col_2->is_common)
03011 non_join_columns->push_back(nj_col_2);
03012 else
03013 {
03014
03015 nj_col_2->is_common= false;
03016 }
03017 }
03018
03019 if (non_join_columns->size() > 0)
03020 natural_using_join->join_columns->concat(non_join_columns);
03021 natural_using_join->is_join_columns_complete= true;
03022
03023 result= false;
03024
03025 return(result);
03026 }
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059 static bool
03060 store_top_level_join_columns(Session *session, TableList *table_ref,
03061 TableList *left_neighbor,
03062 TableList *right_neighbor)
03063 {
03064 bool result= true;
03065
03066
03067 if (table_ref->getNestedJoin())
03068 {
03069 List<TableList>::iterator nested_it(table_ref->getNestedJoin()->join_list.begin());
03070 TableList *same_level_left_neighbor= nested_it++;
03071 TableList *same_level_right_neighbor= NULL;
03072
03073 TableList *real_left_neighbor, *real_right_neighbor;
03074
03075 while (same_level_left_neighbor)
03076 {
03077 TableList *cur_table_ref= same_level_left_neighbor;
03078 same_level_left_neighbor= nested_it++;
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089
03090 if (same_level_left_neighbor &&
03091 cur_table_ref->outer_join & JOIN_TYPE_RIGHT)
03092 {
03093
03094 assert(table_ref->getNestedJoin()->join_list.size() == 2);
03095 std::swap(same_level_left_neighbor, cur_table_ref);
03096 }
03097
03098
03099
03100
03101
03102 real_left_neighbor= (same_level_left_neighbor) ?
03103 same_level_left_neighbor : left_neighbor;
03104 real_right_neighbor= (same_level_right_neighbor) ?
03105 same_level_right_neighbor : right_neighbor;
03106
03107 if (cur_table_ref->getNestedJoin() &&
03108 store_top_level_join_columns(session, cur_table_ref,
03109 real_left_neighbor, real_right_neighbor))
03110 return(result);
03111 same_level_right_neighbor= cur_table_ref;
03112 }
03113 }
03114
03115
03116
03117
03118
03119 if (table_ref->is_natural_join)
03120 {
03121 assert(table_ref->getNestedJoin() &&
03122 table_ref->getNestedJoin()->join_list.size() == 2);
03123 List<TableList>::iterator operand_it(table_ref->getNestedJoin()->join_list.begin());
03124
03125
03126
03127
03128
03129 TableList *table_ref_2= operand_it++;
03130 TableList *table_ref_1= operand_it++;
03131 List<String> *using_fields= table_ref->join_using_fields;
03132 uint32_t found_using_fields;
03133
03134
03135
03136
03137
03138 if (table_ref_2->outer_join & JOIN_TYPE_RIGHT)
03139 std::swap(table_ref_1, table_ref_2);
03140 if (mark_common_columns(session, table_ref_1, table_ref_2,
03141 using_fields, &found_using_fields))
03142 return(result);
03143
03144
03145
03146
03147
03148
03149 if (table_ref_1->outer_join & JOIN_TYPE_RIGHT)
03150 std::swap(table_ref_1, table_ref_2);
03151 if (store_natural_using_join_columns(session, table_ref, table_ref_1,
03152 table_ref_2, using_fields,
03153 found_using_fields))
03154 return(result);
03155
03156
03157
03158
03159
03160
03161
03162 table_ref_1->natural_join= table_ref_2->natural_join= NULL;
03163
03164
03165 if (table_ref_2->outer_join &&
03166 !table_ref_1->on_expr && !table_ref_2->on_expr)
03167 table_ref_2->on_expr= new Item_int((int64_t) 1,1);
03168
03169
03170 if (left_neighbor)
03171 {
03172 TableList *last_leaf_on_the_left;
03173 last_leaf_on_the_left= left_neighbor->last_leaf_for_name_resolution();
03174 last_leaf_on_the_left->next_name_resolution_table= table_ref;
03175 }
03176 if (right_neighbor)
03177 {
03178 TableList *first_leaf_on_the_right;
03179 first_leaf_on_the_right= right_neighbor->first_leaf_for_name_resolution();
03180 table_ref->next_name_resolution_table= first_leaf_on_the_right;
03181 }
03182 else
03183 table_ref->next_name_resolution_table= NULL;
03184 }
03185 result= false;
03186
03187 return(result);
03188 }
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215 static bool setup_natural_join_row_types(Session *session,
03216 List<TableList> *from_clause,
03217 Name_resolution_context *context)
03218 {
03219 session->setWhere("from clause");
03220 if (from_clause->size() == 0)
03221 return false;
03222
03223 List<TableList>::iterator table_ref_it(from_clause->begin());
03224 TableList *table_ref;
03225
03226 TableList *left_neighbor;
03227
03228 TableList *right_neighbor= NULL;
03229
03230
03231 for (left_neighbor= table_ref_it++; left_neighbor ; )
03232 {
03233 table_ref= left_neighbor;
03234 left_neighbor= table_ref_it++;
03235 if (store_top_level_join_columns(session, table_ref,
03236 left_neighbor, right_neighbor))
03237 return true;
03238 if (left_neighbor)
03239 {
03240 TableList *first_leaf_on_the_right;
03241 first_leaf_on_the_right= table_ref->first_leaf_for_name_resolution();
03242 left_neighbor->next_name_resolution_table= first_leaf_on_the_right;
03243 }
03244 right_neighbor= table_ref;
03245 }
03246
03247
03248
03249
03250
03251
03252
03253 assert(right_neighbor);
03254 context->first_name_resolution_table=
03255 right_neighbor->first_leaf_for_name_resolution();
03256
03257 return false;
03258 }
03259
03260
03261
03262
03263
03264
03265 int setup_wild(Session *session, List<Item> &fields,
03266 List<Item> *sum_func_list,
03267 uint32_t wild_num)
03268 {
03269 if (!wild_num)
03270 return 0;
03271
03272 Item *item;
03273 List<Item>::iterator it(fields.begin());
03274
03275 session->lex().current_select->cur_pos_in_select_list= 0;
03276 while (wild_num && (item= it++))
03277 {
03278 if (item->type() == Item::FIELD_ITEM &&
03279 ((Item_field*) item)->field_name &&
03280 ((Item_field*) item)->field_name[0] == '*' &&
03281 !((Item_field*) item)->field)
03282 {
03283 uint32_t elem= fields.size();
03284 bool any_privileges= ((Item_field *) item)->any_privileges;
03285 Item_subselect *subsel= session->lex().current_select->master_unit()->item;
03286 if (subsel &&
03287 subsel->substype() == Item_subselect::EXISTS_SUBS)
03288 {
03289
03290
03291
03292
03293
03294 it.replace(new Item_int("Not_used", (int64_t) 1,
03295 MY_INT64_NUM_DECIMAL_DIGITS));
03296 }
03297 else if (insert_fields(session, ((Item_field*) item)->context,
03298 ((Item_field*) item)->db_name,
03299 ((Item_field*) item)->table_name, &it,
03300 any_privileges))
03301 {
03302 return -1;
03303 }
03304 if (sum_func_list)
03305 {
03306
03307
03308
03309
03310
03311 sum_func_list->set_size(sum_func_list->size() + fields.size() - elem);
03312 }
03313 wild_num--;
03314 }
03315 else
03316 session->lex().current_select->cur_pos_in_select_list++;
03317 }
03318 session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
03319
03320 return 0;
03321 }
03322
03323
03324
03325
03326
03327 bool setup_fields(Session *session, Item **ref_pointer_array,
03328 List<Item> &fields, enum_mark_columns mark_used_columns,
03329 List<Item> *sum_func_list, bool allow_sum_func)
03330 {
03331 register Item *item;
03332 enum_mark_columns save_mark_used_columns= session->mark_used_columns;
03333 nesting_map save_allow_sum_func= session->lex().allow_sum_func;
03334 List<Item>::iterator it(fields.begin());
03335 bool save_is_item_list_lookup;
03336
03337 session->mark_used_columns= mark_used_columns;
03338 if (allow_sum_func)
03339 session->lex().allow_sum_func|= 1 << session->lex().current_select->nest_level;
03340 session->setWhere(Session::DEFAULT_WHERE);
03341 save_is_item_list_lookup= session->lex().current_select->is_item_list_lookup;
03342 session->lex().current_select->is_item_list_lookup= 0;
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354 if (ref_pointer_array)
03355 {
03356 memset(ref_pointer_array, 0, sizeof(Item *) * fields.size());
03357 }
03358
03359 Item **ref= ref_pointer_array;
03360 session->lex().current_select->cur_pos_in_select_list= 0;
03361 while ((item= it++))
03362 {
03363 if ((!item->fixed && item->fix_fields(session, it.ref())) || (item= *(it.ref()))->check_cols(1))
03364 {
03365 session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
03366 session->lex().allow_sum_func= save_allow_sum_func;
03367 session->mark_used_columns= save_mark_used_columns;
03368 return true;
03369 }
03370 if (ref)
03371 *(ref++)= item;
03372 if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
03373 sum_func_list)
03374 item->split_sum_func(session, ref_pointer_array, *sum_func_list);
03375 session->used_tables|= item->used_tables();
03376 session->lex().current_select->cur_pos_in_select_list++;
03377 }
03378 session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
03379 session->lex().current_select->cur_pos_in_select_list= UNDEF_POS;
03380
03381 session->lex().allow_sum_func= save_allow_sum_func;
03382 session->mark_used_columns= save_mark_used_columns;
03383 return(test(session->is_error()));
03384 }
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398 static TableList **make_leaves_list(TableList **list, TableList *tables)
03399 {
03400 for (TableList *table= tables; table; table= table->next_local)
03401 {
03402 {
03403 *list= table;
03404 list= &table->next_leaf;
03405 }
03406 }
03407 return list;
03408 }
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438 bool setup_tables(Session *session, Name_resolution_context *context,
03439 List<TableList> *from_clause, TableList *tables,
03440 TableList **leaves, bool select_insert)
03441 {
03442 uint32_t tablenr= 0;
03443
03444 assert ((select_insert && !tables->next_name_resolution_table) || !tables ||
03445 (context->table_list && context->first_name_resolution_table));
03446
03447
03448
03449
03450 TableList *first_select_table= (select_insert ? tables->next_local: NULL);
03451
03452 if (!(*leaves))
03453 make_leaves_list(leaves, tables);
03454
03455 TableList *table_list;
03456 for (table_list= *leaves;
03457 table_list;
03458 table_list= table_list->next_leaf, tablenr++)
03459 {
03460 Table *table= table_list->table;
03461 table->pos_in_table_list= table_list;
03462 if (first_select_table &&
03463 table_list->top_table() == first_select_table)
03464 {
03465
03466 first_select_table= 0;
03467 tablenr= 0;
03468 }
03469 table->setup_table_map(table_list, tablenr);
03470 if (table_list->process_index_hints(table))
03471 return 1;
03472 }
03473 if (tablenr > MAX_TABLES)
03474 {
03475 my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
03476 return 1;
03477 }
03478
03479
03480 if (setup_natural_join_row_types(session, from_clause, context))
03481 return 1;
03482
03483 return 0;
03484 }
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510 bool setup_tables_and_check_access(Session *session,
03511 Name_resolution_context *context,
03512 List<TableList> *from_clause,
03513 TableList *tables,
03514 TableList **leaves,
03515 bool select_insert)
03516 {
03517 TableList *leaves_tmp= NULL;
03518
03519 if (setup_tables(session, context, from_clause, tables,
03520 &leaves_tmp, select_insert))
03521 return true;
03522
03523 if (leaves)
03524 *leaves= leaves_tmp;
03525
03526 return false;
03527 }
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548 bool
03549 insert_fields(Session *session, Name_resolution_context *context, const char *db_name,
03550 const char *table_name, List<Item>::iterator *it,
03551 bool )
03552 {
03553 Field_iterator_table_ref field_iterator;
03554 bool found;
03555 char name_buff[NAME_LEN+1];
03556
03557 if (db_name)
03558 {
03559
03560
03561
03562
03563
03564 strncpy(name_buff, db_name, sizeof(name_buff)-1);
03565 my_casedn_str(files_charset_info, name_buff);
03566 db_name= name_buff;
03567 }
03568
03569 found= false;
03570
03571
03572
03573
03574
03575
03576 for (TableList *tables= (table_name ? context->table_list :
03577 context->first_name_resolution_table);
03578 tables;
03579 tables= (table_name ? tables->next_local :
03580 tables->next_name_resolution_table)
03581 )
03582 {
03583 Field *field;
03584 Table *table= tables->table;
03585
03586 assert(tables->is_leaf_for_name_resolution());
03587
03588 if ((table_name && my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
03589 (db_name && my_strcasecmp(system_charset_info, tables->getSchemaName(),db_name)))
03590 continue;
03591
03592
03593
03594
03595
03596 if (table)
03597 session->used_tables|= table->map;
03598
03599
03600
03601
03602
03603
03604
03605 field_iterator.set(tables);
03606
03607 for (; !field_iterator.end_of_fields(); field_iterator.next())
03608 {
03609 Item *item;
03610
03611 if (!(item= field_iterator.create_item(session)))
03612 return true;
03613
03614 if (!found)
03615 {
03616 found= true;
03617 it->replace(item);
03618 }
03619 else
03620 it->after(item);
03621
03622 if ((field= field_iterator.field()))
03623 {
03624
03625 field->getTable()->setReadSet(field->position());
03626 if (table)
03627 {
03628 table->covering_keys&= field->part_of_key;
03629 table->merge_keys|= field->part_of_key;
03630 }
03631 if (tables->is_natural_join)
03632 {
03633 Table *field_table;
03634
03635
03636
03637
03638 Natural_join_column *nj_col;
03639 if (!(nj_col= field_iterator.get_natural_column_ref()))
03640 return true;
03641 assert(nj_col->table_field);
03642 field_table= nj_col->table_ref->table;
03643 if (field_table)
03644 {
03645 session->used_tables|= field_table->map;
03646 field_table->covering_keys&= field->part_of_key;
03647 field_table->merge_keys|= field->part_of_key;
03648 field_table->used_fields++;
03649 }
03650 }
03651 }
03652 else
03653 {
03654 session->used_tables|= item->used_tables();
03655 }
03656
03657 session->lex().current_select->cur_pos_in_select_list++;
03658 }
03659
03660
03661
03662
03663
03664
03665 if (table)
03666 table->used_fields= table->getShare()->sizeFields();
03667 }
03668 if (found)
03669 return false;
03670
03671
03672
03673
03674
03675
03676 if (not table_name)
03677 {
03678 my_message(ER_NO_TABLES_USED, ER(ER_NO_TABLES_USED), MYF(0));
03679 }
03680 else
03681 {
03682 my_error(ER_BAD_TABLE_ERROR, MYF(0), table_name);
03683 }
03684
03685 return true;
03686 }
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707 int Session::setup_conds(TableList *leaves, COND **conds)
03708 {
03709 Session *session= this;
03710 Select_Lex *select_lex= session->lex().current_select;
03711 TableList *table= NULL;
03712 void *save_session_marker= session->session_marker;
03713
03714
03715
03716
03717
03718
03719
03720
03721 bool save_is_item_list_lookup= select_lex->is_item_list_lookup;
03722 select_lex->is_item_list_lookup= 0;
03723
03724 session->mark_used_columns= MARK_COLUMNS_READ;
03725 select_lex->cond_count= 0;
03726 select_lex->between_count= 0;
03727 select_lex->max_equal_elems= 0;
03728
03729 session->session_marker= (void*)1;
03730 if (*conds)
03731 {
03732 session->setWhere("where clause");
03733 if ((!(*conds)->fixed && (*conds)->fix_fields(session, conds)) ||
03734 (*conds)->check_cols(1))
03735 goto err_no_arena;
03736 }
03737 session->session_marker= save_session_marker;
03738
03739
03740
03741
03742
03743 for (table= leaves; table; table= table->next_leaf)
03744 {
03745 TableList *embedded;
03746 TableList *embedding= table;
03747 do
03748 {
03749 embedded= embedding;
03750 if (embedded->on_expr)
03751 {
03752
03753 session->session_marker= (void*)embedded;
03754 session->setWhere("on clause");
03755 if ((!embedded->on_expr->fixed && embedded->on_expr->fix_fields(session, &embedded->on_expr)) ||
03756 embedded->on_expr->check_cols(1))
03757 goto err_no_arena;
03758 select_lex->cond_count++;
03759 }
03760 embedding= embedded->getEmbedding();
03761 }
03762 while (embedding &&
03763 &embedding->getNestedJoin()->join_list.front() == embedded);
03764
03765 }
03766 session->session_marker= save_session_marker;
03767
03768 session->lex().current_select->is_item_list_lookup= save_is_item_list_lookup;
03769 return(test(session->is_error()));
03770
03771 err_no_arena:
03772 select_lex->is_item_list_lookup= save_is_item_list_lookup;
03773
03774 return 1;
03775 }
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803 bool
03804 fill_record(Session *session, List<Item> &fields, List<Item> &values, bool ignore_errors)
03805 {
03806 List<Item>::iterator f(fields.begin());
03807 List<Item>::iterator v(values.begin());
03808 Item *value;
03809 Item_field *field;
03810 Table *table;
03811
03812
03813
03814
03815
03816 if (fields.size())
03817 {
03818
03819
03820
03821
03822 field= static_cast<Item_field *>(f++);
03823 table= field->field->getTable();
03824 table->auto_increment_field_not_null= false;
03825 f= fields.begin();
03826 }
03827
03828 while ((field= static_cast<Item_field *>(f++)))
03829 {
03830 value= v++;
03831
03832 Field *rfield= field->field;
03833 table= rfield->getTable();
03834
03835 if (rfield == table->next_number_field)
03836 table->auto_increment_field_not_null= true;
03837 if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors)
03838 {
03839 my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
03840 if (table)
03841 table->auto_increment_field_not_null= false;
03842
03843 return true;
03844 }
03845 }
03846
03847 return session->is_error();
03848 }
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870 bool fill_record(Session *session, Field **ptr, List<Item> &values, bool)
03871 {
03872 List<Item>::iterator v(values.begin());
03873 Item *value;
03874 Table *table= 0;
03875 Field *field;
03876
03877
03878
03879
03880
03881 if (*ptr)
03882 {
03883
03884
03885
03886
03887 table= (*ptr)->getTable();
03888 table->auto_increment_field_not_null= false;
03889 }
03890
03891 while ((field = *ptr++) && ! session->is_error())
03892 {
03893 value=v++;
03894 table= field->getTable();
03895
03896 if (field == table->next_number_field)
03897 table->auto_increment_field_not_null= true;
03898
03899 if (value->save_in_field(field, 0) < 0)
03900 {
03901 if (table)
03902 table->auto_increment_field_not_null= false;
03903
03904 return true;
03905 }
03906 }
03907
03908 return(session->is_error());
03909 }
03910
03911
03912 bool drizzle_rm_tmp_tables()
03913 {
03914
03915 assert(drizzle_tmpdir.size());
03916 Session::shared_ptr session= Session::make_shared(plugin::Listen::getNullClient(), catalog::local());
03917
03918 if (not session)
03919 return true;
03920 session->thread_stack= (char*) session.get();
03921 session->storeGlobals();
03922
03923 plugin::StorageEngine::removeLostTemporaryTables(*session, drizzle_tmpdir.c_str());
03924
03925 return false;
03926 }
03927
03928
03929
03930
03931
03932
03933
03934
03935
03936
03941 void kill_drizzle(void)
03942 {
03943 pthread_kill(signal_thread, SIGTERM);
03944 shutdown_in_progress= 1;
03945 }
03946
03947 }