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