1 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /* open a heap-database */
24 
25 #include "heapdef.h"
26 #include "my_sys.h"
27 
28 /*
29   Open heap table based on HP_SHARE structure
30 
31   NOTE
32     This doesn't register the table in the open table list.
33 */
34 
heap_open_from_share(HP_SHARE * share,int mode)35 HP_INFO *heap_open_from_share(HP_SHARE *share, int mode)
36 {
37   HP_INFO *info;
38   DBUG_ENTER("heap_open_from_share");
39 
40   if (!(info= (HP_INFO*) my_malloc(hp_key_memory_HP_INFO,
41                                    (uint) sizeof(HP_INFO) +
42 				  2 * share->max_key_length,
43 				  MYF(MY_ZEROFILL))))
44   {
45     DBUG_RETURN(0);
46   }
47   share->open_count++;
48   /*
49     Don't initialize THR_LOCK_DATA for internal temporary tables as it
50     is not used for them anyway (and THR_LOCK is not initialized for them
51     too).
52   */
53   if (share->open_list.data != NULL)
54     thr_lock_data_init(&share->lock, &info->lock, NULL);
55   info->s= share;
56   info->lastkey= (uchar*) (info + 1);
57   info->recbuf= (uchar*) (info->lastkey + share->max_key_length);
58   info->mode= mode;
59   info->current_record= (ulong) ~0L;		/* No current record */
60   info->lastinx= info->errkey= -1;
61 #ifndef NDEBUG
62   info->opt_flag= READ_CHECK_USED;		/* Check when changing */
63 #endif
64   DBUG_PRINT("exit",("heap: 0x%lx  reclength: %d  records_in_block: %d",
65 		     (long) info, share->reclength,
66                      share->block.records_in_block));
67   DBUG_RETURN(info);
68 }
69 
70 
71 /*
72   Open heap table based on HP_SHARE structure and register it
73 */
74 
heap_open_from_share_and_register(HP_SHARE * share,int mode)75 HP_INFO *heap_open_from_share_and_register(HP_SHARE *share, int mode)
76 {
77   HP_INFO *info;
78   DBUG_ENTER("heap_open_from_share_and_register");
79 
80   mysql_mutex_lock(&THR_LOCK_heap);
81   if ((info= heap_open_from_share(share, mode)))
82   {
83     info->open_list.data= (void*) info;
84     heap_open_list= list_add(heap_open_list,&info->open_list);
85     /* Unpin the share, it is now pinned by the file. */
86     share->open_count--;
87   }
88   mysql_mutex_unlock(&THR_LOCK_heap);
89   DBUG_RETURN(info);
90 }
91 
92 
93 /**
94   Dereference a HEAP share and free it if it's not referenced.
95   We don't check open_count for internal tables since they
96   are always thread-local, i.e. referenced by a single thread.
97 */
heap_release_share(HP_SHARE * share,my_bool internal_table)98 void heap_release_share(HP_SHARE *share, my_bool internal_table)
99 {
100   /* Couldn't open table; Remove the newly created table */
101   if (internal_table)
102     hp_free(share);
103   else
104   {
105     mysql_mutex_lock(&THR_LOCK_heap);
106     if (--share->open_count == 0)
107       hp_free(share);
108     mysql_mutex_unlock(&THR_LOCK_heap);
109   }
110 }
111 
112 /*
113   Open heap table based on name
114 
115   NOTE
116     This register the table in the open table list. so that it can be
117     found by future heap_open() calls.
118 */
119 
heap_open(const char * name,int mode)120 HP_INFO *heap_open(const char *name, int mode)
121 {
122   HP_INFO *info;
123   HP_SHARE *share;
124   DBUG_ENTER("heap_open");
125 
126   mysql_mutex_lock(&THR_LOCK_heap);
127   if (!(share= hp_find_named_heap(name)))
128   {
129     set_my_errno(ENOENT);
130     mysql_mutex_unlock(&THR_LOCK_heap);
131     DBUG_RETURN(0);
132   }
133   if ((info= heap_open_from_share(share, mode)))
134   {
135     info->open_list.data= (void*) info;
136     heap_open_list= list_add(heap_open_list,&info->open_list);
137   }
138   mysql_mutex_unlock(&THR_LOCK_heap);
139   DBUG_RETURN(info);
140 }
141 
142 
143 /* map name to a heap-nr. If name isn't found return 0 */
144 
hp_find_named_heap(const char * name)145 HP_SHARE *hp_find_named_heap(const char *name)
146 {
147   LIST *pos;
148   HP_SHARE *info;
149   DBUG_ENTER("heap_find");
150   DBUG_PRINT("enter",("name: %s",name));
151 
152   for (pos= heap_share_list; pos; pos= pos->next)
153   {
154     info= (HP_SHARE*) pos->data;
155     if (!strcmp(name, info->name))
156     {
157       DBUG_PRINT("exit", ("Old heap_database: 0x%lx", (long) info));
158       DBUG_RETURN(info);
159     }
160   }
161   DBUG_RETURN((HP_SHARE *) 0);
162 }
163 
164 
165