mariadb/sql/sp_cache.cc
unknown 645d19f694 WL#1366: Use the schema (db) associated with an SP.
Phase 4 (final): Remove associated stored procedures when a database is dropped.


mysql-test/r/sp-security.result:
  drop database now deletes associated SPs.
mysql-test/r/sp.result:
  drop database now deletes associated SPs.
mysql-test/t/sp-security.test:
  drop database now deletes associated SPs.
mysql-test/t/sp.test:
  drop database now deletes associated SPs.
sql/sp.cc:
  New function for deleting all SPs associated with a database.
sql/sp.h:
  New function for deleting all SPs associated with a database.
sql/sp_cache.cc:
  New function for just invalidating all SP caches (when dropping a database).
sql/sp_cache.h:
  New function for just invalidating all SP caches (when dropping a database).
sql/sql_db.cc:
  When dropping a database, also delete all associated SPs.
2004-03-22 14:44:41 +01:00

166 lines
3 KiB
C++

/* Copyright (C) 2002 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef __GNUC__
#pragma implementation
#endif
#include "mysql_priv.h"
#include "sp_cache.h"
#include "sp_head.h"
static pthread_mutex_t Cversion_lock;
static ulong Cversion = 0;
void
sp_cache_init()
{
pthread_mutex_init(&Cversion_lock, MY_MUTEX_INIT_FAST);
}
void
sp_cache_clear(sp_cache **cp)
{
sp_cache *c= *cp;
if (c)
{
delete c;
*cp= NULL;
}
}
void
sp_cache_insert(sp_cache **cp, sp_head *sp)
{
sp_cache *c= *cp;
if (! c)
c= new sp_cache();
if (c)
{
ulong v;
pthread_mutex_lock(&Cversion_lock); // LOCK
v= Cversion;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
if (c->version < v)
{
if (*cp)
c->remove_all();
c->version= v;
}
c->insert(sp);
if (*cp == NULL)
*cp= c;
}
}
sp_head *
sp_cache_lookup(sp_cache **cp, sp_name *name)
{
ulong v;
sp_cache *c= *cp;
if (! c)
return NULL;
pthread_mutex_lock(&Cversion_lock); // LOCK
v= Cversion;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
if (c->version < v)
{
c->remove_all();
c->version= v;
return NULL;
}
return c->lookup(name->m_qname.str, name->m_qname.length);
}
bool
sp_cache_remove(sp_cache **cp, sp_name *name)
{
sp_cache *c= *cp;
bool found= FALSE;
if (c)
{
ulong v;
pthread_mutex_lock(&Cversion_lock); // LOCK
v= Cversion++;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
if (c->version < v)
c->remove_all();
else
found= c->remove(name->m_qname.str, name->m_qname.length);
c->version= v+1;
}
return found;
}
void
sp_cache_invalidate()
{
pthread_mutex_lock(&Cversion_lock); // LOCK
Cversion++;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
}
static byte *
hash_get_key_for_sp_head(const byte *ptr, uint *plen,
my_bool first)
{
sp_head *sp= (sp_head *)ptr;
*plen= sp->m_qname.length;
return (byte*) sp->m_qname.str;
}
static void
hash_free_sp_head(void *p)
{
sp_head *sp= (sp_head *)p;
delete sp;
}
sp_cache::sp_cache()
{
init();
}
sp_cache::~sp_cache()
{
hash_free(&m_hashtable);
}
void
sp_cache::init()
{
hash_init(&m_hashtable, system_charset_info, 0, 0, 0,
hash_get_key_for_sp_head, hash_free_sp_head, 0);
version= 0;
}
void
sp_cache::cleanup()
{
hash_free(&m_hashtable);
}