~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_base.cc

  • Committer: Brian Aker
  • Date: 2009-06-03 19:30:45 UTC
  • mfrom: (1046.1.6 merge)
  • Revision ID: brian@gaz-20090603193045-4xgeczyfixh07beg
MergeĀ forĀ Brian

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#include <drizzled/server_includes.h>
19
19
#include <drizzled/field/timestamp.h>
20
20
#include <drizzled/field/null.h>
 
21
#include <assert.h>
21
22
 
22
23
#include <signal.h>
23
24
 
90
91
    if (!open_cache.records)                    // Safety first
91
92
      hash_free(&open_cache);
92
93
  }
93
 
  return;
94
94
}
95
95
 
96
96
uint32_t cached_open_tables(void)
173
173
    pthread_mutex_destroy(&LOCK_table_share);
174
174
    hash_free(&table_def_cache);
175
175
  }
176
 
  return;
177
176
}
178
177
 
179
178
 
417
416
  release_table_share(table->s);
418
417
  table->s= share;
419
418
  table->file->change_table_ptr(table, table->s);
420
 
 
421
 
  return;
422
419
}
423
420
 
424
421
 
446
443
  OPEN_TableList **start_list, *open_list;
447
444
  TableList table_list;
448
445
 
449
 
  pthread_mutex_lock(&LOCK_open);
 
446
  pthread_mutex_lock(&LOCK_open); /* List all open tables */
450
447
  memset(&table_list, 0, sizeof(table_list));
451
448
  start_list= &open_list;
452
449
  open_list=0;
510
507
  free_io_cache(table);
511
508
  if (table->file)                              // Not true if name lock
512
509
    table->closefrm(true);                      // close file
513
 
  return;
514
510
}
515
511
 
516
512
/*
536
532
    {
537
533
      unused_tables=unused_tables->next;
538
534
      if (table == unused_tables)
539
 
        unused_tables=0;
 
535
        unused_tables= NULL;
540
536
    }
541
537
  }
 
538
 
542
539
  free(table);
543
 
  return;
544
540
}
545
541
 
546
542
/* Free resources allocated by filesort() and read_record() */
553
549
    delete table->sort.io_cache;
554
550
    table->sort.io_cache= 0;
555
551
  }
556
 
  return;
557
552
}
558
553
 
559
554
 
579
574
  assert(session || (!wait_for_refresh && !tables));
580
575
 
581
576
  if (!have_lock)
582
 
    pthread_mutex_lock(&LOCK_open);
 
577
    pthread_mutex_lock(&LOCK_open); /* Optionally lock for remove tables from open_cahe if not in use */
583
578
  if (!tables)
584
579
  {
585
580
    refresh_version++;                          // Force close of open tables
731
726
}
732
727
 
733
728
 
734
 
/*
735
 
  Close all tables which match specified connection string or
736
 
  if specified string is NULL, then any table with a connection string.
737
 
*/
738
 
 
739
 
bool close_cached_connection_tables(Session *session, bool if_wait_for_refresh,
740
 
                                    LEX_STRING *connection, bool have_lock)
741
 
{
742
 
  uint32_t idx;
743
 
  TableList tmp, *tables= NULL;
744
 
  bool result= false;
745
 
  assert(session);
746
 
 
747
 
  if (!have_lock)
748
 
    pthread_mutex_lock(&LOCK_open);
749
 
 
750
 
  for (idx= 0; idx < table_def_cache.records; idx++)
751
 
  {
752
 
    TableShare *share= (TableShare *) hash_element(&table_def_cache, idx);
753
 
 
754
 
    /* Ignore if table is not open or does not have a connect_string */
755
 
    if (!share->connect_string.length || !share->ref_count)
756
 
      continue;
757
 
 
758
 
    /* Compare the connection string */
759
 
    if (connection &&
760
 
        (connection->length > share->connect_string.length ||
761
 
         (connection->length < share->connect_string.length &&
762
 
          (share->connect_string.str[connection->length] != '/' &&
763
 
           share->connect_string.str[connection->length] != '\\')) ||
764
 
         strncasecmp(connection->str, share->connect_string.str,
765
 
                     connection->length)))
766
 
      continue;
767
 
 
768
 
    /* close_cached_tables() only uses these elements */
769
 
    tmp.db= share->db.str;
770
 
    tmp.table_name= share->table_name.str;
771
 
    tmp.next_local= tables;
772
 
 
773
 
    tables= (TableList *) memdup_root(session->mem_root, (char*)&tmp,
774
 
                                      sizeof(TableList));
775
 
  }
776
 
 
777
 
  if (tables)
778
 
    result= close_cached_tables(session, tables, true, false, false);
779
 
 
780
 
  if (!have_lock)
781
 
    pthread_mutex_unlock(&LOCK_open);
782
 
 
783
 
  if (if_wait_for_refresh)
784
 
  {
785
 
    pthread_mutex_lock(&session->mysys_var->mutex);
786
 
    session->mysys_var->current_mutex= 0;
787
 
    session->mysys_var->current_cond= 0;
788
 
    session->set_proc_info(0);
789
 
    pthread_mutex_unlock(&session->mysys_var->mutex);
790
 
  }
791
 
 
792
 
  return(result);
793
 
}
794
 
 
795
 
 
796
729
/**
797
 
  Auxiliary function to close all tables in the open_tables list.
798
 
 
799
 
  @param session Thread context.
800
 
 
801
 
  @remark It should not ordinarily be called directly.
 
730
  move one table to free list 
802
731
*/
803
732
 
