CUBRID Engine  latest
cas_handle.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 
20 /*
21  * cas_handle.c -
22  */
23 
24 #ident "$Id$"
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <assert.h>
30 
31 #if defined(WINDOWS)
32 #include <winsock2.h>
33 #include <windows.h>
34 #else /* WINDOWS */
35 #include <unistd.h>
36 #endif /* WINDOWS */
37 
38 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
39 #include "cas_db_inc.h"
40 #endif /* !CAS_FOR_ORACLE && !CAS_FOR_MYSQL */
41 #include "cas_execute.h"
42 
43 #include "cas.h"
44 #include "cas_common.h"
45 #include "cas_handle.h"
46 #include "cas_log.h"
47 
48 #define SRV_HANDLE_ALLOC_SIZE 256
49 
50 static void srv_handle_content_free (T_SRV_HANDLE * srv_handle);
51 static void col_update_info_free (T_QUERY_RESULT * q_result);
52 static void srv_handle_rm_tmp_file (int h_id, T_SRV_HANDLE * srv_handle);
53 
55 static int max_srv_handle = 0;
56 static int max_handle_id = 0;
57 #if !defined(LIBCAS_FOR_JSP)
58 static int current_handle_count = 0;
59 #endif
60 
61 int
62 hm_new_srv_handle (T_SRV_HANDLE ** new_handle, unsigned int seq_num)
63 {
64  int i;
65  int new_max_srv_handle;
66  int new_handle_id = 0;
67  T_SRV_HANDLE **new_srv_handle_table = NULL;
68  T_SRV_HANDLE *srv_handle;
69 
70 #if !defined(LIBCAS_FOR_JSP)
72  {
74  }
75 #endif /* !LIBCAS_FOR_JSP */
76 
77  for (i = 0; i < max_srv_handle; i++)
78  {
79  if (srv_handle_table[i] == NULL)
80  {
81  *new_handle = srv_handle_table[i];
82  new_handle_id = i + 1;
83  break;
84  }
85  }
86 
87  if (new_handle_id == 0)
88  {
89  new_max_srv_handle = max_srv_handle + SRV_HANDLE_ALLOC_SIZE;
90  new_srv_handle_table = (T_SRV_HANDLE **) REALLOC (srv_handle_table, sizeof (T_SRV_HANDLE *) * new_max_srv_handle);
91  if (new_srv_handle_table == NULL)
92  {
94  }
95 
96  new_handle_id = max_srv_handle + 1;
97  memset (new_srv_handle_table + max_srv_handle, 0, sizeof (T_SRV_HANDLE *) * SRV_HANDLE_ALLOC_SIZE);
98  max_srv_handle = new_max_srv_handle;
99  srv_handle_table = new_srv_handle_table;
100  }
101 
102  srv_handle = (T_SRV_HANDLE *) MALLOC (sizeof (T_SRV_HANDLE));
103  if (srv_handle == NULL)
104  {
106  }
107  memset (srv_handle, 0, sizeof (T_SRV_HANDLE));
108  srv_handle->id = new_handle_id;
109  srv_handle->query_seq_num = seq_num;
110  srv_handle->use_plan_cache = false;
111  srv_handle->use_query_cache = false;
112  srv_handle->is_holdable = false;
113  srv_handle->is_from_current_transaction = true;
114 #if defined(CAS_FOR_ORACLE)
115  srv_handle->has_out_result = false;
116 #endif /* defined(CAS_FOR_ORACLE) */
117 #if defined(CAS_FOR_ORACLE) || defined(CAS_FOR_MYSQL)
118  srv_handle->send_metadata_before_execute = false;
119  srv_handle->next_cursor_pos = 1;
120 #endif
121 #if !defined(LIBCAS_FOR_JSP)
122  srv_handle->is_pooled = as_info->cur_statement_pooling;
123 #endif
124 
125 #if defined(CAS_FOR_MYSQL)
126  srv_handle->has_mysql_last_insert_id = false;
127 #endif /* CAS_FOR_MYSQL */
128 
129  *new_handle = srv_handle;
130  srv_handle_table[new_handle_id - 1] = srv_handle;
131  if (new_handle_id > max_handle_id)
132  {
133  max_handle_id = new_handle_id;
134  }
135 
136 #if !defined(LIBCAS_FOR_JSP)
138 #endif
139 
140  return new_handle_id;
141 }
142 
143 T_SRV_HANDLE *
145 {
146  if (h_id <= 0 || h_id > max_srv_handle)
147  {
148  return NULL;
149  }
150 
151  return (srv_handle_table[h_id - 1]);
152 }
153 
154 void
156 {
157  T_SRV_HANDLE *srv_handle;
158 
159  if (h_id <= 0 || h_id > max_srv_handle)
160  {
161  return;
162  }
163 
164  srv_handle = srv_handle_table[h_id - 1];
165  if (srv_handle == NULL)
166  {
167  return;
168  }
169 
170  srv_handle_content_free (srv_handle);
171  srv_handle_rm_tmp_file (h_id, srv_handle);
172 
173 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
174  FREE_MEM (srv_handle->classes);
175  FREE_MEM (srv_handle->classes_chn);
176 #endif /* !CAS_FOR_ORACLE && !CAS_FOR_MYSQL */
177 
178  FREE_MEM (srv_handle);
179  srv_handle_table[h_id - 1] = NULL;
180 #if !defined(LIBCAS_FOR_JSP)
182 #endif
183 }
184 
185 void
186 hm_srv_handle_free_all (bool free_holdable)
187 {
188  T_SRV_HANDLE *srv_handle;
189  int i;
190  int new_max_handle_id = 0;
191 
192  for (i = 0; i < max_handle_id; i++)
193  {
194  srv_handle = srv_handle_table[i];
195  if (srv_handle == NULL)
196  {
197  continue;
198  }
199 
200  if (srv_handle->is_holdable && !free_holdable)
201  {
202  new_max_handle_id = i;
203  continue;
204  }
205 
206  srv_handle_content_free (srv_handle);
207  srv_handle_rm_tmp_file (i + 1, srv_handle);
208  FREE_MEM (srv_handle);
209  srv_handle_table[i] = NULL;
210 #if !defined(LIBCAS_FOR_JSP)
212 #endif
213  }
214 
215  max_handle_id = new_max_handle_id;
216 #if !defined(LIBCAS_FOR_JSP)
217  if (free_holdable)
218  {
221  }
222 #endif
223 }
224 
225 void
227 {
228  T_SRV_HANDLE *srv_handle;
229  int i;
230 
231  for (i = 0; i < max_handle_id; i++)
232  {
233  srv_handle = srv_handle_table[i];
234  if (srv_handle == NULL)
235  {
236  continue;
237  }
238 
239  srv_handle->is_prepared = FALSE;
240  }
241 
243 }
244 
245 void
246 hm_srv_handle_qresult_end_all (bool end_holdable)
247 {
248  T_SRV_HANDLE *srv_handle;
249  int i;
250 
251  for (i = 0; i < max_handle_id; i++)
252  {
253  srv_handle = srv_handle_table[i];
254  if (srv_handle == NULL)
255  {
256  continue;
257  }
258 
259 #if defined(CAS_FOR_ORACLE) || defined(CAS_FOR_MYSQL)
260  hm_qresult_end (srv_handle, FALSE);
261 #else /* CAS_FOR_MYSQL */
262 
263  if (srv_handle->is_holdable && !end_holdable)
264  {
265  /* do not close holdable results */
266  srv_handle->is_from_current_transaction = false;
267  continue;
268  }
269 
270  if (srv_handle->is_holdable && !srv_handle->is_from_current_transaction)
271  {
272  /* end only holdable handles from the current transaction */
273  continue;
274  }
275 
276  if (srv_handle->schema_type < 0 || srv_handle->schema_type == CCI_SCH_CLASS
277  || srv_handle->schema_type == CCI_SCH_VCLASS || srv_handle->schema_type == CCI_SCH_ATTRIBUTE
278  || srv_handle->schema_type == CCI_SCH_CLASS_ATTRIBUTE || srv_handle->schema_type == CCI_SCH_QUERY_SPEC
279  || srv_handle->schema_type == CCI_SCH_DIRECT_SUPER_CLASS || srv_handle->schema_type == CCI_SCH_PRIMARY_KEY)
280  {
281  hm_qresult_end (srv_handle, FALSE);
282  }
283 #endif
284  }
285 }
286 
287 #if defined (ENABLE_UNUSED_FUNCTION)
288 void
289 hm_srv_handle_set_pooled ()
290 {
291  T_SRV_HANDLE *srv_handle;
292  int i;
293 
294  for (i = 0; i < max_handle_id; i++)
295  {
296  srv_handle = srv_handle_table[i];
297  if (srv_handle == NULL)
298  {
299  continue;
300  }
301 
302  srv_handle->is_pooled = 1;
303  }
304 }
305 #endif /* ENABLE_UNUSED_FUNCTION */
306 
307 void
309 {
310  memset (q_result, 0, sizeof (T_QUERY_RESULT));
311 }
312 
313 void
314 hm_qresult_end (T_SRV_HANDLE * srv_handle, char free_flag)
315 {
316  T_QUERY_RESULT *q_result;
317  int i;
318 
319  q_result = srv_handle->q_result;
320 #if defined(CAS_FOR_ORACLE) || defined(CAS_FOR_MYSQL)
321 
322 #if defined(CAS_FOR_MYSQL)
323  if (srv_handle->session)
324  {
325  cas_mysql_stmt_free_result (srv_handle->session);
326  }
327 #endif /* CAS_FOR_MYSQL */
328 
329  if (free_flag == TRUE)
330  {
331  ux_free_result (q_result);
332  FREE_MEM (q_result);
333  srv_handle->q_result = NULL;
334  }
335 #else /* CAS_FOR_ORACLE || CAS_FOR_MYSQL */
336  if (q_result)
337  {
338  for (i = 0; i < srv_handle->num_q_result; i++)
339  {
340  if (q_result[i].copied != TRUE && q_result[i].result)
341  {
342  ux_free_result (q_result[i].result);
343 
344  if (q_result[i].is_holdable == true)
345  {
346  q_result[i].is_holdable = false;
347 #if !defined(LIBCAS_FOR_JSP)
349 #endif
350  }
351  }
352  q_result[i].result = NULL;
353 
354  if (q_result[i].column_info)
355  {
356  db_query_format_free ((DB_QUERY_TYPE *) q_result[i].column_info);
357  }
358 
359  q_result[i].column_info = NULL;
360  if (free_flag == TRUE)
361  {
362  col_update_info_free (&(q_result[i]));
363  FREE_MEM (q_result[i].null_type_column);
364  }
365  }
366 
367  if (free_flag == TRUE)
368  {
369  FREE_MEM (q_result);
370  }
371  }
372 
373  if (free_flag == TRUE)
374  {
375  srv_handle->q_result = NULL;
376  srv_handle->num_q_result = 0;
377  srv_handle->cur_result_index = 0;
378  }
379 
380  srv_handle->cur_result = NULL;
381  srv_handle->has_result_set = false;
382 #endif /* CAS_FOR_ORACLE || CAS_FOR_MYSQL */
383 }
384 
385 void
387 {
388  if (srv_handle->session)
389  {
390 #if defined(CAS_FOR_ORACLE)
391  cas_oracle_stmt_close (srv_handle->session);
392 #elif defined(CAS_FOR_MYSQL)
393  cas_mysql_stmt_close (srv_handle->session);
394 #else /* CAS_FOR_ORACLE */
395  db_close_session ((DB_SESSION *) (srv_handle->session));
396 #endif /* CAS_FOR_ORACLE */
397  }
398  srv_handle->session = NULL;
399 }
400 
401 void
403 {
404  memset (col_update_info, 0, sizeof (T_COL_UPDATE_INFO));
405 }
406 
407 static void
409 {
410 #if defined(CAS_FOR_ORACLE) || defined(CAS_FOR_MYSQL)
411  FREE_MEM (srv_handle->sql_stmt);
413  hm_qresult_end (srv_handle, TRUE);
414  hm_session_free (srv_handle);
415 #else /* CAS_FOR_ORACLE || CAS_FOR_MYSQL */
416  FREE_MEM (srv_handle->sql_stmt);
418 
419  if (srv_handle->schema_type < 0 || srv_handle->schema_type == CCI_SCH_CLASS
420  || srv_handle->schema_type == CCI_SCH_VCLASS || srv_handle->schema_type == CCI_SCH_ATTRIBUTE
421  || srv_handle->schema_type == CCI_SCH_CLASS_ATTRIBUTE || srv_handle->schema_type == CCI_SCH_QUERY_SPEC
422  || srv_handle->schema_type == CCI_SCH_DIRECT_SUPER_CLASS || srv_handle->schema_type == CCI_SCH_PRIMARY_KEY)
423  {
424  hm_qresult_end (srv_handle, TRUE);
425  hm_session_free (srv_handle);
426  }
427  else if (srv_handle->schema_type == CCI_SCH_CLASS_PRIVILEGE || srv_handle->schema_type == CCI_SCH_ATTR_PRIVILEGE
428  || srv_handle->schema_type == CCI_SCH_SUPERCLASS || srv_handle->schema_type == CCI_SCH_SUBCLASS)
429  {
430  FREE_MEM (srv_handle->session);
431  srv_handle->cur_result = NULL;
432  }
433  else if (srv_handle->schema_type == CCI_SCH_TRIGGER)
434  {
435  if (srv_handle->session)
436  {
437  db_objlist_free ((DB_OBJLIST *) (srv_handle->session));
438  }
439  srv_handle->cur_result = NULL;
440  }
441  else if (srv_handle->schema_type == CCI_SCH_IMPORTED_KEYS || srv_handle->schema_type == CCI_SCH_EXPORTED_KEYS
442  || srv_handle->schema_type == CCI_SCH_CROSS_REFERENCE)
443  {
444  T_FK_INFO_RESULT *fk_res = (T_FK_INFO_RESULT *) srv_handle->session;
445 
446  if (fk_res != NULL)
447  {
449  srv_handle->session = NULL;
450  }
451  srv_handle->cur_result = NULL;
452  }
453 #endif /* CAS_FOR_ORACLE || CAS_FOR_MYSQL */
454 }
455 
456 static void
458 {
459  int i;
460 
461 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
462  if (q_result->col_update_info)
463  {
464  for (i = 0; i < q_result->num_column; i++)
465  {
466  FREE_MEM (q_result->col_update_info[i].attr_name);
467  FREE_MEM (q_result->col_update_info[i].class_name);
468  }
469  FREE_MEM (q_result->col_update_info);
470  }
471  q_result->col_updatable = FALSE;
472  q_result->num_column = 0;
473 #endif /* !CAS_FOR_ORACLE && !CAS_FOR_MYSQL */
474 }
475 
476 static void
477 srv_handle_rm_tmp_file (int h_id, T_SRV_HANDLE * srv_handle)
478 {
479 #if !defined(CAS_FOR_ORACLE) && !defined(CAS_FOR_MYSQL)
480  if (srv_handle->query_info_flag == TRUE)
481  {
482  char *p;
483 
484  p = cas_log_query_plan_file (h_id);
485  if (p != NULL)
486  {
487  unlink (p);
488  }
489  }
490 #endif /* !CAS_FOR_ORACLE && !CAS_FOR_MYSQL */
491 }
492 
493 int
495 {
496 #if !defined(LIBCAS_FOR_JSP)
497  return current_handle_count;
498 #else
499  return 0;
500 #endif
501 }
T_QUERY_RESULT * q_result
Definition: cas_handle.h:159
static int max_srv_handle
Definition: cas_handle.c:55
#define TRUE
Definition: broker_admin.c:49
static int max_handle_id
Definition: cas_handle.c:56
int max_prepared_stmt_count
Definition: broker_shm.h:623
int cur_result_index
Definition: cas_handle.h:173
char * sql_stmt
Definition: cas_handle.h:169
static void srv_handle_rm_tmp_file(int h_id, T_SRV_HANDLE *srv_handle)
Definition: cas_handle.c:477
static void col_update_info_free(T_QUERY_RESULT *q_result)
Definition: cas_handle.c:457
bool is_holdable
Definition: cas_handle.h:196
void * column_info
Definition: cas_handle.h:137
static void srv_handle_content_free(T_SRV_HANDLE *srv_handle)
Definition: cas_handle.c:408
static int current_handle_count
Definition: cas_handle.c:58
void db_query_format_free(DB_QUERY_TYPE *query_type)
Definition: db_query.c:1723
bool use_query_cache
Definition: cas_handle.h:194
bool has_result_set
Definition: cas_handle.h:175
void * cur_result
Definition: cas_handle.h:167
void release_all_fk_info_results(T_FK_INFO_RESULT *fk_res)
Definition: cas_execute.c:8460
int * classes_chn
Definition: cas_handle.h:172
void hm_qresult_clear(T_QUERY_RESULT *q_result)
Definition: cas_handle.c:308
T_PREPARE_CALL_INFO * prepare_call_info
Definition: cas_handle.h:158
#define SRV_HANDLE_ALLOC_SIZE
Definition: cas_handle.c:48
char cur_statement_pooling
Definition: broker_shm.h:313
void * session
Definition: cas_handle.h:153
void hm_srv_handle_free(int h_id)
Definition: cas_handle.c:155
int cas_shard_flag
Definition: cas.c:143
void hm_qresult_end(T_SRV_HANDLE *srv_handle, char free_flag)
Definition: cas_handle.c:314
char * cas_log_query_plan_file(int id)
Definition: cas_log.c:892
bool use_plan_cache
Definition: cas_handle.h:193
void ux_free_result(void *res)
Definition: cas_execute.c:3452
T_COL_UPDATE_INFO * col_update_info
Definition: cas_handle.h:136
void db_objlist_free(DB_OBJLIST *list)
Definition: db_admin.c:2612
bool is_from_current_transaction
Definition: cas_handle.h:197
unsigned int query_seq_num
Definition: cas_handle.h:184
T_SRV_HANDLE * hm_find_srv_handle(int h_id)
Definition: cas_handle.c:144
#define CAS_ERROR_INDICATOR
Definition: cas.h:39
#define NULL
Definition: freelistheap.h:34
if(extra_options)
Definition: dynamic_load.c:958
void db_close_session(DB_SESSION *session)
Definition: db_vdb.c:3319
#define MALLOC(SIZE)
Definition: cas_common.h:53
#define FREE_MEM(PTR)
Definition: cas_common.h:58
static T_SRV_HANDLE ** srv_handle_table
Definition: cas_handle.c:54
void hm_col_update_info_clear(T_COL_UPDATE_INFO *col_update_info)
Definition: cas_handle.c:402
char col_updatable
Definition: cas_handle.h:143
static T_SHM_APPL_SERVER * shm_appl
Definition: broker.c:311
char is_pooled
Definition: cas_handle.h:189
void hm_srv_handle_free_all(bool free_holdable)
Definition: cas_handle.c:186
int hm_new_srv_handle(T_SRV_HANDLE **new_handle, unsigned int seq_num)
Definition: cas_handle.c:62
char is_prepared
Definition: cas_handle.h:186
#define FALSE
Definition: broker_admin.c:50
T_APPL_SERVER_INFO * as_info
Definition: cas.c:153
#define ERROR_INFO_SET(ERR_CODE, ERR_INDICATOR)
Definition: cas_execute.h:49
void ** classes
Definition: cas_handle.h:171
char query_info_flag
Definition: cas_handle.h:188
int i
Definition: dynamic_load.c:954
void hm_srv_handle_qresult_end_all(bool end_holdable)
Definition: cas_handle.c:246
int num_q_result
Definition: cas_handle.h:174
void ux_prepare_call_info_free(T_PREPARE_CALL_INFO *call_info)
Definition: cas_execute.c:3626
const char ** p
Definition: dynamic_load.c:945
void hm_srv_handle_unset_prepare_flag_all(void)
Definition: cas_handle.c:226
#define REALLOC(PTR, SIZE)
Definition: cas_common.h:54
int hm_srv_handle_get_current_count(void)
Definition: cas_handle.c:494
void hm_session_free(T_SRV_HANDLE *srv_handle)
Definition: cas_handle.c:386