804
 
void Session::close_open_tables()
805
 
{
806
 
  bool found_old_table= 0;
807
 
 
808
 
  safe_mutex_assert_not_owner(&LOCK_open);
809
 
 
810
 
  pthread_mutex_lock(&LOCK_open);
811
 
 
812
 
  while (open_tables)
813
 
    found_old_table|= close_thread_table(this, &open_tables);
814
 
  some_tables_deleted= 0;
815
 
 
816
 
  /* Free tables to hold down open files */
817
 
  while (open_cache.records > table_cache_size && unused_tables)
818
 
    hash_delete(&open_cache,(unsigned char*) unused_tables); /* purecov: tested */
819
 
  if (found_old_table)
820
 
  {
821
 
    /* Tell threads waiting for refresh that something has happened */
822
 
    broadcast_refresh();
823
 
  }
824
 
 
825
 
  pthread_mutex_unlock(&LOCK_open);
826
 
}
827
 
 
828
 
 
829
 
/* move one table to free list */
830
 
 
831
 
bool close_thread_table(Session *session, Table **table_ptr)
 
733
static bool free_cached_table(Session *session, Table **table_ptr)
832
734
{
833
735
  bool found_old_table= 0;
834
736
  Table *table= *table_ptr;
835
737
 
 
738
  safe_mutex_assert_owner(&LOCK_open);
836
739
  assert(table->key_read == 0);
837
740
  assert(!table->file || table->file->inited == handler::NONE);
838
741
 
839
 
  *table_ptr=table->next;
 
742
  *table_ptr= table->next;
840
743
 
841
744
  if (table->needs_reopen_or_name_lock() ||
842
745
      session->version != refresh_version || !table->db_stat)
843
746
  {
844
747
    hash_delete(&open_cache,(unsigned char*) table);
845
 
    found_old_table=1;
 
748
    found_old_table= true;
846
749
  }
847
750
  else
848
751
  {
854
757
 
855
758
    /* Free memory and reset for next loop */
856
759
    table->file->ha_reset();
857
 
    table->in_use=0;
 
760
    table->in_use= false;
858
761
    if (unused_tables)
859
762
    {
860
763
      table->next=unused_tables;                /* Link in last */
865
768
    else
866
769
      unused_tables=table->next=table->prev=table;
867
770
  }
868
 
  return(found_old_table);
 
771
 
 
772
  return found_old_table;
 
773
}
 
774
 
 
775
 
 
776
/**
 
777
  Auxiliary function to close all tables in the open_tables list.
 
778
 
 
779
  @param session Thread context.
 
780
 
 
781
  @remark It should not ordinarily be called directly.
 
782
*/
 
783
 
 
784
void Session::close_open_tables()
 
785
{
 
786
  bool found_old_table= false;
 
787
 
 
788
  safe_mutex_assert_not_owner(&LOCK_open);
 
789
 
 
790
  pthread_mutex_lock(&LOCK_open); /* Close all open tables on Session */
 
791
 
 
792
  while (open_tables)
 
793
    found_old_table|= free_cached_table(this, &open_tables);
 
794
  some_tables_deleted= false;
 
795
 
 
796
  if (found_old_table)
 
797
  {
 
798
    /* Tell threads waiting for refresh that something has happened */
 
799
    broadcast_refresh();
 
800
  }
 
801
 
 
802
  pthread_mutex_unlock(&LOCK_open);
869
803
}
870
804
 
871
805
/*
1115
1049
      table->next->prev= 0;
1116
1050
  }
1117
1051
  close_temporary(table, free_share, delete_table);
1118
 
  return;
1119
1052
}
1120
1053
 
1121
1054
 
1142
1075
    table->s->free_table_share();
1143
1076
    free((char*) table);
1144
1077
  }
1145
 
  return;
1146
1078
}
1147
1079
 
1148
1080
 
1245
1177
 
1246
1178
  // Notify any 'refresh' threads
1247
1179
  broadcast_refresh();
1248
 
  return;
1249
1180
}
1250
1181
 
1251
1182
 
1276
1207
  else
1277
1208
  {
1278
1209
    StorageEngine *table_type= table->s->db_type();
1279
 
    pthread_mutex_lock(&LOCK_open);
 
1210
    pthread_mutex_lock(&LOCK_open); /* Close and drop a table (AUX routine) */
1280
1211
    /*
1281
1212
      unlink_open_table() also tells threads waiting for refresh or close
1282
1213
      that something has happened.
1327
1258
  session->mysys_var->current_cond= 0;
1328
1259
  session->set_proc_info(proc_info);
1329
1260
  pthread_mutex_unlock(&session->mysys_var->mutex);
1330
 
  return;
1331
1261
}
1332
1262
 
1333
1263
 
1397
1327
  safe_mutex_assert_owner(&LOCK_open);
1398
1328
 
1399
1329
  if (session->killed || !table)
1400
 
    return(true);
 
1330
    return true;
1401
1331
 
1402
1332
  orig_table= *table;
1403
1333
 
1449
1379
  table->maybe_null= false;
1450
1380
  table->force_index= false;
1451
1381
  table->status=STATUS_NO_RECORD;
 
1382
 
1452
1383
  return false;
1453
1384
}
1454
1385
 
1536
1467
  key_pos= strcpy(key_pos+1, table_name) + strlen(table_name);
1537
1468
  key_length= (uint32_t) (key_pos-key)+1;
1538
1469
 
1539
 
  pthread_mutex_lock(&LOCK_open);
 
1470
  pthread_mutex_lock(&LOCK_open); /* Obtain a name lock even though table is not in cache (like for create table)  */
1540
1471
 
1541
1472
  if (hash_search(&open_cache, (unsigned char *)key, key_length))
1542
1473
  {
1602
1533
 
1603
1534
  /* find a unused table in the open table cache */
1604
1535
  if (refresh)
1605
 
    *refresh=0;
 
1536
    *refresh= false;
1606
1537
 
1607
1538
  /* an open table operation needs a lot of the stack space */
1608
1539
  if (check_stack_overrun(session, STACK_MIN_SIZE_FOR_OPEN, (unsigned char *)&alias))
1609
 
    return(0);
 
1540
    return NULL;
1610
1541
 
1611
1542
  if (session->killed)
1612
 
    return(0);
 
1543
    return NULL;
1613
1544
 
1614
1545
  key_length= create_table_def_key(key, table_list);
1615
1546
 
1618
1549
    of temporary tables of this thread. In MySQL temporary tables
1619
1550
    are always thread-local and "shadow" possible base tables with the
1620
1551
    same name. This block implements the behaviour.
1621
 
TODO: move this block into a separate function.
 
1552
    TODO -> move this block into a separate function.
1622
1553
  */
 
1554
  for (table= session->temporary_tables; table ; table=table->next)
1623
1555
  {
1624
 
    for (table= session->temporary_tables; table ; table=table->next)
 
1556
    if (table->s->table_cache_key.length == key_length && !memcmp(table->s->table_cache_key.str, key, key_length))
1625
1557
    {
1626
 
      if (table->s->table_cache_key.length == key_length && !memcmp(table->s->table_cache_key.str, key, key_length))
 
1558
      /*
 
1559
        We're trying to use the same temporary table twice in a query.
 
1560
        Right now we don't support this because a temporary table
 
1561
        is always represented by only one Table object in Session, and
 
1562
        it can not be cloned. Emit an error for an unsupported behaviour.
 
1563
      */
 
1564
      if (table->query_id)
1627
1565
      {
1628
 
        /*
1629
 
          We're trying to use the same temporary table twice in a query.
1630
 
          Right now we don't support this because a temporary table
1631
 
          is always represented by only one Table object in Session, and
1632
 
          it can not be cloned. Emit an error for an unsupported behaviour.
1633
 
        */
1634
 
        if (table->query_id)
1635
 
        {
1636
 
          my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
1637
 
          return(0);
1638
 
        }
1639
 
        table->query_id= session->query_id;
1640
 
        goto reset;
 
1566
        my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
 
1567
        return NULL;
1641
1568
      }
 
1569
      table->query_id= session->query_id;
 
1570
      goto reset;
1642
1571
    }
1643
1572
  }
1644
1573
 
1645
1574
  if (flags & DRIZZLE_OPEN_TEMPORARY_ONLY)
1646
1575
  {
1647
1576
    my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->table_name);
1648
 
    return(0);
 
1577
    return NULL;
1649
1578
  }
1650
1579
 
1651
1580
  /*
1676
1605
          */
1677
1606
          my_error(ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG, MYF(0),
1678
1607
                   table->s->table_name.str);
1679
 
          return(0);
 
1608
          return NULL;
1680
1609
        }
1681
1610
        /*
1682
1611
          When looking for a usable Table, ignore MERGE children, as they
1731
1660
      locked tables list was created.
1732
1661
    */
1733
1662
    my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
1734
 
    return(0);
 
1663
    return NULL;
 
1664
  }
 
1665
 
 
1666
  /*
 
1667
    If it's the first table from a list of tables used in a query,
 
1668
    remember refresh_version (the version of open_cache state).
 
1669
    If the version changes while we're opening the remaining tables,
 
1670
    we will have to back off, close all the tables opened-so-far,
 
1671
    and try to reopen them.
 
1672
 
 
1673
    Note-> refresh_version is currently changed only during FLUSH TABLES.
 
1674
  */
 
1675
  if (!session->open_tables)
 
1676
    session->version=refresh_version;
 
1677
  else if ((session->version != refresh_version) &&
 
1678
           ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
 
1679
  {
 
1680
    /* Someone did a refresh while thread was opening tables */
 
1681
    if (refresh)
 
1682
      *refresh= true;
 
1683
    pthread_mutex_unlock(&LOCK_open);
 
1684
 
 
1685
    return NULL;
 
1686
  }
 
1687
 
 
1688
  /*
 
1689
    Before we test the global cache, we test our local session cache.
 
1690
  */
 
1691
  if (session->cached_table)
 
1692
  {
 
1693
    assert(false); /* Not implemented yet */
1735
1694
  }
1736
1695
 
1737
1696
  /*
1740
1699
    Now we should:
1741
1700
    - try to find the table in the table cache.
1742
1701
    - if one of the discovered Table instances is name-locked
1743
 
    (table->s->version == 0) or some thread has started FLUSH TABLES
1744
 
    (refresh_version > table->s->version), back off -- we have to wait
 
1702
    (table->s->version == 0) back off -- we have to wait
1745
1703
    until no one holds a name lock on the table.
1746
1704
    - if there is no such Table in the name cache, read the table definition
1747
1705
    and insert it into the cache.
1750
1708
    on disk.
1751
1709
  */
1752
1710
 
1753
 
  pthread_mutex_lock(&LOCK_open);
1754
 
 
1755
 
  /*
1756
 
    If it's the first table from a list of tables used in a query,
1757
 
    remember refresh_version (the version of open_cache state).
1758
 
    If the version changes while we're opening the remaining tables,
1759
 
    we will have to back off, close all the tables opened-so-far,
1760
 
    and try to reopen them.
1761
 
Note: refresh_version is currently changed only during FLUSH TABLES.
1762
 
  */
1763
 
  if (!session->open_tables)
1764
 
    session->version=refresh_version;
1765
 
  else if ((session->version != refresh_version) &&
1766
 
           ! (flags & DRIZZLE_LOCK_IGNORE_FLUSH))
1767
 
  {
1768
 
    /* Someone did a refresh while thread was opening tables */
1769
 
    if (refresh)
1770
 
      *refresh=1;
1771
 
    pthread_mutex_unlock(&LOCK_open);
1772
 
    return(0);
1773
 
  }
 
1711
  pthread_mutex_lock(&LOCK_open); /* Lock for FLUSH TABLES for open table */
1774
1712
 
1775
1713
  /*
1776
1714
    Actually try to find the table in the open_cache.
1820
1758
      {
1821
1759
        pthread_mutex_unlock(&LOCK_open);
1822
1760
        my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str);
1823
 
        return(0);
 
1761
        return NULL;
1824
1762
      }
1825
1763
 
1826
1764
      /*
1866
1804
        Signal the caller that it has to try again.
1867
1805
      */
1868
1806
      if (refresh)
1869
 
        *refresh=1;
1870
 
      return(0);
 
1807
        *refresh= true;
 
1808
      return NULL;
1871
1809
    }
1872
1810
  }
1873
1811
  if (table)
1877
1815
    {  // First unused
1878
1816
      unused_tables=unused_tables->next; // Remove from link
1879
1817
      if (table == unused_tables)
1880
 
        unused_tables=0;
 
1818
        unused_tables= NULL;
1881
1819
    }
1882
1820
    table->prev->next=table->next; /* Remove from unused list */
1883
1821
    table->next->prev=table->prev;
1910
1848
          removed once tables are closed. Also mark it so it won't be ignored
1911
1849
          by other trying to take name-lock.
1912
1850
        */
1913
 
        table->open_placeholder= 1;
 
1851
        table->open_placeholder= true;
1914
1852
        table->next= session->open_tables;
1915
1853
        session->open_tables= table;
1916
1854
        pthread_mutex_unlock(&LOCK_open);
1917
 
        return(table);
 
1855
        return table ;
1918
1856
      }
1919
1857
      /* Table exists. Let us try to open it. */
1920
1858
    }
1934
1872
      pthread_mutex_unlock(&LOCK_open);
1935
1873
      return NULL;
1936
1874
    }
1937
 
    my_hash_insert(&open_cache,(unsigned char*) table);
 
1875
    my_hash_insert(&open_cache, (unsigned char*) table);
1938
1876
  }
1939
1877
 
1940
1878
  pthread_mutex_unlock(&LOCK_open);
1943
1881
    table->next=session->open_tables; /* Link into simple list */
1944
1882
    session->open_tables=table;
1945
1883
  }
1946
 
  table->reginfo.lock_type=TL_READ; /* Assume read */
 
1884
  table->reginfo.lock_type= TL_READ; /* Assume read */
1947
1885
 
1948
1886
reset:
1949
1887
  assert(table->s->ref_count > 0 || table->s->tmp_table != NO_TMP_TABLE);
1958
1896
    table->alias= (char*) realloc((char*) table->alias, length);
1959
1897
    memcpy((void*) table->alias, alias, length);
1960
1898
  }
 
1899
 
1961
1900
  /* These variables are also set in reopen_table() */
1962
1901
  table->tablenr=session->current_tablenr++;
1963
 
  table->used_fields=0;
1964
 
  table->const_table=0;
 
1902
  table->used_fields= 0;
 
1903
  table->const_table= 0;
1965
1904
  table->null_row= false;
1966
1905
  table->maybe_null= false;
1967
1906
  table->force_index= false;
1975
1914
  table->pos_in_table_list= table_list;
1976
1915
  table->clear_column_bitmaps();
1977
1916
  assert(table->key_read == 0);
1978
 
  return(table);
 
1917
 
 
1918
  return table;
1979
1919
}
1980
1920
 
1981
1921
 
2115
2055
{
2116
2056
  Table *table;
2117
2057
 
2118
 
  safe_mutex_assert_owner(&LOCK_open);
 
2058
  safe_mutex_assert_owner(&LOCK_open); /* Adjust locks at the end of ALTER TABLEL */
2119
2059
 
2120
2060
  if (session->lock)
2121
2061
  {
2145
2085
      close_handle_and_leave_table_as_lock(table);
2146
2086
    }
2147
2087
  }
2148
 
  return;
2149
2088
}
2150
2089
 
2151
2090
 
2339
2278
  }
2340
2279
  if (found)
2341
2280
    broadcast_refresh();
2342
 
  return;
2343
2281
}
2344
2282
 
2345
2283
 
2388
2326
  bool result;
2389
2327
 
2390
2328
  session->set_proc_info("Waiting for tables");
2391
 
  pthread_mutex_lock(&LOCK_open);
 
2329
  pthread_mutex_lock(&LOCK_open); /* Lock for all tables to be refreshed */
2392
2330
  while (!session->killed)
2393
2331
  {
2394
2332
    session->some_tables_deleted=0;
3330
3268
  }
3331
3269
  else if (table->get_fields_in_item_tree)
3332
3270
    field->flags|= GET_FIXED_FIELDS_FLAG;
3333
 
  return;
3334
3271
}
3335
3272
 
3336
3273
 
5619
5556
 
5620
5557
 
5621
5558
/*
5622
 
  free all unused tables
5623
 
 
5624
 
  NOTE
5625
 
  This is called by 'handle_manager' when one wants to periodicly flush
5626
 
  all not used tables.
5627
 
*/
5628
 
 
5629
 
void flush_tables()
5630
 
{
5631
 
  (void) pthread_mutex_lock(&LOCK_open);
5632
 
  while (unused_tables)
5633
 
    hash_delete(&open_cache,(unsigned char*) unused_tables);
5634
 
  (void) pthread_mutex_unlock(&LOCK_open);
5635
 
}
5636
 
 
5637
 
 
5638
 
/*
5639
5559
  Mark all entries with the table as deleted to force an reopen of the table
5640
5560
 
5641
5561
  The table will be closed (not stored in cache) by the current thread when