CUBRID Engine  latest
cci_stub.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  * cci_stub.c -
21  */
22 
23 #include "config.h"
24 
25 #include <string.h>
26 #include <assert.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include "api_util.h"
30 #include "api_common.h"
31 /* this is hack */
32 #define DBDEF_HEADER_
33 #include "cas_cci.h"
34 #undef DBDEF_HEADER_
35 
36 
37 /* ------------- */
38 /* API STRUCTURE */
39 /* ------------- */
40 typedef enum impl_handle_type IMPL_HANDLE_TYPE;
49 typedef struct api_val_s API_VAL;
51 typedef struct cci_object_s CCI_OBJECT;
54 
56 {
58  T_CCI_ERROR err_buf;
59  int rid;
60  CI_CONNECTION conn;
63  /* option related */
64  bool autocommit;
66  /* object pool */
68 };
69 
71 {
74 };
75 
77 {
80 };
81 
83 {
85  char sql[1];
86 };
87 
89 {
91  API_VAL *ary[1];
92 };
93 
95 {
99  int status;
101  /*
102  * parameter and parameter meta related fields
103  * - PM : parameter meta data api structure header
104  * - got_pm_handle : flag for indicating parameter related fields sanity
105  * - pm_handle : handle
106  * - num_col : number of column information
107  * - col_info : column meta information
108  * - params : parameter values
109  */
113  int num_col;
114  T_CCI_CUBRID_STMT cmd_type;
115  T_CCI_COL_INFO *col_info;
117  /*
118  * current result info (batch or multiple query in single statement)
119  * - has_resultset : flag for field availablity
120  * - res_handle : handle
121  * - num_query : query_result array size
122  * - curr_query_result_index
123  * - query_result : query_result array
124  * NOTE
125  * cci_next_result() closes current result set
126  */
131  T_CCI_QUERY_RESULT *query_result;
132  int curr_query_result_index; /* 0 start */
133 
134  /*
135  * fields for batch processing
136  * batch : list of BATCH_SQL_ITEM or BATCH_ARY_ITEM w.r.t. status
137  */
142 };
143 
145 {
148 };
149 
151 {
154 
155  /*
156  * provided (do not try to destroy them)
157  * parent, bh, req_handle, err_buf, on_close
158  */
160  bool updatable;
161  CI_CONNECTION conn;
164  T_CCI_ERROR *err_buf;
165  void *arg;
166  /* called when this structure is to be destroyed by resultset_impl_dtor */
167  void (*on_close) (RESULTSET_IMPL * pres, void *arg);
168 
169  /*
170  * result set cursor related
171  */
172  int offset;
173  bool fetched;
175  /*
176  * resultset meta fields (lazy initialized)
177  */
180  int num_col;
181  T_CCI_CUBRID_STMT cmd_type;
182  T_CCI_COL_INFO *col_info;
183 };
184 
185 struct api_val_s
186 {
187  CI_TYPE type;
188  void *ptr;
189  size_t len;
190 };
191 
193 {
194  CI_CONNECTION conn;
195  int flag;
196  T_CCI_A_TYPE atype;
197  void *value;
199  union
200  {
201  T_CCI_BIT bit_val;
202  T_CCI_DATE data_val;
203  int int_val;
204  char *cp;
205  char oid_buf[32];
206  T_CCI_SET tset;
207  } redirect;
208 };
209 #define API_VAL_CCI_BIND_FLAG_GET 0x01
210 #define API_VAL_CCI_BIND_FLAG_SET 0x02
211 
213 {
214  CI_OID xoid;
215  bool deleted;
219 };
220 
222 {
225  hash_table *ht; /* CI_OID to CCI_OBJECT */
226  hash_table *ght; /* CI_OID to GLO_OFFSET */
227  T_CCI_ERROR err_buf;
228 };
229 
231 {
233  CI_TYPE type; /* only supports homogenious collection type */
234  VALUE_INDEXER *indexer; /* value is pointer to API_VAL */
235  CI_CONNECTION conn; /* CCI_U_TYPE_OBJECT */
236 };
237 
238 /* ------------------- */
239 /* forward declaration */
240 /* ------------------- */
241 /* bind management */
243  BIND_HANDLE * handle);
244 /* error handling */
245 static int err_from_cci (int err);
246 
247 /* connection */
248 static void connection_impl_dtor (BH_BIND * bind);
249 static void init_connection_impl (CONNECTION_IMPL * impl, int rid, CI_CONNECTION conn, BH_INTERFACE * bh,
250  int conn_handle, CCI_OBJECT_POOL * pool);
251 static int complete_connection (CONNECTION_IMPL * impl);
252 /* api value and cci value binding */
253 static void api_val_dtor (VALUE_AREA * va, API_VALUE * val);
254 static CI_TYPE cci_u_type_to_type (T_CCI_U_TYPE utype);
255 static T_CCI_U_TYPE type_to_cci_u_type (CI_TYPE type);
256 static int get_value_from_api_val (const API_VAL * pv, CI_TYPE type, void *addr, size_t len, size_t * outlen,
257  bool * isnull);
258 static int set_value_to_api_val (API_VAL * pv, CI_TYPE type, void *addr, size_t len);
259 static int get_type_value_size (CI_TYPE type, int *len);
260 static void api_val_cci_bind_init (API_VAL_CCI_BIND * bind, CI_CONNECTION conn, int flag);
261 static int api_val_cci_bind_bind (CI_TYPE type, void *ptr, int len, API_VAL_CCI_BIND * bind);
262 static void api_val_cci_bind_clear (API_VAL_CCI_BIND * bind);
263 
264 static int api_val_bind_param (CI_CONNECTION conn, int req_handle, API_VAL * pv, int index);
265 static int get_value_from_req_handle (CI_CONNECTION conn, int req_handle, int index, CI_TYPE type, void *addr,
266  size_t len, size_t * outlen, bool * is_null);
267 static int get_value_from_tset (T_CCI_U_TYPE utype, T_CCI_SET tset, CI_TYPE type, CI_CONNECTION conn, int i,
268  API_VAL ** pv);
269 static int api_val_cursor_update (CI_CONNECTION conn, int req_handle, int offset, int index, API_VAL * av,
270  T_CCI_ERROR * err_buf);
271 /* parameter meta */
272 /* resultset ifs impl */
273 static int lazy_bind_qres_rmeta (RESULTSET_IMPL * pres);
275 static int api_qres_fetch (API_RESULTSET * res, int offset, CI_FETCH_POSITION pos);
276 static int api_qres_tell (API_RESULTSET * res, int *offset);
277 static int api_qres_clear_updates (API_RESULTSET * res);
278 static int api_qres_delete_row (API_RESULTSET * res);
279 static int api_qres_get_value (API_RESULTSET * res, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
280  bool * is_null);
281 static int api_qres_get_value_by_name (API_RESULTSET * res, const char *name, CI_TYPE type, void *addr, size_t len,
282  size_t * outlen, bool * isnull);
283 static int api_qres_update_value (API_RESULTSET * res, int index, CI_TYPE type, void *addr, size_t len);
284 static int api_qres_apply_update (API_RESULTSET * res);
285 static void api_qres_destroy (API_RESULTSET * res);
286 static int create_resultset_impl (CI_CONNECTION conn, BH_INTERFACE * bh, int req_handle, T_CCI_ERROR * err_buf,
287  COMMON_API_STRUCTURE * parent, bool updatable, void *arg,
288  void (*on_close) (RESULTSET_IMPL *, void *), API_RESULTSET_IFS * resifs,
289  API_RESULTSET_META_IFS * rmifs, RESULTSET_IMPL ** rpres);
290 static void resultset_impl_dtor (BH_BIND * bind);
291 
292 /* resultset meta ifs impl */
293 static int api_qrmeta_get_count (API_RESULTSET_META * rm, int *count);
294 static int api_qrmeta_get_info (API_RESULTSET_META * rm, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size);
295 /* statement */
296 static int lazy_bind_pstmt_pmeta (STATEMENT_IMPL * pstmt);
297 static void statement_impl_dtor (BH_BIND * bind);
298 static void init_statement_impl (STATEMENT_IMPL * pstmt, CONNECTION_IMPL * pconn);
299 static int statement_execute (STATEMENT_IMPL * pstmt, T_CCI_ERROR * err_buf);
301 static int complete_statement (STATEMENT_IMPL * pstmt);
302 static void on_close_statement_res (RESULTSET_IMPL * impl, void *arg);
303 
304 static int add_batch_params_restore_mapf (void *arg, int index, VALUE_AREA * va, API_VALUE * val);
305 static int add_batch_params_mapf (void *arg, int index, VALUE_AREA * va, API_VALUE * val);
306 static int stmt_execute_batch_sql (STATEMENT_IMPL * pstmt);
307 static int stmt_execute_batch_array (STATEMENT_IMPL * pstmt);
308 static int stmt_complete_batch (STATEMENT_IMPL * pstmt);
309 
310 /* object resultset and resultset meta api */
311 static int api_ormeta_get_count (API_RESULTSET_META * rm, int *count);
312 static int api_ormeta_get_info (API_RESULTSET_META * rm, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size);
314 static int api_ores_fetch (API_RESULTSET * res, int offset, CI_FETCH_POSITION pos);
315 static int api_ores_tell (API_RESULTSET * res, int *offset);
316 static int api_ores_clear_updates (API_RESULTSET * res);
317 static int api_ores_delete_row (API_RESULTSET * res);
318 static int api_ores_get_value (API_RESULTSET * res, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
319  bool * is_null);
320 static int api_ores_get_value_by_name (API_RESULTSET * res, const char *name, CI_TYPE type, void *addr, size_t len,
321  size_t * outlen, bool * isnull);
322 static int api_ores_update_value (API_RESULTSET * res, int index, CI_TYPE type, void *addr, size_t len);
323 static int api_ores_apply_update (API_RESULTSET * res);
324 static void api_ores_destroy (API_RESULTSET * res);
325 
326 
327 /* api object resultset pool implementation */
328 static int opool_get_object_resultset (API_OBJECT_RESULTSET_POOL * poo, CI_OID * oid, API_RESULTSET ** rres);
329 static int opool_oid_delete (API_OBJECT_RESULTSET_POOL * poo, CI_OID * oid);
330 static int opool_oid_get_classname (API_OBJECT_RESULTSET_POOL * pool, CI_OID * oid, char *name, size_t size);
331 static void opool_destroy (API_OBJECT_RESULTSET_POOL * poo);
332 
333 /* object pool related functions */
334 static int create_cci_object (CCI_OBJECT_POOL * pool, CI_OID * oid, CCI_OBJECT ** cobj);
335 static void destroy_cci_object (CCI_OBJECT * obj);
336 static void on_close_opool_res (RESULTSET_IMPL * impl, void *arg);
337 static void xoid2oidstr (const CI_OID * xoid, char *oidbuf);
338 static int oidstr2xoid (const char *oidstr, CI_CONNECTION conn, CI_OID * xoid);
339 
340 static int opool_ht_comparef (void *key1, void *key2, int *r);
341 static int opool_ht_hashf (void *key, unsigned int *rv);
342 static int opool_ht_keyf (void *elem, void **rk);
343 static void opool_ht_elem_dtor (void *elem);
344 static int opool_ght_keyf (void *elem, void **rk);
345 static void opool_ght_elem_dtor (void *elem);
346 static int opool_create (CONNECTION_IMPL * pconn, CCI_OBJECT_POOL ** rpool);
347 /* collection interface related */
348 static int api_col_length (API_COLLECTION * col, int *len);
349 static int api_col_insert (API_COLLECTION * col, long pos, CI_TYPE type, void *ptr, size_t size);
350 static int api_col_update (API_COLLECTION * col, long pos, CI_TYPE type, void *ptr, size_t size);
351 static int api_col_delete (API_COLLECTION * col, long pos);
352 static int api_col_get_elem_domain_info (API_COLLECTION * col, long pos, CI_TYPE * type, int *precision, int *scale);
353 static int api_col_get_elem (API_COLLECTION * col, long pos, CI_TYPE type, void *addr, size_t len, size_t * outlen,
354  bool * isnull);
355 static void api_col_destroy (API_COLLECTION * col);
356 
357 /* collection releated */
358 static void xcol_elem_dtor (VALUE_AREA * va, API_VALUE * av);
359 static int xcol_create (CI_TYPE type, CI_CONNECTION conn, CI_COLLECTION * rcol);
360 static void xcol_destroy (CI_COLLECTION col);
361 static int xcol_elem_cci_bind_mapf (void *arg, int index, VALUE_AREA * va, API_VALUE * av);
362 static int xcol_to_cci_set (CI_COLLECTION col, T_CCI_SET * tset);
363 
364 static int cci_set_to_xcol (CI_CONNECTION conn, T_CCI_SET tset, CI_COLLECTION * col);
365 static int xcol_copy (CI_COLLECTION col, CI_COLLECTION * rcol);
366 
367 
368 
369 /*
370  * bind_api_structure - make handle for COMMON_API_STRUCTURE s and
371  * bind the handle to the handle of COMMON_API_STRUCTURE
372  * parent
373  * return: NO_ERROR if successful, error code otherwise
374  * bh(in): BH_INTERFACE
375  * s(in): pointer to COMMON_API_STRUCTURE
376  * parent(in):pointer to COMMON_API_STRUCTURE
377  * handle(out): BIND_HANDLE
378  */
379 static int
381 {
382  int res;
383 
384  assert (s != NULL);
385  assert (handle != NULL);
386 
387  res = bh->alloc_handle (bh, (BH_BIND *) s, handle);
388  if (res != NO_ERROR)
389  {
390  return res;
391  }
392 
393  if (parent != NULL)
394  {
395  res = bh->bind_graft (bh, (BH_BIND *) s, (BH_BIND *) parent);
396  if (res != NO_ERROR)
397  { /* destroy handle only */
398  bh_destroyf dtor = s->bind.dtor;
399  s->bind.dtor = NULL;
400  bh->destroy_handle (bh, *handle);
401  s->bind.dtor = dtor;
402  }
403  return res;
404  }
405 
406  return NO_ERROR;
407 }
408 
409 /*
410  * err_from_cci - convert CCI error code to CUBRID API error code
411  * return: error code
412  * err(in): CCI error code
413  */
414 static int
416 {
417  switch (err)
418  {
419  case CCI_ER_NO_ERROR:
420  return NO_ERROR;
421  case CCI_ER_DBMS:
422  return ER_INTERFACE_DBMS;
423  case CCI_ER_CON_HANDLE:
424  case CCI_ER_NO_MORE_MEMORY:
425  case CCI_ER_COMMUNICATION:
426  case CCI_ER_NO_MORE_DATA:
427  case CCI_ER_TRAN_TYPE:
428  case CCI_ER_STRING_PARAM:
429  case CCI_ER_TYPE_CONVERSION:
430  case CCI_ER_BIND_INDEX:
431  case CCI_ER_ATYPE:
432  case CCI_ER_PARAM_NAME:
433  case CCI_ER_COLUMN_INDEX:
434  case CCI_ER_SCHEMA_TYPE:
435  case CCI_ER_FILE:
436  case CCI_ER_CONNECT:
437  case CCI_ER_ALLOC_CON_HANDLE:
438  case CCI_ER_REQ_HANDLE:
439  case CCI_ER_INVALID_CURSOR_POS:
440  case CCI_ER_HOSTNAME:
441  case CCI_ER_OBJECT:
442  case CCI_ER_SET_INDEX:
443  case CCI_ER_DELETED_TUPLE:
444  case CCI_ER_SAVEPOINT_CMD:
445  case CCI_ER_THREAD_RUNNING:
446  case CCI_ER_ISOLATION_LEVEL:
447  case CCI_ER_BIND_ARRAY_SIZE:
448  case CCI_ER_OID_CMD:
449  case CCI_ER_NOT_BIND:
450  case CCI_ER_CAS:
451  case CAS_ER_INTERNAL:
454  case CAS_ER_ARGS:
455  case CAS_ER_TRAN_TYPE:
456  case CAS_ER_SRV_HANDLE:
457  case CAS_ER_NUM_BIND:
459  case CAS_ER_DB_VALUE:
461  case CAS_ER_PARAM_NAME:
462  case CAS_ER_NO_MORE_DATA:
463  case CAS_ER_OBJECT:
464  case CAS_ER_OPEN_FILE:
465  case CAS_ER_SCHEMA_TYPE:
466  case CAS_ER_VERSION:
467  case CAS_ER_FREE_SERVER:
469  case CAS_ER_QUERY_CANCEL:
474  case CAS_ER_STMT_POOLING:
477  case CAS_ER_IS:
478  case CCI_ER_NOT_IMPLEMENTED:
479  return ER_INTERFACE_BROKER;
480  default:
481  return ER_INTERFACE_GENERIC;
482  }
483 }
484 
485 /*
486  * connection_impl_dtor - CONNECTION_IMPL structure bind handle destructor
487  * return: void
488  * bind(in): pointer to CONNECTON_IMPL
489  */
490 static void
492 {
493  CONNECTION_IMPL *impl = (CONNECTION_IMPL *) bind;
494 
495  if (impl)
496  {
497  if (impl->conn_handle >= 0)
498  {
499  (void) cci_disconnect (impl->conn_handle, &impl->err_buf);
500  }
501  API_FREE (impl);
502  }
503 
504  if (impl->opool)
505  {
507  }
508 }
509 
510 /*
511  * init_connection_impl - initialize CONNECTION_IMPL structure
512  * return: void
513  * pconn(int): pointer to CONNECTION_IMPL
514  * rid(int): root id
515  * conn(int): CI_CONNECTION
516  * bh(int): BH_INTERFACE
517  * conn_handle(int): CCI connection handle
518  * pool(in): CCI_OBJECT_POOL
519  */
520 static void
521 init_connection_impl (CONNECTION_IMPL * pconn, int rid, CI_CONNECTION conn, BH_INTERFACE * bh, int conn_handle,
522  CCI_OBJECT_POOL * pool)
523 {
524  pconn->conn = conn;
525  pconn->bind.dtor = connection_impl_dtor;
526  pconn->handle_type = HANDLE_TYPE_CONNECTION;
527  pconn->err_buf.err_code = 0;
528  pconn->err_buf.err_msg[0] = 0;
529  pconn->rid = rid;
530  pconn->bh = bh;
531  pconn->conn_handle = conn_handle;
532  pconn->autocommit = false;
533  pconn->n_need_complete = 0;
534  pconn->opool = pool;
535 }
536 
537 /*
538  * completes all incompleted object bound to this connection
539  */
540 
541 /*
542  * complete_connection - complete transaction boundary resources
543  * return: NO_ERROR if successful, error code otherwise
544  * pconn(in): pointer to CONNECTION_IMPL
545  */
546 static int
548 {
550  int res;
551 
552  res = pconn->bh->bind_get_first_child (pconn->bh, (BH_BIND *) pconn, (BH_BIND **) (&st));
553  if (res != NO_ERROR)
554  {
555  return res;
556  }
557 
558  while (st != NULL)
559  {
560  if (st->handle_type == HANDLE_TYPE_STATEMENT)
561  {
562  res = complete_statement ((STATEMENT_IMPL *) st);
563  if (res != NO_ERROR)
564  {
565  return res;
566  }
567  }
568  res = pconn->bh->bind_get_next_sibling (pconn->bh, (BH_BIND *) st, (BH_BIND **) (&st));
569  if (res != NO_ERROR)
570  {
571  return res;
572  }
573  }
574 
575  return NO_ERROR;
576 }
577 
578 
579 /*
580  * api_val_dtor - API_VAL VALUE_INDEXER destructor
581  * return: NO_ERROR if successful, error code otherwise
582  * va(in): VALUE_AREA
583  * val(in): API_VALUE
584  */
585 static void
587 {
588  if (val != NULL)
589  {
590  API_VAL *pv = (API_VAL *) val;
591 
592  if (pv->type == CI_TYPE_COLLECTION)
593  {
594  xcol_destroy (*(CI_COLLECTION *) pv->ptr);
595  }
596 
597  if (pv->ptr)
598  {
599  API_FREE (pv->ptr);
600  }
601  API_FREE (pv);
602  }
603 }
604 
605 
606 /*
607  * cci_u_type_to_type - map T_CCI_U_TYPE to CI_TYPE
608  * return: CI_TYPE
609  * utype(in): T_CCI_U_TYPE
610  */
611 static CI_TYPE
612 cci_u_type_to_type (T_CCI_U_TYPE utype)
613 {
614  switch (utype)
615  {
616  case CCI_U_TYPE_NULL:
617  return CI_TYPE_NULL;
618  case CCI_U_TYPE_CHAR:
619  return CI_TYPE_CHAR;
620  case CCI_U_TYPE_STRING:
621  return CI_TYPE_VARCHAR;
622  case CCI_U_TYPE_NCHAR:
623  return CI_TYPE_NCHAR;
624  case CCI_U_TYPE_VARNCHAR:
625  return CI_TYPE_VARNCHAR;
626  case CCI_U_TYPE_BIT:
627  return CI_TYPE_BIT;
628  case CCI_U_TYPE_VARBIT:
629  return CI_TYPE_VARBIT;
630  case CCI_U_TYPE_NUMERIC:
631  return CI_TYPE_NUMERIC;
632  case CCI_U_TYPE_BIGINT:
633  case CCI_U_TYPE_UBIGINT:
634  return CI_TYPE_BIGINT;
635  case CCI_U_TYPE_INT:
636  case CCI_U_TYPE_UINT:
637  return CI_TYPE_INT;
638  case CCI_U_TYPE_SHORT:
639  case CCI_U_TYPE_USHORT:
640  return CI_TYPE_SHORT;
641  case CCI_U_TYPE_MONETARY:
642  return CI_TYPE_MONETARY;
643  case CCI_U_TYPE_FLOAT:
644  return CI_TYPE_FLOAT;
645  case CCI_U_TYPE_DOUBLE:
646  return CI_TYPE_DOUBLE;
647  case CCI_U_TYPE_DATE:
648  return CI_TYPE_DATE;
649  case CCI_U_TYPE_TIME:
650  return CI_TYPE_TIME;
651  case CCI_U_TYPE_TIMESTAMP:
652  return CI_TYPE_TIMESTAMP;
653  case CCI_U_TYPE_DATETIME:
654  return CI_TYPE_DATETIME;
655  case CCI_U_TYPE_SET:
656  case CCI_U_TYPE_MULTISET:
657  case CCI_U_TYPE_SEQUENCE:
658  return CI_TYPE_COLLECTION;
659  case CCI_U_TYPE_OBJECT:
660  return CI_TYPE_OID;
661  case CCI_U_TYPE_RESULTSET:
662  default:
663  return CI_TYPE_NULL;
664  }
665  return CI_TYPE_NULL;
666 }
667 
668 
669 /*
670  * type_to_cci_u_type - map CI_TYPE to T_CCI_U_TYPE
671  * return: T_CCI_U_TYPE
672  * type(in): CI_TYPE
673  */
674 static T_CCI_U_TYPE
675 type_to_cci_u_type (CI_TYPE type)
676 {
677  switch (type)
678  {
679  case CI_TYPE_NULL:
680  return CCI_U_TYPE_NULL;
681  case CI_TYPE_BIGINT:
682  return CCI_U_TYPE_BIGINT;
683  case CI_TYPE_INT:
684  return CCI_U_TYPE_INT;
685  case CI_TYPE_SHORT:
686  return CCI_U_TYPE_SHORT;
687  case CI_TYPE_FLOAT:
688  return CCI_U_TYPE_FLOAT;
689  case CI_TYPE_DOUBLE:
690  return CCI_U_TYPE_DOUBLE;
691  case CI_TYPE_CHAR:
692  return CCI_U_TYPE_CHAR;
693  case CI_TYPE_VARCHAR:
694  return CCI_U_TYPE_STRING;
695  case CI_TYPE_NCHAR:
696  return CCI_U_TYPE_NCHAR;
697  case CI_TYPE_VARNCHAR:
698  return CCI_U_TYPE_VARNCHAR;
699  case CI_TYPE_BIT:
700  return CCI_U_TYPE_BIT;
701  case CI_TYPE_VARBIT:
702  return CCI_U_TYPE_VARBIT;
703  case CI_TYPE_TIME:
704  return CCI_U_TYPE_TIME;
705  case CI_TYPE_DATE:
706  return CCI_U_TYPE_DATE;
707  case CI_TYPE_TIMESTAMP:
708  return CCI_U_TYPE_TIMESTAMP;
709  case CI_TYPE_DATETIME:
710  return CCI_U_TYPE_DATETIME;
711  case CI_TYPE_MONETARY:
712  return CCI_U_TYPE_MONETARY;
713  case CI_TYPE_NUMERIC:
714  return CCI_U_TYPE_NUMERIC;
715  case CI_TYPE_OID:
716  return CCI_U_TYPE_OBJECT;
717  case CI_TYPE_COLLECTION:
718  return CCI_U_TYPE_SEQUENCE;
719  default:
720  break;
721  }
722  return CCI_U_TYPE_NULL;
723 }
724 
725 /*
726  * get_value_from_api_val - get CUBRID C API value from API_VAL
727  * return: NO_ERROR if successful, error code otherwise
728  * pv(in): pointer to API_VAL
729  * type(in): CI_TYPE
730  * addr(out): address of the container of type value
731  * len(in): length of container pointed by addr field
732  * outlen(out): written size
733  * isnull(out): null indicator
734  *
735  * NOTE : no non-trvial conversion is allowed between CUBRID C API native
736  * type values
737  */
738 static int
739 get_value_from_api_val (const API_VAL * pv, CI_TYPE type, void *addr, size_t len, size_t * outlen, bool * isnull)
740 {
741  if (pv->type != type)
743 
744  if (len < pv->len)
746 
747  if (type == CI_TYPE_NULL)
748  {
749  *isnull = true;
750  return NO_ERROR;
751  }
752  else if (type == CI_TYPE_COLLECTION)
753  {
754  CI_COLLECTION col;
755  int res;
756 
757  res = xcol_copy (*(CI_COLLECTION *) pv->ptr, &col);
758  if (res != NO_ERROR)
759  return res;
760 
761  *(CI_COLLECTION *) addr = col;
762  *outlen = sizeof (CI_COLLECTION);
763 
764  return NO_ERROR;
765  }
766 
767  memcpy (addr, pv->ptr, pv->len);
768  *outlen = pv->len;
769 
770  return NO_ERROR;
771 }
772 
773 /*
774  * set_value_to_api_val - set CUBRID C API type value to API_VAL structure
775  * return: NO_ERROR if successful, error code otherwise
776  * pv(in): pointer to API_VAL
777  * type(in): CI_TYPE
778  * addr(in): address of type value container
779  * len(in): length of type value container
780  */
781 static int
782 set_value_to_api_val (API_VAL * pv, CI_TYPE type, void *addr, size_t len)
783 {
784  void *ptr;
785 
786  /* clear previous value */
787  if (pv->type == CI_TYPE_COLLECTION)
788  {
789  CI_COLLECTION col = *(CI_COLLECTION *) pv->ptr;
790 
791  if (col != NULL)
792  xcol_destroy (col);
793  pv->ptr = NULL;
794  }
795 
796  /* reuse holder place if possible */
797  if (pv->len >= len)
798  {
799  pv->type = type;
800  memcpy (pv->ptr, addr, len);
801 
802  return NO_ERROR;
803  }
804 
805  ptr = API_MALLOC (len + 1);
806  if (!ptr)
808 
809  memcpy (ptr, addr, len);
810  ((char *) ptr)[len] = 0;
811  API_FREE (pv->ptr);
812  pv->type = type;
813  pv->ptr = ptr;
814  pv->len = len;
815 
816  return NO_ERROR;
817 }
818 
819 /*
820  * get_type_value_size - get the size of container from CI_TYPE
821  * return: NO_ERROR if successful, error code otherwise
822  * type(in): CI_TYPE
823  * len(out): 0 if type is variable size
824  * >0 if type value is fixed size
825  * <0 on error
826  */
827 static int
828 get_type_value_size (CI_TYPE type, int *len)
829 {
830  assert (len != NULL);
831 
832  switch (type)
833  {
834  case CI_TYPE_BIGINT:
835  *len = sizeof (INT64);
836  break;
837 
838  case CI_TYPE_INT:
839  *len = sizeof (int);
840  break;
841 
842  case CI_TYPE_SHORT:
843  *len = sizeof (short);
844  break;
845 
846  case CI_TYPE_FLOAT:
847  *len = sizeof (float);
848  break;
849 
850  case CI_TYPE_DOUBLE:
851  case CI_TYPE_MONETARY:
852  *len = sizeof (double);
853  break;
854 
855  case CI_TYPE_CHAR:
856  case CI_TYPE_VARCHAR:
857  case CI_TYPE_NCHAR:
858  case CI_TYPE_VARNCHAR:
859  case CI_TYPE_BIT:
860  case CI_TYPE_VARBIT:
861  case CI_TYPE_NUMERIC:
862  *len = 0;
863  break;
864 
865  case CI_TYPE_TIME:
866  case CI_TYPE_DATE:
867  case CI_TYPE_TIMESTAMP:
868  case CI_TYPE_DATETIME:
869  *len = sizeof (CI_TIME);
870  break;
871 
872  case CI_TYPE_OID:
873  *len = sizeof (CI_OID);
874  break;
875 
876  case CI_TYPE_COLLECTION:
877  *len = sizeof (CI_COLLECTION);
878  break;
879 
880  case CI_TYPE_NULL: /* should be checked before */
881  default:
882  *len = -1;
883  return ER_INTERFACE_GENERIC;
884  }
885 
886  return NO_ERROR;
887 }
888 
889 /*
890  * api_val_cci_bind_bind - set value, atype, directed fields of API_VAL_CCI_BIND
891  * structure w.r.t. CI_TYPE
892  * return: NO_ERROR if successful, error code otherwise
893  * type(in): CI_TYPE
894  * ptr(in): address of value container
895  * len(in): length of value container
896  * bind(in): pointer to API_VAL_CCI_BIND structure
897  */
898 static int
899 api_val_cci_bind_bind (CI_TYPE type, void *ptr, int len, API_VAL_CCI_BIND * bind)
900 {
901  bind->value = NULL;
902  bind->atype = CCI_A_TYPE_STR;
903  bind->redirected = false;
904 
905  if ((type != CI_TYPE_NULL && (ptr == NULL || len <= 0)))
907 
908  assert (bind != NULL);
909 
910  /* determine atype and value ptr */
911  switch (type)
912  {
913  case CI_TYPE_NULL:
914  bind->value = NULL;
915  return NO_ERROR;
916 
917  case CI_TYPE_INT:
918  if (len < SSIZEOF (int))
919  {
921  }
922  bind->atype = CCI_A_TYPE_INT;
923  bind->value = ptr;
924 
925  return NO_ERROR;
926 
927  case CI_TYPE_SHORT:
928  if (len < SSIZEOF (short))
929  {
931  }
932 
933  bind->atype = CCI_A_TYPE_INT;
934  bind->value = &bind->redirect.int_val;
935  bind->redirected = true;
936  if (bind->flag & API_VAL_CCI_BIND_FLAG_SET)
937  {
938  bind->redirect.int_val = *(short *) ptr;
939  }
940 
941  return NO_ERROR;
942 
943  case CI_TYPE_FLOAT:
944  if (len < SSIZEOF (float))
945  {
947  }
948  bind->atype = CCI_A_TYPE_FLOAT;
949  bind->value = ptr;
950 
951  return NO_ERROR;
952 
953  case CI_TYPE_DOUBLE:
954  if (len < SSIZEOF (float))
955  {
957  }
958 
959  bind->atype = CCI_A_TYPE_DOUBLE;
960  bind->value = ptr;
961 
962  return NO_ERROR;
963 
964  case CI_TYPE_CHAR:
965  case CI_TYPE_VARCHAR:
966  case CI_TYPE_NCHAR:
967  case CI_TYPE_VARNCHAR:
968  if (len < 1) /* need re-check after data get */
969  {
971  }
972 
973  bind->atype = CCI_A_TYPE_STR;
974  if (bind->flag & API_VAL_CCI_BIND_FLAG_SET)
975  bind->value = ptr;
976  else
977  {
978  bind->value = &bind->redirect.cp;
979  bind->redirected = true;
980  }
981 
982  return NO_ERROR;
983 
984  case CI_TYPE_BIT:
985  case CI_TYPE_VARBIT:
986  bind->atype = CCI_A_TYPE_BIT;
987  bind->redirected = true;
988 
989  if (bind->flag & API_VAL_CCI_BIND_FLAG_SET)
990  {
991  bind->redirect.bit_val.size = (len + 7) / 8;
992  bind->redirect.bit_val.buf = (char *) ptr;
993  bind->value = &bind->redirect.bit_val;
994  }
995  else
996  {
997  bind->value = &bind->redirect.bit_val;
998  }
999 
1000  return NO_ERROR;
1001 
1002  case CI_TYPE_TIME:
1003  case CI_TYPE_DATE:
1004  case CI_TYPE_TIMESTAMP:
1005  case CI_TYPE_DATETIME:
1006  if (len < SSIZEOF (CI_TIME))
1007  {
1009  }
1010 
1011  bind->atype = CCI_A_TYPE_DATE;
1012  bind->value = ptr;
1013 
1014  return NO_ERROR;
1015 
1016  case CI_TYPE_MONETARY:
1017  if (len < SSIZEOF (double))
1018  {
1020  }
1021 
1022  bind->atype = CCI_A_TYPE_DOUBLE;
1023  bind->value = ptr;
1024 
1025  return NO_ERROR;
1026 
1027  case CI_TYPE_NUMERIC:
1028  /* need re-check */
1029  if (len < 1)
1030  {
1032  }
1033 
1034  bind->atype = CCI_A_TYPE_STR;
1035  if (bind->flag & API_VAL_CCI_BIND_FLAG_SET)
1036  {
1037  bind->value = ptr;
1038  }
1039  else
1040  {
1041  bind->value = &bind->redirect.cp;
1042  bind->redirected = true;
1043  }
1044 
1045  return NO_ERROR;
1046 
1047  case CI_TYPE_OID:
1048  /* need re-check (w.r.t. CI_TYPE) */
1049  if (len < 1)
1050  {
1052  }
1053 
1054  bind->atype = CCI_A_TYPE_STR;
1055  bind->redirected = true;
1056  bind->value = bind->redirect.oid_buf;
1057  if (bind->flag & API_VAL_CCI_BIND_FLAG_SET)
1058  {
1059  xoid2oidstr ((CI_OID *) ptr, (char *) bind->value);
1060  }
1061 
1062  return NO_ERROR;
1063 
1064  case CI_TYPE_COLLECTION:
1065  if (len < SSIZEOF (CI_COLLECTION *))
1066  {
1068  }
1069 
1070  if (bind->flag & API_VAL_CCI_BIND_FLAG_SET)
1071  {
1072  int res;
1073  T_CCI_SET tset = NULL;
1074 
1075  res = xcol_to_cci_set (*(CI_COLLECTION *) ptr, &tset);
1076  if (res != NO_ERROR)
1077  return res;
1078 
1079  bind->atype = CCI_A_TYPE_SET;
1080  bind->redirect.tset = tset;
1081  bind->value = &bind->redirect.tset;
1082  bind->redirected = true;
1083  }
1084  else
1085  {
1086  bind->atype = CCI_A_TYPE_SET;
1087  bind->redirect.tset = NULL;
1088  bind->value = &bind->redirect.tset;
1089  }
1090 
1091  return NO_ERROR;
1092 
1093  default:
1095  }
1096 }
1097 
1098 
1099 /*
1100  * api_val_cci_bind_init - initialize API_VAL_CCI_BIND structure
1101  * return: void
1102  * bind(in/out): pointer to API_VAL_CCI_BIND
1103  * conn(in): CI_CONNECTION handle
1104  * flag(in): flag (get/set purpose)
1105  */
1106 static void
1107 api_val_cci_bind_init (API_VAL_CCI_BIND * bind, CI_CONNECTION conn, int flag)
1108 {
1109  memset (bind, 0, sizeof (*bind));
1110  bind->conn = conn;
1111  bind->flag = flag;
1112 }
1113 
1114 /*
1115  * api_val_cci_bind_clear - clear API_VAL_CCI_BIND structure
1116  * return: void
1117  * bind(in/out): API_VAL_CCI_BIND structure
1118  */
1119 static void
1121 {
1122  if (bind->redirected && bind->atype == CCI_A_TYPE_SET && bind->redirect.tset != NULL)
1123  {
1124  cci_set_free (bind->redirect.tset);
1125  bind->redirect.tset = NULL;
1126  }
1127 
1128  bind->redirected = false;
1129  bind->flag = 0;
1130 
1131  return;
1132 }
1133 
1134 /*
1135  * api_val_bind_param - call cci_bind_param() from API_VAL structure
1136  * return: NO_ERROR if successful, error code otherwise
1137  * conn(in): CI_CONNECTION handle
1138  * req_handle(in): CCI request handle
1139  * pv(in): pointer to API_VAL
1140  * index(in): parameter index
1141  */
1142 static int
1143 api_val_bind_param (CI_CONNECTION conn, int req_handle, API_VAL * pv, int index)
1144 {
1145  T_CCI_U_TYPE utype;
1146  API_VAL_CCI_BIND bind;
1147  int res;
1148 
1149  utype = type_to_cci_u_type (pv->type);
1150 
1152  res = api_val_cci_bind_bind (pv->type, pv->ptr, pv->len, &bind);
1153  if (res != NO_ERROR)
1154  {
1155  api_val_cci_bind_clear (&bind);
1156  return res;
1157  }
1158 
1159  res = cci_bind_param (req_handle, index, bind.atype, bind.value, utype, CCI_BIND_PTR);
1160  api_val_cci_bind_clear (&bind);
1161 
1162  if (res != 0)
1163  {
1164  return err_from_cci (res);
1165  }
1166 
1167  return NO_ERROR;
1168 }
1169 
1170 /*
1171  * get_value_from_req_handle - get CUBRID C API value from cci_get_dat()
1172  * return: NO_ERROR if successful, error code otherwise
1173  * conn(in): CI_CONNECTION handle
1174  * req_handle(in): CCI request handle
1175  * index(in): CCI column index
1176  * type(in): CI_TYPE
1177  * addr(out): address of value container
1178  * len(in): length of value container
1179  * outlen(out): actuall written size
1180  * is_null(out): null indicator
1181  */
1182 static int
1183 get_value_from_req_handle (CI_CONNECTION conn, int req_handle, int index, CI_TYPE type, void *addr, size_t len,
1184  size_t * outlen, bool * is_null)
1185 {
1186  API_VAL_CCI_BIND bind;
1187  int res;
1188  int indicator;
1189 
1191  res = api_val_cci_bind_bind (type, addr, len, &bind);
1192  if (res != NO_ERROR)
1193  {
1194  api_val_cci_bind_clear (&bind);
1195  return res;
1196  }
1197 
1198  res = cci_get_data (req_handle, index, bind.atype, bind.value, &indicator);
1199  if (res != 0)
1200  {
1201  api_val_cci_bind_clear (&bind);
1202  return err_from_cci (res);
1203  }
1204 
1205  if (indicator == -1)
1206  {
1207  *is_null = true;
1208  api_val_cci_bind_clear (&bind);
1209  return NO_ERROR;
1210  }
1211  else
1212  {
1213  *is_null = false;
1214  }
1215 
1216  if (bind.redirected)
1217  {
1218  if (type == CI_TYPE_OID)
1219  {
1220  /*
1221  * this implies bind.atype == CCI_A_TYPE_STR so shoud be
1222  * checked before other cases which binds results
1223  * bind.atype == CCI_A_TYPE_STR
1224  */
1225  oidstr2xoid (bind.redirect.oid_buf, bind.conn, (CI_OID *) addr);
1226  }
1227  else if (bind.atype == CCI_A_TYPE_BIT)
1228  {
1229  *outlen = bind.redirect.bit_val.size * 8;
1230  if (*outlen > len)
1231  {
1233  }
1234 
1235  memcpy (addr, bind.redirect.bit_val.buf, bind.redirect.bit_val.size);
1236  }
1237  else if (bind.atype == CCI_A_TYPE_STR)
1238  {
1239  if (indicator + 1 > (ssize_t) len)
1240  {
1242  }
1243 
1244  *outlen = indicator;
1245  memcpy (addr, bind.redirect.cp, indicator);
1246  ((char *) addr)[indicator] = 0;
1247  }
1248  else if (bind.atype == CCI_A_TYPE_SET)
1249  {
1250  CI_COLLECTION col;
1251 
1252  res = cci_set_to_xcol (conn, bind.redirect.tset, &col);
1253  if (res != NO_ERROR)
1254  return res;
1255 
1256  *(CI_COLLECTION *) addr = col;
1257 
1258  return NO_ERROR;
1259  }
1260  else
1261  {
1262  assert (0);
1263  return ER_INTERFACE_GENERIC;
1264  }
1265  }
1266 
1267  api_val_cci_bind_clear (&bind);
1268 
1269  return NO_ERROR;
1270 }
1271 
1272 /*
1273  * get_value_from_tset - get value of CCI set structure
1274  * return: NO_ERROR if successful, error code otherwise
1275  * utype(in):
1276  * tset(in): type of tset. precalcuated to prevent repeated function call
1277  * type(in): dest type of pv
1278  * conn(in): CI_CONNECTION handle
1279  * i(in): index of element
1280  * pv(out): API_VAL created
1281  */
1282 static int
1283 get_value_from_tset (T_CCI_U_TYPE utype, T_CCI_SET tset, CI_TYPE type, CI_CONNECTION conn, int i, API_VAL ** pv)
1284 {
1285  int res;
1286  void *ptr;
1287  int len;
1288  API_VAL *pval;
1289  API_VAL_CCI_BIND bind;
1290  int indicator;
1291  union
1292  {
1293  int ival;
1294  float fval;
1295  double dval;
1296  void *ptr;
1297  CI_TIME tval;
1298  CI_OID oidval;
1299  CI_COLLECTION col;
1300  } data;
1301 
1302  assert (pv != NULL);
1303 
1305 
1306  res = api_val_cci_bind_bind (type, &data, sizeof (data), &bind);
1307  if (res != NO_ERROR)
1308  {
1309  return res;
1310  }
1311 
1312  res = cci_set_get (tset, i + 1, bind.atype, bind.value, &indicator);
1313  if (res != 0)
1314  {
1315  api_val_cci_bind_clear (&bind);
1316  return err_from_cci (res);
1317  }
1318 
1319  /* determine type, ptr, len for API_VAL creation */
1320  if (indicator == -1)
1321  {
1322  /* null value */
1323  type = CI_TYPE_NULL;
1324  ptr = NULL;
1325  len = 0;
1326  }
1327  else if (bind.redirected)
1328  {
1329  if (type == CI_TYPE_OID)
1330  {
1331  CI_OID *xoid;
1332 
1333  len = sizeof (*xoid);
1334  xoid = API_MALLOC (len);
1335  if (xoid == NULL)
1336  {
1337  api_val_cci_bind_clear (&bind);
1339  }
1340  oidstr2xoid (bind.redirect.oid_buf, conn, xoid);
1341  ptr = xoid;
1342  }
1343  else if (bind.atype == CCI_A_TYPE_BIT)
1344  {
1345  len = bind.redirect.bit_val.size;
1346  ptr = API_MALLOC (len);
1347  if (!ptr)
1348  {
1349  api_val_cci_bind_clear (&bind);
1351  }
1352  memcpy (ptr, bind.redirect.bit_val.buf, len);
1353  }
1354  else if (bind.atype == CCI_A_TYPE_STR)
1355  {
1356  len = indicator + 1;
1357  ptr = API_MALLOC (len);
1358  if (!ptr)
1359  {
1360  api_val_cci_bind_clear (&bind);
1362  }
1363  memcpy (ptr, bind.redirect.cp, len);
1364  ((char *) ptr)[indicator] = 0;
1365  }
1366  else if (bind.atype == CCI_A_TYPE_SET)
1367  {
1368  CI_COLLECTION col;
1369 
1370  len = sizeof (CI_COLLECTION *);
1371  ptr = API_MALLOC (len);
1372  if (!ptr)
1373  {
1374  api_val_cci_bind_clear (&bind);
1376  }
1377 
1378  res = cci_set_to_xcol (conn, bind.redirect.tset, &col);
1379  if (res != NO_ERROR)
1380  {
1381  API_FREE (ptr);
1382  api_val_cci_bind_clear (&bind);
1383  return res;
1384  }
1385  *(CI_COLLECTION *) ptr = col;
1386  }
1387  else
1388  {
1389  assert (0); /* should not happen */
1390  return ER_INTERFACE_GENERIC;
1391  }
1392  }
1393  else
1394  {
1395  res = get_type_value_size (type, &len);
1396  if (res != NO_ERROR)
1397  {
1398  api_val_cci_bind_clear (&bind);
1399  return res;
1400  }
1401 
1402  assert (len > 0); /* variable size should be redirecteded */
1403 
1404  ptr = API_MALLOC (len);
1405  if (ptr == NULL)
1406  {
1407  api_val_cci_bind_clear (&bind);
1409  }
1410  }
1411 
1412  pval = API_MALLOC (sizeof (*pval));
1413  if (pval == NULL)
1414  {
1415  API_FREE (ptr);
1416  api_val_cci_bind_clear (&bind);
1418  }
1419 
1420  pval->type = type;
1421  pval->ptr = ptr;
1422  pval->len = len;
1423  *pv = pval;
1424 
1425  return NO_ERROR;
1426 }
1427 
1428 /* cci_cursor_update */
1429 
1430 /*
1431  * api_val_cursor_update - call cci_cursor_update() whth API_VAL
1432  * return: NO_ERROR if successful, error code otherwise
1433  * conn(in): CI_CONNECTION
1434  * req_handle(in): CCI request handle
1435  * offset(in): cursor offset
1436  * index(in): column index
1437  * pv(in): pointer to API_VAL
1438  * err_buf(out): CCI error buffer
1439  */
1440 static int
1441 api_val_cursor_update (CI_CONNECTION conn, int req_handle, int offset, int index, API_VAL * pv, T_CCI_ERROR * err_buf)
1442 {
1443  API_VAL_CCI_BIND bind;
1444  int res;
1445 
1447 
1448  res = api_val_cci_bind_bind (pv->type, pv->ptr, pv->len, &bind);
1449  if (res != NO_ERROR)
1450  {
1451  api_val_cci_bind_clear (&bind);
1452  return res;
1453  }
1454 
1455  res = cci_cursor_update (req_handle, offset, index, bind.atype, bind.value, err_buf);
1456 
1457  api_val_cci_bind_clear (&bind);
1458 
1459  if (res != 0)
1460  return err_from_cci (res);
1461 
1462  return NO_ERROR;
1463 }
1464 
1465 /*
1466  * lazy_bind_qres_rmeta - create and bind resultset meta handle of RESULTSET_IMPL
1467  * return: NO_ERROR if successful, error code otherwise
1468  * pres(in): pointer to RESULTSET_IMPL
1469  */
1470 static int
1472 {
1473  API_RESULTSET_META *prm;
1475  int res;
1476 
1477  if (pres->got_rm_handle)
1478  return NO_ERROR;
1479 
1480  prm = (API_RESULTSET_META *) (&pres->RM);
1481  res = bind_api_structure (pres->bh, (COMMON_API_STRUCTURE *) prm, (COMMON_API_STRUCTURE *) pres, &handle);
1482  if (res != NO_ERROR)
1483  {
1484  return res;
1485  }
1486 
1487  pres->got_rm_handle = true;
1488  pres->rm_handle = handle;
1489 
1490  return NO_ERROR;
1491 }
1492 
1493 /*
1494  * api_qres_get_resultset_metadata - API_RESULTSET::get_resultset_metadata
1495  * implementation of CCI query result
1496  * return: NO_ERROR if successful, error code otherwise
1497  * rs(in): pointer to API_RESULTSET
1498  * rimpl(out): pointer to API_RESULTSET_META
1499  */
1500 static int
1502 {
1503  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1504  int res;
1505 
1506  assert (pres != NULL);
1507  assert (rimpl != NULL);
1508 
1509  /* lazy initialize result set meta */
1510  res = lazy_bind_qres_rmeta (pres);
1511  if (res != NO_ERROR)
1512  {
1513  return res;
1514  }
1515 
1516  assert (pres->got_rm_handle);
1517 
1518  *rimpl = (API_RESULTSET_META *) (&pres->RM);
1519 
1520  return NO_ERROR;
1521 }
1522 
1523 /*
1524  * api_qres_fetch - API_RESULTSET_IFS::fetch implementation of
1525  * CCI query result
1526  * return:NO_ERROR if successful, error code otherwise
1527  * rs(in): pointer to API_RESULTSET
1528  * offset(in): offset of cursor
1529  * pos(in): start definition of cursor
1530  */
1531 static int
1532 api_qres_fetch (API_RESULTSET * rs, int offset, CI_FETCH_POSITION pos)
1533 {
1534  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1535  int origin;
1536  int res;
1537 
1538  assert (pres != NULL);
1539 
1540  if (pos == CI_FETCH_POSITION_FIRST)
1541  {
1542  origin = 0;
1543  }
1544  else if (pos == CI_FETCH_POSITION_CURRENT)
1545  {
1546  origin = pres->offset;
1547  }
1548  else if (pos == CI_FETCH_POSITION_LAST)
1549  {
1551  }
1552  else
1553  {
1555  }
1556 
1557  res = cci_cursor (pres->req_handle, origin + offset, CCI_CURSOR_FIRST, pres->err_buf);
1558  if (res != 0)
1559  {
1560  return err_from_cci (res);
1561  }
1562 
1563  pres->offset = origin + offset;
1564  pres->fetched = false;
1565 
1566  return NO_ERROR;
1567 }
1568 
1569 /*
1570  * api_qres_tell - API_RESULTSET_IFS::tell() implementation of
1571  * CCI query result
1572  * return: NO_ERROR if successful, error code otherwise
1573  * rs(in): pointer to API_RESULTSET
1574  * offset(out): cursor offset from the start
1575  */
1576 static int
1577 api_qres_tell (API_RESULTSET * rs, int *offset)
1578 {
1579  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1580 
1581  *offset = pres->offset;
1582 
1583  return NO_ERROR;
1584 }
1585 
1586 /*
1587  * api_qres_clear_updates - API_RESULTSET::clear_updates() implementation of
1588  * CCI query result
1589  * return: NO_ERROR if successful, error code otherwise
1590  * rs(in): API_RESULTSET
1591  */
1592 static int
1594 {
1595  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1596  VALUE_INDEXER *indexer;
1597  int res, i, len;
1598 
1599  assert (pres != NULL);
1600 
1601  indexer = pres->updated_values;
1602  if (indexer == NULL)
1603  {
1604  /* no updates before this call */
1605  return NO_ERROR;
1606  }
1607 
1608  res = indexer->ifs->length (indexer, &len);
1609  if (res != NO_ERROR)
1610  {
1611  return res;
1612  }
1613 
1614  for (i = 0; i < len; i++)
1615  {
1616  VALUE_AREA *va;
1617  API_VAL *av;
1618 
1619  res = indexer->ifs->check (indexer, i, CHECK_FOR_GET | CHECK_FOR_SET);
1620  if (res != NO_ERROR)
1621  {
1622  return res;
1623  }
1624 
1625  res = indexer->ifs->get (indexer, i, &va, (API_VALUE **) (&av));
1626  if (res != NO_ERROR)
1627  {
1628  return res;
1629  }
1630 
1631  if (av != NULL)
1632  {
1633  api_val_dtor (va, (API_VALUE *) av);
1634  }
1635 
1636  res = indexer->ifs->set (indexer, i, NULL, NULL);
1637  if (res != NO_ERROR)
1638  {
1639  return res;
1640  }
1641  }
1642 
1643  return NO_ERROR;
1644 }
1645 
1646 /*
1647  * api_qres_delete_row - API_RESULTSET::delete_row(), delete the current row
1648  * return: NO_ERROR if successful, error code otherwise
1649  * res(in): pointer to API_RESULTSET
1650  */
1651 static int
1653 {
1655 }
1656 
1657 /*
1658  * api_qres_get_value - API_RESULTSET::get_value implementation of
1659  * CCI query result
1660  * return: NO_ERROR if successful, error code otherwise
1661  * rs(in): API_RESULTSET
1662  * index(in): cloumn index
1663  * type(in): CI_TYPE
1664  * addr(out): address of value container
1665  * len(in): length of value container
1666  * outlen(out): output length
1667  * is_null(out): null indicator
1668  */
1669 static int
1670 api_qres_get_value (API_RESULTSET * rs, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
1671  bool * is_null)
1672 {
1673  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1674  int res;
1675 
1676  assert (pres != NULL);
1677 
1678  if (!pres->fetched)
1679  {
1680  res = cci_fetch (pres->req_handle, pres->err_buf);
1681  if (res != 0)
1682  {
1683  return err_from_cci (res);
1684  }
1685  pres->fetched = true;
1686  }
1687 
1688  assert (pres->fetched);
1689 
1690  if (pres->updated_values != NULL)
1691  {
1692  VALUE_INDEXER *indexer = pres->updated_values;
1693  VALUE_AREA *va;
1694  API_VAL *av;
1695 
1696  res = indexer->ifs->check (indexer, index - 1, (CHECK_FOR_GET | CHECK_FOR_SET));
1697  if (res != NO_ERROR)
1698  {
1699  return res;
1700  }
1701 
1702  res = indexer->ifs->get (indexer, index - 1, &va, (API_VALUE **) (&av));
1703  if (res != NO_ERROR)
1704  {
1705  return res;
1706  }
1707 
1708  if (av != NULL)
1709  {
1710  res = get_value_from_api_val (av, type, addr, len, outlen, is_null);
1711  }
1712  else
1713  {
1714  res = get_value_from_req_handle (pres->conn, pres->req_handle, index, type, addr, len, outlen, is_null);
1715  }
1716  }
1717  else
1718  {
1719  res = get_value_from_req_handle (pres->conn, pres->req_handle, index, type, addr, len, outlen, is_null);
1720  }
1721 
1722  return res;
1723 }
1724 
1725 /*
1726  * api_qres_get_value_by_name - API_RESULSET::get_value_by_name implementation
1727  * of CCI query result
1728  * return: NO_ERROR if successful, error code otherwise
1729  * rs(in): API_RESULTSET
1730  * name(in): cloumn name
1731  * type(in): CI_TYPE
1732  * addr(out): address of value container
1733  * len(in): length of value container
1734  * outlen(out): output length
1735  * is_null(out): null indicator
1736  */
1737 static int
1738 api_qres_get_value_by_name (API_RESULTSET * rs, const char *name, CI_TYPE type, void *addr, size_t len, size_t * outlen,
1739  bool * isnull)
1740 {
1741  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1742  int i;
1743 
1744  assert (pres != NULL);
1745 
1746  for (i = 0; i < pres->num_col; i++)
1747  {
1748  if (strcmp (name, pres->col_info[i].col_name) == 0)
1749  {
1750  return api_qres_get_value (rs, i + 1, type, addr, len, outlen, isnull);
1751  }
1752  }
1753 
1755 }
1756 
1757 /*
1758  * api_qres_update_value - API_RESULTSET::update_value implementation of
1759  * CCI query result
1760  * return: NO_ERROR if successful, error code otherwise
1761  * rs(in): API_RESULTSET
1762  * index(in): column index
1763  * type(in): CI_TYPE
1764  * addr(in): address of the value container
1765  * len(in): length of the value container
1766  */
1767 static int
1768 api_qres_update_value (API_RESULTSET * rs, int index, CI_TYPE type, void *addr, size_t len)
1769 {
1770  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1771  int res;
1772  VALUE_INDEXER *indexer;
1773  VALUE_AREA *va;
1774  API_VAL *av;
1775  bool val_created = false;
1776 
1777  if (!pres->updatable)
1778  {
1780  }
1781 
1782  if (pres->updated_values == NULL)
1783  {
1784  res = array_indexer_create (pres->num_col, &pres->updated_values);
1785  if (res != NO_ERROR)
1786  {
1787  return res;
1788  }
1789  }
1790 
1791  assert (pres->updated_values != NULL);
1792 
1793  indexer = pres->updated_values;
1794  res = indexer->ifs->check (indexer, index - 1, (CHECK_FOR_GET | CHECK_FOR_SET));
1795 
1796  if (res != NO_ERROR)
1797  {
1798  return res;
1799  }
1800 
1801  res = indexer->ifs->get (indexer, index - 1, &va, (API_VALUE **) (&av));
1802  if (res != NO_ERROR)
1803  {
1804  return res;
1805  }
1806 
1807  if (av == NULL)
1808  {
1809  av = API_CALLOC (1, sizeof (*av));
1810  if (av == NULL)
1811  {
1813  }
1814 
1815  val_created = true;
1816  }
1817 
1818  res = set_value_to_api_val (av, type, addr, len);
1819  if (res != NO_ERROR)
1820  {
1821  if (val_created)
1822  {
1823  api_val_dtor (NULL, (API_VALUE *) av);
1824  }
1825  return res;
1826  }
1827 
1828  if (val_created)
1829  {
1830  (void) indexer->ifs->set (indexer, index - 1, NULL, (API_VALUE *) av);
1831  }
1832 
1833  return NO_ERROR;
1834 }
1835 
1836 /*
1837  * qres_apply_updatef - api_qres_apply_update worker function.
1838  * return: NO_ERROR if successful, error code otherwise
1839  * arg(in): pointer to RESULTSET_IMPL
1840  * index(in): column index
1841  * va(in): pointer to VALUE_AREA
1842  * v(in): pointer to API_VALUE
1843  */
1844 static int
1845 qres_apply_updatef (void *arg, int index, VALUE_AREA * va, API_VALUE * v)
1846 {
1847  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) arg;
1848  API_VAL *av = (API_VAL *) v;
1849  int res;
1850 
1851  if (av == NULL)
1852  {
1853  return NO_ERROR;
1854  }
1855 
1856  res = api_val_cursor_update (pres->conn, pres->req_handle, pres->offset, index, av, pres->err_buf);
1857  return res;
1858 }
1859 
1860 /*
1861  * api_qres_apply_update - API_RESULTSET::apply_updates() implmentation of
1862  * CCI query result
1863  * return: NO_ERROR if successful, error code otherwise
1864  * rs():
1865  */
1866 static int
1868 {
1869  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
1870  int res;
1871 
1872  if (pres->updated_values == NULL)
1873  {
1874  return NO_ERROR;
1875  }
1876 
1877  res = pres->updated_values->ifs->map (pres->updated_values, qres_apply_updatef, (void *) pres);
1878  return res;
1879 }
1880 
1881 /*
1882  * api_qres_destroy - API_RESULTSET::destroy() implementation of
1883  * CCI query result set
1884  * return: void
1885  * rs():
1886  */
1887 static void
1889 {
1890  return;
1891 }
1892 
1896  api_qres_tell,
1904 };
1905 
1906 /*
1907  * create_resultset_impl - create RESULTSET_IMPL
1908  * return: NO_ERROR if successful, error code otherwise
1909  * conn(in): CI_CONNECTION
1910  * bh(in): BH_INTERFACE
1911  * req_handle(in): CCI request handle
1912  * err_buf(in): CCI error buffer
1913  * parent(in): parent (in binding relationship) COMMON_API_STRUCTURE
1914  * updatable(in): indicator of updatable resultset
1915  * arg(in): on_close function argument
1916  * on_close(in): notification fucntion to parent COMMON_API_STRUCTURE called
1917  * when this RESULTSET_IMPL is to be destroyed
1918  * resifs(in): API_RESULTSET_IFS implementation
1919  * rmifs(in): API_RESULTSET_META_IFS implementation
1920  * rpres(in): return pointer
1921  */
1922 static int
1923 create_resultset_impl (CI_CONNECTION conn, BH_INTERFACE * bh, int req_handle, T_CCI_ERROR * err_buf,
1924  COMMON_API_STRUCTURE * parent, bool updatable, void *arg, void (*on_close) (RESULTSET_IMPL *,
1925  void *),
1926  API_RESULTSET_IFS * resifs, API_RESULTSET_META_IFS * rmifs, RESULTSET_IMPL ** rpres)
1927 {
1928  T_CCI_COL_INFO *col_info;
1929  T_CCI_CUBRID_STMT cmd_type;
1930  int res, num_col;
1932  RESULTSET_IMPL *pres;
1933 
1934  col_info = cci_get_result_info (req_handle, &cmd_type, &num_col);
1935  if (col_info == NULL)
1936  return ER_INTERFACE_GENERIC;
1937 
1938  pres = (RESULTSET_IMPL *) API_CALLOC (1, sizeof (*pres));
1939  if (pres == NULL)
1940  {
1942  }
1943 
1944  /* initialize fields */
1945  pres->bind.dtor = resultset_impl_dtor;
1946  pres->handle_type = HANDLE_TYPE_RESULTSET;
1947  pres->ifs = resifs;
1948  pres->RM.bind.dtor = NULL;
1949  pres->RM.handle_type = HANDLE_TYPE_RMETA;
1950  pres->RM.ifs = rmifs;
1951  pres->RM.bp = pres;
1952  pres->conn = conn;
1953  pres->bh = bh;
1954  pres->req_handle = req_handle;
1955  pres->err_buf = err_buf;
1956  pres->parent = parent;
1957  pres->updatable = updatable;
1958  pres->arg = arg;
1959  pres->on_close = on_close;
1960  pres->offset = 0;
1961  pres->fetched = false;
1962  pres->got_rm_handle = false;
1963  pres->rm_handle = -1LL;
1964  pres->num_col = num_col;
1965  pres->cmd_type = cmd_type;
1966  pres->col_info = col_info;
1967 
1968  res = bind_api_structure (bh, (COMMON_API_STRUCTURE *) pres, parent, &handle);
1969  if (res != NO_ERROR)
1970  {
1971  API_FREE (pres);
1972  return res;
1973  }
1974 
1975  *rpres = pres;
1976 
1977  return NO_ERROR;
1978 }
1979 
1980 /*
1981  * resultset_impl_dtor - RESULTSET_IMPL bind handle destructor
1982  * return: void
1983  * bind(in): pointer to RESULTSET_IMPL
1984  */
1985 static void
1987 {
1988  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) bind;
1989 
1990  if (pres == NULL)
1991  return;
1992 
1993  if (pres->on_close != NULL)
1994  {
1995  pres->on_close (pres, pres->arg);
1996  }
1997 
1998  if (pres->updated_values)
1999  {
2001  }
2002 
2003  API_FREE (pres);
2004 }
2005 
2006 /*
2007  * api_qrmeta_get_count - API_RESULTSET_META::get_count implementation of
2008  * CCI query result
2009  * return: NO_ERROR if successful, error code otherwise
2010  * rm(in): API_RESULTSET_META
2011  * count(out): number of rows
2012  */
2013 static int
2015 {
2016  RESULTSET_META_IMPL *prmeta = (RESULTSET_META_IMPL *) rm;
2017 
2018  assert (prmeta != NULL);
2019  assert (count != NULL);
2020 
2021  *count = prmeta->bp->num_col;
2022 
2023  return NO_ERROR;
2024 }
2025 
2026 /*
2027  * api_qrmeta_get_info -
2028  * return: NO_ERROR if successful, error code otherwise
2029  * rm():
2030  * index():
2031  * type():
2032  * arg():
2033  * size():
2034  */
2035 static int
2036 api_qrmeta_get_info (API_RESULTSET_META * rm, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size)
2037 {
2038  RESULTSET_META_IMPL *prmeta = (RESULTSET_META_IMPL *) rm;
2039  size_t len = 0;
2040  char *p;
2041 
2042  assert (prmeta != NULL);
2043 
2044  if (index <= 0 || index > prmeta->bp->num_col)
2045  {
2047  }
2048 
2049  switch (type)
2050  {
2051  case CI_RMETA_INFO_COL_LABEL:
2052  {
2053  p = prmeta->bp->col_info[index - 1].real_attr;
2054  p = p ? p : (char *) "";
2055  len = strlen (p);
2056  if (size < len + 1)
2057  {
2059  }
2060 
2061  strcpy ((char *) arg, p);
2062  return NO_ERROR;
2063  }
2064  case CI_RMETA_INFO_COL_NAME:
2065  {
2066  p = prmeta->bp->col_info[index - 1].col_name;
2067  p = p ? p : (char *) "";
2068  len = strlen (p);
2069  if (size < len + 1)
2070  {
2072  }
2073 
2074  strcpy ((char *) arg, p);
2075  return NO_ERROR;
2076  }
2077  case CI_RMETA_INFO_COL_TYPE:
2078  {
2079  T_CCI_U_TYPE utype = prmeta->bp->col_info[index - 1].type;
2080 
2081  if (len < sizeof (CI_TYPE))
2082  {
2084  }
2085 
2086  *(CI_TYPE *) arg = cci_u_type_to_type (utype);
2087  return NO_ERROR;
2088  }
2089  case CI_RMETA_INFO_PRECISION:
2090  {
2091  if (len < sizeof (int))
2092  {
2094  }
2095 
2096  *(int *) arg = prmeta->bp->col_info[index - 1].precision;
2097  return NO_ERROR;
2098  }
2099  case CI_RMETA_INFO_SCALE:
2100  {
2101  if (len < sizeof (int))
2102  {
2104  }
2105 
2106  *(int *) arg = prmeta->bp->col_info[index - 1].scale;
2107  return NO_ERROR;
2108  }
2109  case CI_RMETA_INFO_TABLE_NAME:
2110  {
2111  p = prmeta->bp->col_info[index - 1].class_name;
2112  p = p ? p : (char *) "";
2113  if (size < len + 1)
2114  {
2116  }
2117 
2118  strcpy ((char *) arg, p);
2119  return NO_ERROR;
2120  }
2121  case CI_RMETA_INFO_IS_AUTO_INCREMENT:
2122  {
2124  }
2125  case CI_RMETA_INFO_IS_NULLABLE:
2126  {
2127  if (len < sizeof (int))
2128  {
2130  }
2131 
2132  *(int *) arg = prmeta->bp->col_info[index - 1].is_non_null ? 0 : 1;
2133  return NO_ERROR;
2134  }
2135  case CI_RMETA_INFO_IS_WRITABLE:
2136  {
2137  if (len < sizeof (int))
2138  {
2140  }
2141 
2142  *(int *) arg = prmeta->bp->updatable ? 1 : 0;
2143  return NO_ERROR;
2144  }
2145  default:
2147  }
2148 
2149  return NO_ERROR;
2150 }
2151 
2155 };
2156 
2157 /*
2158  * lazy_bind_pstmt_pmeta -
2159  * return: NO_ERROR if successful, error code otherwise
2160  * pstmt():
2161  */
2162 static int
2164 {
2165  int res;
2167 
2168  if (pstmt->got_pm_handle)
2169  return NO_ERROR;
2170 
2171  res =
2172  bind_api_structure (pstmt->pconn->bh, (COMMON_API_STRUCTURE *) (&pstmt->PM), (COMMON_API_STRUCTURE *) pstmt,
2173  &handle);
2174  if (res != NO_ERROR)
2175  return res;
2176 
2177  pstmt->got_pm_handle = true;
2178  pstmt->pm_handle = handle;
2179 
2180  return NO_ERROR;
2181 }
2182 
2183 /*
2184  * statement_impl_dtor -
2185  * return: NO_ERROR if successful, error code otherwise
2186  * bind():
2187  */
2188 static void
2190 {
2191  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) bind;
2192 
2193  if (pstmt == NULL)
2194  return;
2195 
2196  if (pstmt->params != NULL)
2197  {
2198  pstmt->params->ifs->destroy (pstmt->params, api_val_dtor);
2199  }
2200 
2201  if (pstmt->req_handle >= 0)
2202  {
2203  (void) cci_close_req_handle (pstmt->req_handle);
2204  }
2205 
2206  API_FREE (pstmt);
2207 }
2208 
2209 /*
2210  * init_statement_impl -
2211  * return: void
2212  * pstmt():
2213  * pconn():
2214  */
2215 static void
2217 {
2218  memset (pstmt, 0, sizeof (*pstmt));
2219 
2220  pstmt->bind.dtor = statement_impl_dtor;
2221  pstmt->handle_type = HANDLE_TYPE_STATEMENT;
2222  pstmt->pconn = pconn;
2223  pstmt->req_handle = -1;
2224  pstmt->PM.bind.dtor = NULL;
2225  pstmt->PM.handle_type = HANDLE_TYPE_PMETA;
2226  pstmt->PM.bptr = pstmt;
2227  pstmt->BR.bind.dtor = NULL;
2228  pstmt->BR.bptr = pstmt;
2229  pstmt->BR.handle_type = HANDLE_TYPE_BATCH_RESULT;
2231  dlisth_init (&pstmt->batch);
2232  pstmt->num_batch = 0;
2233 }
2234 
2235 /*
2236  * statement_execute -
2237  * return: NO_ERROR if successful, error code otherwise
2238  * pstmt():
2239  * err_buf():
2240  */
2241 static int
2242 statement_execute (STATEMENT_IMPL * pstmt, T_CCI_ERROR * err_buf)
2243 {
2244  char ex_flag;
2245  int res, nres, num_query;
2246  T_CCI_QUERY_RESULT *query_result;
2247 
2248  ex_flag = CCI_EXEC_QUERY_ALL;
2249 
2250  res = cci_execute (pstmt->req_handle, ex_flag, 0, err_buf);
2251  if (res < 0)
2252  {
2253  return err_from_cci (err_buf->err_code);
2254  }
2255  nres = res;
2256 
2257  res = cci_execute_result (pstmt->req_handle, &query_result, err_buf);
2258  if (res < 0)
2259  {
2260  return err_from_cci (err_buf->err_code);
2261  }
2262  num_query = res;
2263 
2264  if (pstmt->query_result)
2265  {
2266  cci_query_result_free (pstmt->query_result, pstmt->num_query);
2267  pstmt->query_result = NULL;
2268  pstmt->num_query = 0;
2269  }
2270 
2271  pstmt->has_resultset = false;
2272  pstmt->res_handle = -1LL;
2273  pstmt->affected_rows = -1;
2274  pstmt->num_query = num_query;
2275  pstmt->query_result = query_result;
2276  pstmt->curr_query_result_index = 0;
2277 
2278  return NO_ERROR;
2279 }
2280 
2281 /*
2282  * get result of pstmt->curr_query_result_idx
2283  */
2284 
2285 /*
2286  * statement_get_reshandle_or_affectedrows -
2287  * return: NO_ERROR if successful, error code otherwise
2288  * bh():
2289  * pstmt():
2290  */
2291 static int
2293 {
2294  int idx, res;
2295 
2296  idx = pstmt->curr_query_result_index + 1;
2297  if (idx < 1 || idx > pstmt->num_query)
2298  {
2299  assert (0);
2300  return ER_INTERFACE_GENERIC;
2301  }
2302 
2303  /*
2304  * call cci_cursor () for resutlset test. (hack)
2305  * It will be good if CCI API provides function something like
2306  * CCI_QUERY_RESULT_HAS_RESULTSET ()
2307  */
2308  res = cci_cursor (pstmt->req_handle, 1, CCI_CURSOR_FIRST, &pstmt->pconn->err_buf);
2309  if (res == 0)
2310  {
2311  RESULTSET_IMPL *pres;
2312 
2313  res =
2314  create_resultset_impl (pstmt->pconn->conn, pstmt->pconn->bh, pstmt->req_handle, &pstmt->pconn->err_buf,
2315  (COMMON_API_STRUCTURE *) pstmt, pstmt->opt_updatable_result, pstmt,
2316  on_close_statement_res, &QRES_IFS_, &QRMETA_IFS_, &pres);
2317  if (res != NO_ERROR)
2318  {
2319  return res;
2320  }
2321 
2322  pstmt->has_resultset = true;
2323  (void) pstmt->pconn->bh->bind_to_handle (pstmt->pconn->bh, (BH_BIND *) pres, &pstmt->res_handle);
2324  pstmt->affected_rows = CCI_QUERY_RESULT_RESULT (pstmt->query_result, idx);
2325 
2326  return NO_ERROR;
2327  }
2328  else if (res == CCI_ER_NO_MORE_DATA)
2329  {
2330  pstmt->has_resultset = false;
2331  pstmt->res_handle = -1LL;
2332  pstmt->affected_rows = CCI_QUERY_RESULT_RESULT (pstmt->query_result, idx);
2333  return NO_ERROR;
2334  }
2335  else
2336  {
2337  return err_from_cci (res);
2338  }
2339 }
2340 
2341 /*
2342  * complete_statement -
2343  * return: NO_ERROR if successful, error code otherwise
2344  * pstmt():
2345  */
2346 static int
2348 {
2349  int res;
2350 
2352 
2353  if (pstmt->status & CI_STMT_STATUS_BATCH_ADDED)
2354  {
2355  res = stmt_complete_batch (pstmt);
2356  if (res != NO_ERROR)
2357  {
2358  return res;
2359  }
2360  }
2361  else if (pstmt->query_result != NULL)
2362  {
2363  cci_query_result_free (pstmt->query_result, pstmt->num_query);
2364  pstmt->query_result = NULL;
2365  pstmt->num_query = 0;
2366  }
2367 
2368  pstmt->curr_query_result_index = 0;
2369 
2370  if (pstmt->has_resultset)
2371  {
2372  res = pstmt->pconn->bh->destroy_handle (pstmt->pconn->bh, pstmt->res_handle);
2373  if (res != NO_ERROR)
2374  {
2375  return res;
2376  }
2377  }
2378 
2379  if (pstmt->status & CI_STMT_STATUS_PREPARED)
2380  {
2381  /* reset parameter table */
2382  if (pstmt->params != NULL)
2383  {
2384  int i;
2385 
2386  for (i = 0; pstmt->num_col; i++)
2387  {
2388  VALUE_AREA *va;
2389  API_VAL *av;
2390 
2391  res = pstmt->params->ifs->check (pstmt->params, i, CHECK_FOR_GET | CHECK_FOR_SET);
2392  if (res != NO_ERROR)
2393  {
2394  return res;
2395  }
2396 
2397  res = pstmt->params->ifs->get (pstmt->params, i, &va, (API_VALUE **) (&av));
2398  if (res != NO_ERROR)
2399  {
2400  return res;
2401  }
2402 
2403  res = pstmt->params->ifs->set (pstmt->params, i, NULL, NULL);
2404  if (res != NO_ERROR)
2405  {
2406  return res;
2407  }
2408 
2409  if (av != NULL)
2410  {
2411  api_val_dtor (NULL, (API_VALUE *) av);
2412  }
2413  }
2414  }
2415  }
2416 
2417  return NO_ERROR;
2418 }
2419 
2420 /*
2421  * on_close_statement_res -
2422  * return: NO_ERROR if successful, error code otherwise
2423  * impl():
2424  * arg():
2425  */
2426 static void
2428 {
2429  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) arg;
2430 
2431  pstmt->has_resultset = false;
2432  pstmt->res_handle = -1LL;
2433  pstmt->affected_rows = -1;
2434 }
2435 
2437 {
2438  int nadded;
2441 };
2442 
2443 /*
2444  * add_batch_params_restore_mapf -
2445  * return: NO_ERROR if successful, error code otherwise
2446  * arg():
2447  * index():
2448  * va():
2449  * val():
2450  */
2451 static int
2453 {
2454  struct add_batch_params_arg *parg = (struct add_batch_params_arg *) arg;
2455 
2456  if (index < parg->nadded)
2457  {
2458  (void) parg->indexer->ifs->set (parg->indexer, index, NULL, (API_VALUE *) parg->bai->ary[index]);
2459  }
2460 
2461  return NO_ERROR;
2462 }
2463 
2464 
2465 /*
2466  * add_batch_params_mapf -
2467  * return: NO_ERROR if successful, error code otherwise
2468  * arg():
2469  * index():
2470  * va():
2471  * val():
2472  */
2473 static int
2474 add_batch_params_mapf (void *arg, int index, VALUE_AREA * va, API_VALUE * val)
2475 {
2476  int res;
2477  struct add_batch_params_arg *parg = (struct add_batch_params_arg *) arg;
2478 
2479  API_VAL *pval = (API_VAL *) val;
2480 
2481  if (val == NULL)
2482  {
2484  }
2485 
2486  parg->bai->ary[index] = pval;
2487  res = parg->indexer->ifs->set (parg->indexer, index, NULL, NULL);
2488  if (res != NO_ERROR)
2489  {
2490  return res;
2491  }
2492  parg->nadded++;
2493 
2494  return res;
2495 }
2496 
2497 /*
2498  * stmt_execute_batch_sql -
2499  * return: NO_ERROR if successful, error code otherwise
2500  * pstmt():
2501  */
2502 static int
2504 {
2505  int res;
2506  T_CCI_QUERY_RESULT *query_result;
2507  char **sql_stmt;
2508  int i;
2509  dlisth *h;
2510 
2511  assert (pstmt->num_batch > 0);
2512  assert (pstmt->num_query == 0);
2513  assert (pstmt->query_result == NULL);
2514 
2515  sql_stmt = (char **) API_MALLOC (pstmt->num_batch * sizeof (char *));
2516  if (sql_stmt == NULL)
2517  {
2519  }
2520 
2521  for (h = pstmt->batch.next, i = 0; (h != &pstmt->batch) && i < pstmt->num_batch; h = h->next, i++)
2522  {
2523  BATCH_SQL_ITEM *bi = (BATCH_SQL_ITEM *) h;
2524 
2525  sql_stmt[i] = bi->sql;
2526  }
2527 
2528  assert (i = pstmt->num_batch);
2529 
2530  res =
2531  cci_execute_batch (pstmt->pconn->conn_handle, pstmt->num_batch, sql_stmt, &query_result, &pstmt->pconn->err_buf);
2532 
2533  API_FREE (sql_stmt);
2534  if (res != 0)
2535  {
2536  return err_from_cci (res);
2537  }
2538 
2539  pstmt->num_query = pstmt->num_batch;
2540  pstmt->query_result = query_result;
2541 
2542  return NO_ERROR;
2543 }
2544 
2545 /*
2546  * stmt_execute_batch_array -
2547  * return: NO_ERROR if successful, error code otherwise
2548  * pstmt():
2549  */
2550 static int
2552 {
2553  int res;
2554  T_CCI_QUERY_RESULT *query_result;
2555  int index;
2556  dlisth *h;
2557  int num_query;
2558 
2559  index = 0;
2560  for (h = pstmt->batch.next; h != &pstmt->batch; h = h->next)
2561  {
2562  BATCH_ARY_ITEM *bi = (BATCH_ARY_ITEM *) h;
2563  int i;
2564 
2565  for (i = 0; i < pstmt->num_col; i++)
2566  {
2567  res = api_val_bind_param (pstmt->pconn->conn, pstmt->req_handle, bi->ary[i], index + i + 1);
2568  if (res != NO_ERROR)
2569  {
2570  return res;
2571  }
2572  }
2573  }
2574 
2575  res = cci_execute_array (pstmt->req_handle, &query_result, &pstmt->pconn->err_buf);
2576  if (res < 0)
2577  {
2578  return err_from_cci (res);
2579  }
2580 
2581  num_query = res;
2582  pstmt->num_query = num_query;
2583  pstmt->query_result = query_result;
2584 
2585  return NO_ERROR;
2586 }
2587 
2588 
2589 /*
2590  * stmt_complete_batch -
2591  * return: NO_ERROR if successful, error code otherwise
2592  * pstmt():
2593  */
2594 static int
2596 {
2597  int res = CCI_ER_NO_ERROR;
2598  int num_batch, i;
2599  dlisth h;
2600 
2601  if (pstmt->query_result == NULL)
2602  {
2603  assert (dlisth_is_empty (&pstmt->batch));
2604  assert (pstmt->num_query == 0);
2605 
2606  return NO_ERROR;
2607  }
2608 
2609  if (pstmt->query_result)
2610  {
2611  res = cci_query_result_free (pstmt->query_result, pstmt->num_query);
2612  }
2613 
2614  if (res != CCI_ER_NO_ERROR)
2615  {
2616  return err_from_cci (res);
2617  }
2618 
2619  pstmt->query_result = NULL;
2620  pstmt->num_query = 0;
2621 
2622  /* clear batch data also */
2623  num_batch = pstmt->num_batch;
2624  dlisth_init (&h);
2625  dlisth_insert_after (&h, &pstmt->batch);
2626  dlisth_delete (&pstmt->batch);
2627  pstmt->num_batch = 0;
2628 
2629  while (dlisth_is_empty (&h))
2630  {
2631  dlisth *tmp = h.next;
2632 
2633  dlisth_delete (tmp);
2634  if (pstmt->status & CI_STMT_STATUS_PREPARED)
2635  {
2636  BATCH_ARY_ITEM *bi = (BATCH_ARY_ITEM *) tmp;
2637 
2638  for (i = 0; i < pstmt->num_col; i++)
2639  {
2640  api_val_dtor (NULL, (API_VALUE *) bi->ary[i]);
2641  }
2642  API_FREE (bi);
2643  }
2644  else
2645  {
2646  API_FREE (tmp);
2647  }
2648  }
2649 
2650  return NO_ERROR;
2651 }
2652 
2653 /*
2654  * api_ormeta_get_count -
2655  * return: NO_ERROR if successful, error code otherwise
2656  * rm():
2657  * count():
2658  */
2659 static int
2661 {
2662  RESULTSET_META_IMPL *prmeta = (RESULTSET_META_IMPL *) rm;
2663  CCI_OBJECT *obj;
2664 
2665  assert (prmeta != NULL);
2666 
2667  obj = (CCI_OBJECT *) prmeta->bp->arg;
2668  if (obj->deleted)
2669  {
2671  }
2672 
2673  return api_qrmeta_get_count (rm, count);
2674 }
2675 
2676 /*
2677  * api_ormeta_get_info -
2678  * return: NO_ERROR if successful, error code otherwise
2679  * rm():
2680  * index():
2681  * type():
2682  * arg():
2683  * size():
2684  */
2685 static int
2686 api_ormeta_get_info (API_RESULTSET_META * rm, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size)
2687 {
2688  RESULTSET_META_IMPL *prmeta = (RESULTSET_META_IMPL *) rm;
2689  CCI_OBJECT *obj;
2690 
2691  assert (prmeta != NULL);
2692 
2693  obj = (CCI_OBJECT *) prmeta->bp->arg;
2694  if (obj->deleted)
2695  {
2697  }
2698 
2699  return api_qrmeta_get_info (rm, index, type, arg, size);
2700 }
2701 
2705 };
2706 
2707 /*
2708  * api_ores_get_resultset_metadata -
2709  * return: NO_ERROR if successful, error code otherwise
2710  * res():
2711  * rimpl():
2712  */
2713 static int
2715 {
2716  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) res;
2717  CCI_OBJECT *obj;
2718 
2719  assert (pres != NULL);
2720 
2721  obj = (CCI_OBJECT *) pres->arg;
2722  if (obj->deleted)
2723  {
2725  }
2726 
2727  return api_qres_get_resultset_metadata (res, rimpl);
2728 }
2729 
2730 /*
2731  * api_ores_fetch -
2732  * return: NO_ERROR if successful, error code otherwise
2733  * res():
2734  * offset():
2735  * pos():
2736  */
2737 static int
2738 api_ores_fetch (API_RESULTSET * res, int offset, CI_FETCH_POSITION pos)
2739 {
2740  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) res;
2741  CCI_OBJECT *obj;
2742 
2743  assert (pres != NULL);
2744 
2745  obj = (CCI_OBJECT *) pres->arg;
2746  if (obj->deleted)
2747  {
2749  }
2750 
2751  return api_qres_fetch (res, offset, pos);
2752 }
2753 
2754 /*
2755  * api_ores_tell -
2756  * return: NO_ERROR if successful, error code otherwise
2757  * res():
2758  * offset():
2759  */
2760 static int
2761 api_ores_tell (API_RESULTSET * res, int *offset)
2762 {
2763  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) res;
2764  CCI_OBJECT *obj;
2765 
2766  assert (pres != NULL);
2767 
2768  obj = (CCI_OBJECT *) pres->arg;
2769  if (obj->deleted)
2770  {
2772  }
2773 
2774  return api_qres_tell (res, offset);
2775 }
2776 
2777 /*
2778  * api_ores_clear_updates -
2779  * return: NO_ERROR if successful, error code otherwise
2780  * res():
2781  */
2782 static int
2784 {
2785  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) res;
2786  CCI_OBJECT *obj;
2787 
2788  assert (pres != NULL);
2789 
2790  obj = (CCI_OBJECT *) pres->arg;
2791  if (obj->deleted)
2792  {
2794  }
2795 
2796  return api_qres_clear_updates (res);
2797 }
2798 
2799 /*
2800  * api_ores_delete_row -
2801  * return: NO_ERROR if successful, error code otherwise
2802  * rs():
2803  */
2804 static int
2806 {
2807  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) rs;
2808  CCI_OBJECT *obj;
2809  int res;
2810  char oid_buf[32];
2811 
2812  assert (pres != NULL);
2813  if (pres == NULL)
2814  {
2815  return ER_INTERFACE_GENERIC;
2816  }
2817 
2818  obj = (CCI_OBJECT *) pres->arg;
2819  xoid2oidstr (&obj->xoid, oid_buf);
2820 
2821  res = cci_oid (obj->pool->pconn->conn_handle, CCI_OID_DROP, oid_buf, &obj->pool->pconn->err_buf);
2822  if (res != 0)
2823  {
2824  return err_from_cci (res);
2825  }
2826 
2827  obj->deleted = true;
2828 
2829  return NO_ERROR;
2830 }
2831 
2832 /*
2833  * api_ores_get_value -
2834  * return: NO_ERROR if successful, error code otherwise
2835  * res():
2836  * index():
2837  * type():
2838  * addr():
2839  * len():
2840  * outlen():
2841  * is_null():
2842  */
2843 static int
2844 api_ores_get_value (API_RESULTSET * res, int index, CI_TYPE type, void *addr, size_t len, size_t * outlen,
2845  bool * is_null)
2846 {
2847  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) res;
2848  CCI_OBJECT *obj;
2849 
2850  assert (pres != NULL);
2851 
2852  obj = (CCI_OBJECT *) pres->arg;
2853  if (obj->deleted)
2854  {
2856  }
2857 
2858  return api_qres_get_value (res, index, type, addr, len, outlen, is_null);
2859 }
2860 
2861 /*
2862  * api_ores_get_value_by_name -
2863  * return: NO_ERROR if successful, error code otherwise
2864  * res():
2865  * name():
2866  * type():
2867  * addr():
2868  * len():
2869  * outlen():
2870  * isnull():
2871  */
2872 static int
2873 api_ores_get_value_by_name (API_RESULTSET * res, const char *name, CI_TYPE type, void *addr, size_t len,
2874  size_t * outlen, bool * isnull)
2875 {
2876  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) res;
2877  CCI_OBJECT *obj;
2878 
2879  assert (pres != NULL);
2880 
2881  obj = (CCI_OBJECT *) pres->arg;
2882  if (obj->deleted)
2883  {
2885  }
2886 
2887  return api_qres_get_value_by_name (res, name, type, addr, len, outlen, isnull);
2888 }
2889 
2890 /*
2891  * api_ores_update_value -
2892  * return: NO_ERROR if successful, error code otherwise
2893  * res():
2894  * index():
2895  * type():
2896  * addr():
2897  * len():
2898  */
2899 static int
2900 api_ores_update_value (API_RESULTSET * res, int index, CI_TYPE type, void *addr, size_t len)
2901 {
2902  RESULTSET_IMPL *pres = (RESULTSET_IMPL *) res;
2903  CCI_OBJECT *obj;
2904 
2905  if (!pres->updatable)
2906  {
2908  }
2909 
2910  obj = (CCI_OBJECT *) pres->arg;
2911  if (obj->deleted)
2912  {
2914  }
2915 
2916  return api_qres_update_value (res, index, type, addr, len);
2917 }
2918 
2920 {
2921  char *name;
2922  char *value;
2923  T_CCI_A_TYPE atype;
2924 };
2925 
2927 {
2929  int nattrs;
2931  char **names;
2933 };
2934 
2935 /*
2936  * ores_apply_updatef -
2937  * return: NO_ERROR if successful, error code otherwise
2938  * arg():
2939  * index():
2940  * va():
2941  * v():
2942  */
2943 static int
2944 ores_apply_updatef (void *arg, int index, VALUE_AREA * va, API_VALUE * v)
2945 {
2946  struct ores_apply_updatef_s *ARG;
2947  API_VAL *pv;
2948  int res;
2949 
2950  if (v == NULL)
2951  {
2952  return NO_ERROR;
2953  }
2954 
2955  ARG = (struct ores_apply_updatef_s *) arg;
2956  pv = (API_VAL *) v;
2957  ARG->names[index] = CCI_GET_RESULT_INFO_ATTR_NAME (ARG->pres->col_info, index + 1);
2958 
2959  res = api_val_cci_bind_bind (pv->type, pv->ptr, pv->len, &ARG->binds[index]);
2960  if (res != NO_ERROR)
2961  {
2962  return res;
2963  }
2964 
2965  ARG->nupdates++;
2966 
2967  return NO_ERROR;
2968 }
2969 
2970 /*
2971  * api_ores_apply_update -
2972  * return: NO_ERROR if successful, error code otherwise
2973  * rs():
2974  */
2975 static int
2977 {
2979  CCI_OBJECT *obj;
2980  struct ores_apply_updatef_s ARG;
2981  int i, res, nattrs;
2982  char oid_buf[32];
2983  char **names;
2984  void **values;
2985  int *atypes;
2987 
2988  obj = (CCI_OBJECT *) pres->arg;
2989  if (obj->deleted)
2990  {
2992  }
2993 
2994  if (pres->updated_values == NULL)
2995  {
2996  return NO_ERROR;
2997  }
2998 
2999  nattrs = pres->num_col;
3000  names = API_CALLOC (1, sizeof (char *) * (nattrs + 1));
3001  binds = API_MALLOC (sizeof (API_VAL_CCI_BIND) * nattrs);
3002  values = API_MALLOC (sizeof (void *) * nattrs);
3003  atypes = API_MALLOC (sizeof (int) * nattrs);
3004  if (names == NULL || binds == NULL || values == NULL || atypes == NULL)
3005  {
3007  goto res_return;
3008  }
3009 
3010  for (i = 0; i < nattrs; i++)
3011  {
3013  }
3014 
3015  ARG.pres = pres;
3016  ARG.nattrs = nattrs;
3017  ARG.nupdates = 0;
3018  ARG.names = names;
3019  ARG.binds = binds;
3020 
3021  res = pres->updated_values->ifs->map (pres->updated_values, ores_apply_updatef, &ARG);
3022  if (res != NO_ERROR)
3023  {
3024  goto res_return;
3025  }
3026 
3027  xoid2oidstr (&obj->xoid, oid_buf);
3028 
3029  names[ARG.nupdates] = NULL;
3030 
3031  for (i = 0; i < ARG.nupdates; i++)
3032  {
3033  values[i] = binds[i].value;
3034  atypes[i] = binds[i].atype;
3035  }
3036 
3037  res = cci_oid_put2 (obj->pool->pconn->conn_handle, oid_buf, names, values, atypes, &obj->pool->pconn->err_buf);
3038 
3039 res_return:
3040  if (names)
3041  {
3042  API_FREE (names);
3043  }
3044 
3045  if (values)
3046  {
3047  API_FREE (values);
3048  }
3049 
3050  if (atypes)
3051  {
3052  API_FREE (atypes);
3053  }
3054 
3055  if (binds)
3056  {
3057  int i;
3058 
3059  for (i = 0; i < nattrs; i++)
3060  api_val_cci_bind_clear (&binds[i]);
3061  API_FREE (binds);
3062  }
3063 
3064  return res;
3065 }
3066 
3067 /*
3068  * api_ores_destroy -
3069  * return: NO_ERROR if successful, error code otherwise
3070  * res():
3071  */
3072 static void
3074 {
3075  assert (0);
3076  /* should not be called */
3077 }
3078 
3082  api_ores_tell,
3084  api_ores_delete_row, /* this calls cci_oid() */
3087  api_ores_update_value, /* this calls cci_oid_put() */
3090 };
3091 
3092 /*
3093  * opool_get_object_resultset -
3094  * return: NO_ERROR if successful, error code otherwise
3095  * poo():
3096  * oid():
3097  * rres():
3098  */
3099 static int
3101 {
3102  CCI_OBJECT_POOL *pool = (CCI_OBJECT_POOL *) poo;
3103  CCI_OBJECT *obj;
3104  int res;
3105 
3106  assert (pool != NULL);
3107  assert (oid != NULL);
3108  assert (rres != NULL);
3109 
3110  obj = NULL;
3111  res = hash_lookup (pool->ht, oid, (void **) &obj);
3112  if (res != NO_ERROR)
3113  {
3114  return res;
3115  }
3116 
3117  if (obj != NULL)
3118  {
3119  res = create_cci_object (pool, oid, &obj);
3120  if (res != NO_ERROR)
3121  {
3122  return res;
3123  }
3124 
3125  assert (obj != NULL);
3126  assert (obj->pres != NULL);
3127 
3128  res = hash_insert (pool->ht, obj);
3129  if (res != NO_ERROR)
3130  {
3131  destroy_cci_object (obj);
3132  return res;
3133  }
3134  }
3135 
3136  *rres = (API_RESULTSET *) obj->pres;
3137 
3138  return NO_ERROR;
3139 }
3140 
3141 /*
3142  * opool_oid_delete -
3143  * return: NO_ERROR if successful, error code otherwise
3144  * poo():
3145  * oid():
3146  */
3147 static int
3149 {
3150  CCI_OBJECT_POOL *pool = (CCI_OBJECT_POOL *) poo;
3151  int res;
3152  CCI_OBJECT *obj;
3153  char oid_buf[32];
3154 
3155  assert (pool != NULL);
3156  assert (oid != NULL);
3157 
3158  res = hash_delete (pool->ht, oid, (void **) &obj);
3159  if (res != NO_ERROR)
3160  {
3161  return res;
3162  }
3163 
3164  if (obj != NULL)
3165  {
3166  destroy_cci_object (obj);
3167  }
3168 
3169  xoid2oidstr (oid, oid_buf);
3170 
3171  res = cci_oid (pool->pconn->conn_handle, CCI_OID_DROP, oid_buf, &pool->pconn->err_buf);
3172  return err_from_cci (res);
3173 }
3174 
3175 /*
3176  * opool_oid_get_classname -
3177  * return: NO_ERROR if successful, error code otherwise
3178  * poo():
3179  * oid():
3180  */
3181 static int
3182 opool_oid_get_classname (API_OBJECT_RESULTSET_POOL * poo, CI_OID * oid, char *name, size_t size)
3183 {
3185 }
3186 
3187 /*
3188  * opool_destroy -
3189  * return: void
3190  * poo():
3191  */
3192 static void
3194 {
3195  CCI_OBJECT_POOL *pool = (CCI_OBJECT_POOL *) poo;
3196 
3197  assert (pool != NULL);
3198 
3201 
3202  API_FREE (pool);
3203 
3204  return;
3205 }
3206 
3207 /*
3208  * create_cci_object -
3209  * return: NO_ERROR if successful, error code otherwise
3210  * pool():
3211  * oid():
3212  * cobj():
3213  */
3214 static int
3215 create_cci_object (CCI_OBJECT_POOL * pool, CI_OID * oid, CCI_OBJECT ** cobj)
3216 {
3217  int res, req_handle;
3218  char oid_buf[32];
3219  CCI_OBJECT *obj;
3221 
3222  obj = API_MALLOC (sizeof (*obj));
3223  if (obj == NULL)
3224  {
3226  }
3227 
3228  xoid2oidstr (oid, oid_buf);
3229  res = cci_oid_get (pool->pconn->conn_handle, oid_buf, NULL, &pool->pconn->err_buf);
3230  if (res < 0)
3231  {
3232  API_FREE (obj);
3233  return err_from_cci (res);
3234  }
3235 
3236  req_handle = res;
3237 
3238  pres = NULL;
3239  res =
3240  create_resultset_impl (pool->pconn->conn, pool->pconn->bh, req_handle, &pool->pconn->err_buf, NULL, true, obj,
3241  on_close_opool_res, &ORES_IFS_, &ORMETA_IFS_, &pres);
3242  if (res == NO_ERROR)
3243  {
3244  obj->xoid = *oid;
3245  obj->deleted = false;
3246  obj->req_handle = req_handle;
3247  obj->pres = pres;
3248  obj->pool = pool;
3249  }
3250  else
3251  {
3252  API_FREE (obj);
3253  }
3254 
3255  return res;
3256 }
3257 
3258 /*
3259  * destroy_cci_object -
3260  * return: void
3261  * obj():
3262  */
3263 static void
3265 {
3266  if (obj)
3267  {
3268  if (obj->pres)
3269  {
3270  resultset_impl_dtor ((BH_BIND *) obj->pres);
3271  }
3272  API_FREE (obj);
3273  }
3274 }
3275 
3276 /*
3277  * on_close_opool_res -
3278  * return: NO_ERROR if successful, error code otherwise
3279  * impl():
3280  * arg():
3281  */
3282 static void
3284 {
3285  CCI_OBJECT *obj = (CCI_OBJECT *) arg;
3286 
3287  if (obj->req_handle >= 0)
3288  {
3289  cci_close_req_handle (obj->req_handle);
3290  }
3291  obj->req_handle = -1;
3292  obj->pres = NULL;
3293 }
3294 
3295 /*
3296  * xoid2oidstr -
3297  * return: void
3298  * xoid():
3299  * oidstr():
3300  */
3301 static void
3302 xoid2oidstr (const CI_OID * xoid, char *oidstr)
3303 {
3304  int pageid, slotid, volid;
3305 
3306  assert (xoid != NULL);
3307  assert (oidstr != NULL);
3308 
3309  pageid = xoid->d1;
3310  slotid = (xoid->d2 >> 16) & 0xffff;
3311  volid = xoid->d2 & 0xffff;
3312 
3313  sprintf (oidstr, "@%d|%d|%d", pageid, slotid, volid);
3314 }
3315 
3316 /* copy from ut_str_to_oid() */
3317 
3318 /*
3319  * oidstr2xoid -
3320  * return: NO_ERROR if successful, error code otherwise
3321  * oidstr():
3322  * conn():
3323  * xoid():
3324  */
3325 static int
3326 oidstr2xoid (const char *oidstr, CI_CONNECTION conn, CI_OID * xoid)
3327 {
3328  char *p = (char *) oidstr, *end_p;
3329  int pageid, slotid, volid;
3330  int result = 0;
3331 
3332  if (p == NULL)
3333  {
3334  return ER_INTERFACE_GENERIC; /* CCI_ER_CONVERSION */
3335  }
3336 
3337  if (*p != '@')
3338  {
3339  return ER_INTERFACE_GENERIC;
3340  }
3341 
3342  p++;
3343  result = str_to_int32 (&pageid, &end_p, p, 10);
3344  if (result != 0 || *end_p != '|')
3345  {
3346  return ER_INTERFACE_GENERIC;
3347  }
3348 
3349  p = end_p + 1;
3350  result = str_to_int32 (&slotid, &end_p, p, 10);
3351  if (result != 0 || *end_p != '|')
3352  {
3353  return ER_INTERFACE_GENERIC;
3354  }
3355 
3356  p = end_p + 1;
3357  result = str_to_int32 (&volid, &end_p, p, 10);
3358  if (result != 0 || *end_p != '\0')
3359  {
3360  return ER_INTERFACE_GENERIC;
3361  }
3362 
3363  xoid->d1 = pageid;
3364  xoid->d2 = ((slotid << 16) & 0xffff0000) | volid;
3365  xoid->conn = conn;
3366 
3367  return NO_ERROR;
3368 }
3369 
3370 /*
3371  * opool_ht_comparef -
3372  * return: NO_ERROR if successful, error code otherwise
3373  * key1():
3374  * key2():
3375  * r():
3376  */
3377 static int
3378 opool_ht_comparef (void *key1, void *key2, int *r)
3379 {
3380  CI_OID *oid1, *oid2;
3381 
3382  assert (key1 != NULL);
3383  assert (key2 != NULL);
3384  assert (r != NULL);
3385 
3386  oid1 = (CI_OID *) key1;
3387  oid2 = (CI_OID *) key2;
3388 
3389  if (oid1->d1 > oid2->d1)
3390  {
3391  *r = 1;
3392  }
3393  else if (oid1->d1 == oid2->d1)
3394  {
3395  if (oid1->d2 > oid2->d2)
3396  {
3397  *r = 1;
3398  }
3399  else if (oid1->d2 == oid2->d2)
3400  {
3401  *r = 0;
3402  }
3403  else
3404  {
3405  *r = -1;
3406  }
3407  }
3408  else
3409  {
3410  *r = -1;
3411  }
3412 
3413  return NO_ERROR;
3414 }
3415 
3416 /*
3417  * opool_ht_hashf -
3418  * return: NO_ERROR if successful, error code otherwise
3419  * key():
3420  * rv():
3421  */
3422 static int
3423 opool_ht_hashf (void *key, unsigned int *rv)
3424 {
3425  CI_OID *oid = (CI_OID *) key;
3426 
3427  assert (oid != NULL);
3428  assert (rv != NULL);
3429 
3430  *rv = (unsigned int) (oid->d1 + oid->d2);
3431 
3432  return NO_ERROR;
3433 }
3434 
3435 /*
3436  * opool_ht_keyf -
3437  * return: NO_ERROR if successful, error code otherwise
3438  * elem():
3439  * rk():
3440  */
3441 static int
3442 opool_ht_keyf (void *elem, void **rk)
3443 {
3444  CCI_OBJECT *cobj = (CCI_OBJECT *) elem;
3445 
3446  assert (cobj != NULL);
3447  assert (rk != NULL);
3448 
3449  *rk = &cobj->xoid;
3450 
3451  return NO_ERROR;
3452 }
3453 
3454 /*
3455  * opool_ht_elem_dtor -
3456  * return: NO_ERROR if successful, error code otherwise
3457  * elem():
3458  */
3459 static void
3461 {
3462  CCI_OBJECT *obj = (CCI_OBJECT *) elem;
3463 
3464  destroy_cci_object (obj);
3465 }
3466 
3467 /*
3468  * opool_ght_keyf -
3469  * return: NO_ERROR if successful, error code otherwise
3470  * elem():
3471  * rk():
3472  */
3473 static int
3474 opool_ght_keyf (void *elem, void **rk)
3475 {
3476  GLO_OFFSET *obj = (GLO_OFFSET *) elem;
3477 
3478  assert (obj != NULL);
3479  assert (rk != NULL);
3480 
3481  *rk = &obj->xoid;
3482 
3483  return NO_ERROR;
3484 }
3485 
3486 /*
3487  * opool_ght_elem_dtor -
3488  * return: NO_ERROR if successful, error code otherwise
3489  * elem():
3490  */
3491 static void
3493 {
3494  GLO_OFFSET *obj = (GLO_OFFSET *) elem;
3495 
3496  API_FREE (obj);
3497 }
3498 
3499 /*
3500  * opool_create -
3501  * return: NO_ERROR if successful, error code otherwise
3502  * pconn():
3503  * rpool():
3504  */
3505 static int
3507 {
3508  CCI_OBJECT_POOL *pool;
3509  hash_table *ht, *ght;
3510  int res;
3511 
3512  assert (pconn != NULL);
3513  assert (rpool != NULL);
3514 
3515  pool = API_MALLOC (sizeof (*pool));
3516  if (pool == NULL)
3517  {
3519 
3520  }
3521 
3522  ht = NULL;
3524  if (res != NO_ERROR)
3525  {
3526  API_FREE (pool);
3527  return res;
3528  }
3529 
3531  if (res != NO_ERROR)
3532  {
3533  API_FREE (pool);
3534  hash_destroy (ht, NULL);
3535  }
3536 
3540  pool->ifs.destroy = opool_destroy;
3541 
3542  pool->pconn = pconn;
3543  pool->ht = ht;
3544  pool->ght = ght;
3545 
3546  *rpool = pool;
3547 
3548  return NO_ERROR;
3549 }
3550 
3551 /*
3552  * api_col_length -
3553  * return: NO_ERROR if successful, error code otherwise
3554  * coo():
3555  * length():
3556  */
3557 static int
3558 api_col_length (API_COLLECTION * coo, int *length)
3559 {
3560  CCI_COLLECTION *col = (CCI_COLLECTION *) coo;
3561  int res, len;
3562 
3563  res = col->indexer->ifs->length (col->indexer, &len);
3564  if (res == NO_ERROR)
3565  *length = len;
3566  return res;
3567 }
3568 
3569 /*
3570  * api_col_insert -
3571  * return: NO_ERROR if successful, error code otherwise
3572  * coo():
3573  * pos():
3574  * type():
3575  * ptr():
3576  * size():
3577  */
3578 static int
3579 api_col_insert (API_COLLECTION * coo, long pos, CI_TYPE type, void *ptr, size_t size)
3580 {
3581  CCI_COLLECTION *col = (CCI_COLLECTION *) coo;
3582  API_VAL *val;
3583  int res;
3584 
3585  if (col->type != CI_TYPE_NULL && type != CI_TYPE_NULL && col->type != type)
3586  {
3588  }
3589 
3590  res = col->indexer->ifs->check (col->indexer, (int) pos, CHECK_FOR_INSERT);
3591  if (res != NO_ERROR)
3592  {
3593  return res;
3594  }
3595 
3596  val = API_CALLOC (1, sizeof (*val));
3597  if (val == NULL)
3598  {
3600  }
3601 
3602  res = set_value_to_api_val (val, type, ptr, size);
3603  if (res != NO_ERROR)
3604  {
3605  API_FREE (val);
3606  return res;
3607  }
3608 
3609  res = col->indexer->ifs->insert (col->indexer, (int) pos, NULL, (API_VALUE *) val);
3610  if (res != NO_ERROR)
3611  {
3612  api_val_dtor (NULL, (API_VALUE *) val);
3613  }
3614 
3615  if (type != CI_TYPE_NULL && col->type == CI_TYPE_NULL)
3616  {
3617  col->type = type;
3618  }
3619 
3620  return res;
3621 }
3622 
3623 /*
3624  * api_col_update -
3625  * return: NO_ERROR if successful, error code otherwise
3626  * coo():
3627  * pos():
3628  * type():
3629  * ptr():
3630  * size():
3631  */
3632 static int
3633 api_col_update (API_COLLECTION * coo, long pos, CI_TYPE type, void *ptr, size_t size)
3634 {
3635  CCI_COLLECTION *col = (CCI_COLLECTION *) coo;
3636  API_VAL *val;
3637  VALUE_AREA *va;
3638  int res;
3639 
3640  if (col->type != CI_TYPE_NULL && type != CI_TYPE_NULL && col->type != type)
3641  {
3643  }
3644  res = col->indexer->ifs->check (col->indexer, (int) pos, CHECK_FOR_GET | CHECK_FOR_SET);
3645  if (res != NO_ERROR)
3646  {
3647  return res;
3648  }
3649 
3650  res = col->indexer->ifs->get (col->indexer, (int) pos, &va, (API_VALUE **) (&val));
3651  if (res != NO_ERROR)
3652  {
3653  return res;
3654  }
3655 
3656  res = set_value_to_api_val (val, type, ptr, size);
3657 
3658  return res;
3659 }
3660 
3661 /*
3662  * api_col_delete -
3663  * return: NO_ERROR if successful, error code otherwise
3664  * coo():
3665  * pos():
3666  */
3667 static int
3669 {
3670  CCI_COLLECTION *col = (CCI_COLLECTION *) coo;
3671  API_VAL *val;
3672  VALUE_AREA *va;
3673  int res;
3674 
3675  res = col->indexer->ifs->check (col->indexer, (int) pos, CHECK_FOR_DELETE);
3676  if (res != NO_ERROR)
3677  {
3678  return res;
3679  }
3680 
3681  res = col->indexer->ifs->delete (col->indexer, (int) pos, &va, (API_VALUE **) (&val));
3682  if (res != NO_ERROR)
3683  {
3684  return res;
3685  }
3686 
3687  xcol_elem_dtor (va, (API_VALUE *) val);
3688  return NO_ERROR;
3689 }
3690 
3691 /*
3692  * api_col_get_elem_domain_info -
3693  * return: NO_ERROR if successful, error code otherwise
3694  * coo():
3695  * pos():
3696  * type():
3697  * precision():
3698  * scale():
3699  */
3700 static int
3701 api_col_get_elem_domain_info (API_COLLECTION * coo, long pos, CI_TYPE * type, int *precision, int *scale)
3702 {
3703  CCI_COLLECTION *col = (CCI_COLLECTION *) coo;
3704  API_VAL *val;
3705  VALUE_AREA *va;
3706  int res;
3707 
3708  res = col->indexer->ifs->check (col->indexer, (int) pos, CHECK_FOR_GET);
3709  if (res != NO_ERROR)
3710  {
3711  return res;
3712  }
3713 
3714  res = col->indexer->ifs->get (col->indexer, (int) pos, &va, (API_VALUE **) (&val));
3715  if (res != NO_ERROR)
3716  {
3717  return res;
3718  }
3719 
3720  *type = val->type;
3721 
3722  if (precision)
3723  {
3724  *precision = 0;
3725  }
3726  if (scale)
3727  {
3728  *scale = 0;
3729  }
3730 
3731  return res;
3732 }
3733 
3734 /*
3735  * api_col_get_elem -
3736  * return: NO_ERROR if successful, error code otherwise
3737  * coo():
3738  * pos():
3739  * type():
3740  * addr():
3741  * len():
3742  * outlen():
3743  * isnull():
3744  */
3745 static int
3746 api_col_get_elem (API_COLLECTION * coo, long pos, CI_TYPE type, void *addr, size_t len, size_t * outlen, bool * isnull)
3747 {
3748  CCI_COLLECTION *col = (CCI_COLLECTION *) coo;
3749  API_VAL *val;
3750  VALUE_AREA *va;
3751  int res;
3752 
3753  res = col->indexer->ifs->check (col->indexer, (int) pos, CHECK_FOR_GET);
3754  if (res != NO_ERROR)
3755  {
3756  return res;
3757  }
3758 
3759  res = col->indexer->ifs->get (col->indexer, (int) pos, &va, (API_VALUE **) (&val));
3760  if (res != NO_ERROR)
3761  {
3762  return res;
3763  }
3764 
3765  res = get_value_from_api_val (val, type, addr, len, outlen, isnull);
3766 
3767  return res;
3768 }
3769 
3770 /*
3771  * api_col_destroy -
3772  * return: void
3773  * coo():
3774  */
3775 static void
3777 {
3778  CCI_COLLECTION *col = (CCI_COLLECTION *) coo;
3779 
3780  xcol_destroy ((CI_COLLECTION) col);
3781 }
3782 
3791 };
3792 
3793 /*
3794  * xcol_elem_dtor -
3795  * return: NO_ERROR if successful, error code otherwise
3796  * va():
3797  * av():
3798  */
3799 static void
3801 {
3802  API_VAL *pv = (API_VAL *) av;
3803 
3804  if (pv)
3805  {
3806  api_val_dtor (va, av);
3807  }
3808 }
3809 
3810 /*
3811  * xcol_create -
3812  * return: NO_ERROR if successful, error code otherwise
3813  * type():
3814  * conn():
3815  * rcol():
3816  */
3817 static int
3818 xcol_create (CI_TYPE type, CI_CONNECTION conn, CI_COLLECTION * rcol)
3819 {
3820  int res;
3821  CCI_COLLECTION *col;
3822 
3823  col = API_MALLOC (sizeof (*col));
3824  if (col == NULL)
3825  {
3827  }
3828 
3829  col->col.conn = conn;
3830  col->col.ifs = &COL_IFS_;
3831  col->type = type;
3832 
3833  res = list_indexer_create (&col->indexer);
3834  if (res != NO_ERROR)
3835  {
3836  API_FREE (col);
3837  return res;
3838  }
3839 
3840  *rcol = col;
3841 
3842  return NO_ERROR;
3843 }
3844 
3845 /*
3846  * xcol_destroy -
3847  * return: void
3848  * col():
3849  */
3850 static void
3851 xcol_destroy (CI_COLLECTION col)
3852 {
3853  CCI_COLLECTION *co = (CCI_COLLECTION *) col;
3854 
3855  if (co)
3856  {
3857  co->indexer->ifs->destroy (co->indexer, xcol_elem_dtor);
3858  API_FREE (co);
3859  }
3860 }
3861 
3862 /*
3863  * xcol_elem_cci_bind_mapf -
3864  * return: NO_ERROR if successful, error code otherwise
3865  * arg():
3866  * index():
3867  * va():
3868  * av():
3869  */
3870 static int
3872 {
3874  API_VAL *pv = (API_VAL *) av;
3875  API_VAL_CCI_BIND *bind;
3876  int res;
3877 
3878  assert (va == NULL);
3879 
3880  bind = &binds[index];
3882  res = api_val_cci_bind_bind (pv->type, pv->ptr, pv->len, bind);
3883 
3884  return res;
3885 }
3886 
3887 /*
3888  * convert to string. this is the only safe way when col is heterogeneous
3889  */
3890 
3891 /*
3892  * xcol_to_cci_set -
3893  * return: NO_ERROR if successful, error code otherwise
3894  * col():
3895  * rtset():
3896  */
3897 static int
3898 xcol_to_cci_set (CI_COLLECTION col, T_CCI_SET * rtset)
3899 {
3900  CCI_COLLECTION *co;
3901  T_CCI_SET tset = nullptr;
3902  T_CCI_U_TYPE utype;
3903  int res, size, i;
3904  void **values; /* values array */
3905  int *indicators; /* null indicator array */
3906  API_VAL_CCI_BIND *binds; /* bind array */
3907 
3908  assert (col != NULL);
3909  assert (rtset != NULL);
3910 
3911  co = (CCI_COLLECTION *) col;
3912  res = co->indexer->ifs->length (co->indexer, &size);
3913  if (res != NO_ERROR)
3914  {
3915  return res;
3916  }
3917 
3918  values = NULL;
3919  indicators = NULL;
3920  binds = NULL;
3921 
3922  if (size > 0)
3923  {
3924  values = API_CALLOC (size, sizeof (void *));
3925  indicators = API_CALLOC (size, sizeof (int));
3926  binds = API_CALLOC (size, sizeof (API_VAL_CCI_BIND));
3927 
3928  if (values == NULL || indicators == NULL || binds == NULL)
3929  {
3931  goto res_return;
3932  }
3933  }
3934  else
3935  {
3936  /* empty collection is not null value */
3937  ;
3938  }
3939 
3940  res = co->indexer->ifs->map (co->indexer, xcol_elem_cci_bind_mapf, binds);
3941  if (res != NO_ERROR)
3942  {
3943  return res;
3944  }
3945 
3946  for (i = 0; i < size; i++)
3947  {
3948  values[i] = binds[i].value;
3949  indicators[i] = (binds[i].atype == CCI_U_TYPE_NULL);
3950  }
3951 
3952  utype = type_to_cci_u_type (co->type);
3953 
3954  res = cci_set_make (&tset, utype, size, values, indicators);
3955  if (res != 0)
3956  {
3957  res = err_from_cci (res);
3958  goto res_return;
3959  }
3960 
3961  *rtset = tset;
3962  res = NO_ERROR;
3963 
3964 res_return:
3965  if (indicators)
3966  {
3967  API_FREE (indicators);
3968  }
3969 
3970  if (values)
3971  {
3972  API_FREE (values);
3973  }
3974 
3975  if (binds)
3976  {
3977  /*
3978  * calloc'ed API_VAL_CCI_BIND is safe to pass to api_val_cci_bind_clear()
3979  */
3980  for (i = 0; i < size; i++)
3981  {
3982  api_val_cci_bind_clear (&binds[i]);
3983  }
3984  API_FREE (binds);
3985  }
3986 
3987  return res;
3988 }
3989 
3990 /*
3991  * cci_set_to_xcol -
3992  * return: NO_ERROR if successful, error code otherwise
3993  * conn():
3994  * tset():
3995  * rcol():
3996  */
3997 static int
3998 cci_set_to_xcol (CI_CONNECTION conn, T_CCI_SET tset, CI_COLLECTION * rcol)
3999 {
4000  T_CCI_U_TYPE utype;
4001  CI_TYPE type;
4002  CI_COLLECTION col;
4003  CCI_COLLECTION *co;
4004  API_VAL *pv;
4005  int i, size = 0;
4006  int res;
4007 
4008  assert (tset != NULL);
4009  assert (rcol != NULL);
4010 
4011  utype = cci_set_element_type (tset);
4012  type = cci_u_type_to_type (utype);
4013  res = xcol_create (type, conn, &col);
4014  if (res != NO_ERROR)
4015  {
4016  return res;
4017  }
4018 
4019  co = (CCI_COLLECTION *) col;
4020 
4021  for (i = 0; i < size; i++)
4022  {
4023  pv = NULL;
4024 
4025  res = get_value_from_tset (utype, tset, type, conn, i, &pv);
4026  if (res != NO_ERROR)
4027  {
4028  goto res_return;
4029  }
4030 
4031  assert (pv != NULL);
4032 
4033  res = co->indexer->ifs->insert (co->indexer, i - 1, NULL, (API_VALUE *) pv);
4034  if (res != NO_ERROR)
4035  {
4036  api_val_dtor (NULL, (API_VALUE *) pv);
4037  goto res_return;
4038  }
4039  }
4040 
4041 res_return:
4042  if (col != NULL)
4043  {
4044  xcol_destroy (col);
4045  }
4046 
4047  return res;
4048 }
4049 
4050 /*
4051  * xcol_copy -
4052  * return: NO_ERROR if successful, error code otherwise
4053  * col():
4054  * rcol():
4055  */
4056 static int
4057 xcol_copy (CI_COLLECTION col, CI_COLLECTION * rcol)
4058 {
4059  int size, res, i;
4060  CI_COLLECTION rc;
4061  CCI_COLLECTION *co;
4062  CCI_COLLECTION *rco;
4063 
4064  assert (col != NULL);
4065  assert (rcol != NULL);
4066 
4067  co = (CCI_COLLECTION *) col;
4068 
4069  res = xcol_create (co->type, co->col.conn, &rc);
4070  if (res != NO_ERROR)
4071  {
4072  return res;
4073  }
4074  rco = (CCI_COLLECTION *) rc;
4075 
4076  res = co->indexer->ifs->length (co->indexer, &size);
4077  if (res != NO_ERROR)
4078  {
4079  xcol_destroy (rco);
4080  return res;
4081  }
4082 
4083  for (i = 0; i < size; i++)
4084  {
4085  VALUE_AREA *va;
4086  API_VAL *pv, *pvc;
4087 
4088  res = co->indexer->ifs->get (co->indexer, i, &va, (API_VALUE **) (&pv));
4089  if (res != NO_ERROR)
4090  {
4091  xcol_destroy (rco);
4092  return res;
4093  }
4094 
4095  pvc = API_CALLOC (1, sizeof (*pvc));
4096  if (pvc == NULL)
4097  {
4098  xcol_destroy (rco);
4100  }
4101 
4102  res = set_value_to_api_val (pvc, pv->type, pv->ptr, pv->len);
4103  if (res != NO_ERROR)
4104  {
4105  API_FREE (pvc);
4106  xcol_destroy (rco);
4107  return res;
4108  }
4109 
4110  res = rco->indexer->ifs->insert (rco->indexer, i - 1, NULL, (API_VALUE *) pvc);
4111  if (res != NO_ERROR)
4112  {
4113  api_val_dtor (NULL, (API_VALUE *) pvc);
4114  xcol_destroy (rco);
4115  return res;
4116  }
4117  }
4118 
4119  *rcol = (CI_COLLECTION) rco;
4120  return NO_ERROR;
4121 }
4122 
4123 /*
4124  * ci_create_connection_impl -
4125  * return: NO_ERROR if successful, error code otherwise
4126  * conn():
4127  */
4128 static int
4129 ci_create_connection_impl (CI_CONNECTION * conn)
4130 {
4131  int res;
4132  int rid;
4133  CONNECTION_IMPL *pconn;
4134  BH_INTERFACE *bh;
4135  CCI_OBJECT_POOL *pool = NULL;
4136 
4137  pconn = (CONNECTION_IMPL *) API_CALLOC (1, sizeof (*pconn));
4138  if (pconn == NULL)
4139  {
4141  }
4142 
4143  res = opool_create (pconn, &pool);
4144  if (res != NO_ERROR)
4145  {
4147  API_FREE (pconn);
4148  return res;
4149  }
4150 
4152  if (res != NO_ERROR)
4153  {
4154  API_FREE (pconn);
4155  return res;
4156  }
4157 
4158  res = bh_root_lock (rid, &bh);
4159  if (res != NO_ERROR)
4160  {
4161  API_FREE (pconn);
4162  return res;
4163  }
4164 
4165  res = bind_api_structure (bh, (COMMON_API_STRUCTURE *) pconn, NULL, conn);
4166  if (res != NO_ERROR)
4167  {
4168  (void) bh_root_unlock (rid);
4169  (void) bh_root_release (rid);
4170  API_FREE (pconn);
4172  return res;
4173  }
4174 
4175  init_connection_impl (pconn, rid, *conn, bh, -1, pool);
4176  (void) bh_root_unlock (rid);
4177  return NO_ERROR;
4178 }
4179 
4180 /*
4181  * ci_err_set_impl -
4182  * return: NO_ERROR if successful, error code otherwise
4183  * err_code():
4184  */
4185 static int
4186 ci_err_set_impl (int err_code)
4187 {
4188  return NO_ERROR;
4189 }
4190 
4191 /*
4192  * ci_conn_connect_impl -
4193  * return: NO_ERROR if successful, error code otherwise
4194  * conn():
4195  * host():
4196  * port():
4197  * databasename():
4198  * user_name():
4199  * password():
4200  */
4201 static int
4202 ci_conn_connect_impl (COMMON_API_STRUCTURE * conn, const char *host, unsigned short port, const char *databasename,
4203  const char *user_name, const char *password)
4204 {
4205  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4206  int res;
4207 
4208  res = cci_connect ((char *) host, port, (char *) databasename, (char *) user_name, (char *) password);
4209  if (res < 0)
4210  {
4211  return err_from_cci (res);
4212  }
4213 
4214  pconn->conn_handle = res;
4215  return NO_ERROR;
4216 }
4217 
4218 /*
4219  * ci_conn_close_impl -
4220  * return:
4221  * conn():
4222  */
4223 static int
4225 {
4226  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4227 
4228  (void) cci_disconnect (pconn->conn_handle, &pconn->err_buf);
4229  return NO_ERROR;
4230 }
4231 
4232 /*
4233  * ci_conn_create_statement_impl -
4234  * return:
4235  * conn():
4236  * stmt():
4237  */
4238 static int
4240 {
4241  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4242  STATEMENT_IMPL *pstmt;
4243  int res;
4244 
4245  pstmt = (STATEMENT_IMPL *) API_MALLOC (sizeof (*pstmt));
4246  if (pstmt == NULL)
4247  {
4249  }
4250 
4251  init_statement_impl (pstmt, pconn);
4252 
4253  res = bind_api_structure (pconn->bh, (COMMON_API_STRUCTURE *) pstmt, (COMMON_API_STRUCTURE *) pconn, stmt);
4254  if (res != NO_ERROR)
4255  {
4256  API_FREE (pstmt);
4257  return res;
4258  }
4259 
4260  return NO_ERROR;
4261 }
4262 
4263 /*
4264  * ci_conn_set_option_impl -
4265  * return:
4266  * conn():
4267  * option():
4268  * arg():
4269  * size():
4270  */
4271 static int
4272 ci_conn_set_option_impl (COMMON_API_STRUCTURE * conn, CI_CONNECTION_OPTION option, void *arg, size_t size)
4273 {
4274  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4275  int res = 0;
4276 
4277  switch (option)
4278  {
4279  case CI_CONNECTION_OPTION_LOCK_TIMEOUT:
4280  case CI_CONNECTION_OPTION_TRAN_ISOLATION_LV:
4281  case CI_CONNECTION_OPTION_AUTOCOMMIT:
4282  if (size != sizeof (int))
4283  {
4285  }
4286 
4287  if (option == CI_CONNECTION_OPTION_LOCK_TIMEOUT)
4288  {
4289  res = cci_set_db_parameter (pconn->conn_handle, CCI_PARAM_LOCK_TIMEOUT, arg, &pconn->err_buf);
4290  }
4291  else if (option == CI_CONNECTION_OPTION_TRAN_ISOLATION_LV)
4292  {
4293  res = cci_set_db_parameter (pconn->conn_handle, CCI_PARAM_ISOLATION_LEVEL, arg, &pconn->err_buf);
4294  }
4295  else if (option == CI_CONNECTION_OPTION_AUTOCOMMIT)
4296  {
4297  res = cci_set_db_parameter (pconn->conn_handle, CCI_PARAM_AUTO_COMMIT, arg, &pconn->err_buf);
4298  }
4299 
4300  if (res != 0)
4301  {
4302  return err_from_cci (pconn->err_buf.err_code);
4303  }
4304 
4305  if (option == CI_CONNECTION_OPTION_AUTOCOMMIT)
4306  {
4307  pconn->autocommit = *(int *) arg != 0;
4308  }
4309 
4310  break;
4311 
4312  case CI_CONNECTION_OPTION_CLIENT_VERSION:
4313  case CI_CONNECTION_OPTION_SERVER_VERSION:
4314  default:
4316  }
4317 
4318  return NO_ERROR;
4319 }
4320 
4321 /*
4322  * ci_conn_get_option_impl -
4323  * return:
4324  * conn():
4325  * option():
4326  * arg():
4327  * size():
4328  */
4329 static int
4330 ci_conn_get_option_impl (COMMON_API_STRUCTURE * conn, CI_CONNECTION_OPTION option, void *arg, size_t size)
4331 {
4332  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4333  int res = 0;
4334 
4335  switch (option)
4336  {
4337  case CI_CONNECTION_OPTION_LOCK_TIMEOUT:
4338  case CI_CONNECTION_OPTION_TRAN_ISOLATION_LV:
4339  case CI_CONNECTION_OPTION_AUTOCOMMIT:
4340  if (size != sizeof (int))
4341  {
4343  }
4344 
4345  if (option == CI_CONNECTION_OPTION_LOCK_TIMEOUT)
4346  {
4347  res = cci_get_db_parameter (pconn->conn_handle, CCI_PARAM_LOCK_TIMEOUT, arg, &pconn->err_buf);
4348  }
4349  else if (option == CI_CONNECTION_OPTION_TRAN_ISOLATION_LV)
4350  {
4351  res = cci_get_db_parameter (pconn->conn_handle, CCI_PARAM_ISOLATION_LEVEL, arg, &pconn->err_buf);
4352  }
4353  else if (option == CI_CONNECTION_OPTION_AUTOCOMMIT)
4354  {
4355  res = cci_get_db_parameter (pconn->conn_handle, CCI_PARAM_AUTO_COMMIT, arg, &pconn->err_buf);
4356  }
4357 
4358  if (res != 0)
4359  {
4360  return err_from_cci (pconn->err_buf.err_code);
4361  }
4362  break;
4363 
4364  case CI_CONNECTION_OPTION_CLIENT_VERSION:
4365  {
4366  int mj, mi, pa, res;
4367  char buf[48];
4368 
4369  res = cci_get_version (&mj, &mi, &pa);
4370  if (res != 0)
4371  {
4372  return err_from_cci (pconn->err_buf.err_code);
4373  }
4374 
4375  sprintf (buf, "cci %d.%d.%d", mj, mi, pa);
4376  strncpy (arg, buf, size);
4377  break;
4378  }
4379 
4380  case CI_CONNECTION_OPTION_SERVER_VERSION:
4381  default:
4383  }
4384 
4385  return NO_ERROR;
4386 }
4387 
4388 /*
4389  * ci_conn_commit_impl -
4390  * return:
4391  * conn():
4392  */
4393 static int
4395 {
4396  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4397  int res;
4398 
4399  res = cci_end_tran (pconn->conn_handle, CCI_TRAN_COMMIT, &pconn->err_buf);
4400  if (res != 0)
4401  {
4402  return err_from_cci (pconn->err_buf.err_code);
4403  }
4404 
4405  res = complete_connection (pconn);
4406 
4407  return res;
4408 }
4409 
4410 /*
4411  * ci_conn_rollback_impl -
4412  * return:
4413  * conn():
4414  */
4415 static int
4417 {
4418  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4419  int res;
4420 
4421  res = cci_end_tran (pconn->conn_handle, CCI_TRAN_ROLLBACK, &pconn->err_buf);
4422  if (res != 0)
4423  {
4424  return err_from_cci (pconn->err_buf.err_code);
4425  }
4426 
4427  res = complete_connection (pconn);
4428 
4429  return res;
4430 }
4431 
4432 /*
4433  * ci_conn_get_error_impl -
4434  * return:
4435  * conn():
4436  * err():
4437  * msg():
4438  * size():
4439  */
4440 static int
4441 ci_conn_get_error_impl (COMMON_API_STRUCTURE * conn, int *err, char *msg, size_t size)
4442 {
4443  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) conn;
4444 
4445  *err = err_from_cci (pconn->err_buf.err_code);
4446  strncpy (msg, pconn->err_buf.err_msg, size);
4447 
4448  return NO_ERROR;
4449 }
4450 
4451 /*
4452  * ci_stmt_add_batch_query_impl -
4453  * return:
4454  * stmt():
4455  * sql():
4456  * len():
4457  */
4458 static int
4460 {
4461  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4462  BATCH_SQL_ITEM *bsi;
4463 
4464  if (pstmt->status & CI_STMT_STATUS_PREPARED)
4465  {
4467  }
4468 
4469  if (!(pstmt->status & CI_STMT_STATUS_BATCH_ADDED) && (pstmt->status & CI_STMT_STATUS_EXECUTED))
4470  {
4472  }
4473 
4474  bsi = API_MALLOC (sizeof (*bsi) + len);
4475  if (bsi == NULL)
4476  {
4478  }
4479 
4480  dlisth_init (&bsi->h);
4481  memcpy (bsi->sql, sql, len);
4482  bsi->sql[len] = 0;
4483  dlisth_insert_before ((dlisth *) bsi, &pstmt->batch);
4484  pstmt->num_batch++;
4485 
4486  return NO_ERROR;
4487 }
4488 
4489 /*
4490  * ci_stmt_add_batch_impl -
4491  * return:
4492  * stmt():
4493  */
4494 static int
4496 {
4497  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4498  BATCH_ARY_ITEM *bai;
4499  int res;
4500  struct add_batch_params_arg arg;
4501 
4502  if (!(pstmt->status & CI_STMT_STATUS_PREPARED))
4503  {
4505  }
4506 
4507  if (!(pstmt->status & CI_STMT_STATUS_BATCH_ADDED) && (pstmt->status & CI_STMT_STATUS_EXECUTED))
4508  {
4510  }
4511 
4512  bai = API_MALLOC (sizeof (*bai) + sizeof (API_VAL *) * (pstmt->num_col - 1));
4513  if (bai == NULL)
4514  {
4516  }
4517 
4518  dlisth_init (&bai->h);
4519  arg.nadded = 0;
4520  arg.bai = bai;
4521  arg.indexer = pstmt->params;
4522 
4523  res = pstmt->params->ifs->map (pstmt->params, add_batch_params_mapf, &arg);
4524  if (res != NO_ERROR)
4525  {
4526  (void) pstmt->params->ifs->map (pstmt->params, add_batch_params_restore_mapf, &arg);
4527  API_FREE (bai);
4528  return res;
4529  }
4530 
4531  dlisth_insert_before ((dlisth *) bai, &pstmt->batch);
4532  pstmt->num_batch++;
4533 
4534  return NO_ERROR;
4535 }
4536 
4537 /*
4538  * ci_stmt_clear_batch_impl -
4539  * return:
4540  * stmt():
4541  */
4542 static int
4544 {
4545  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4546  int res;
4547 
4548  if ((!(pstmt->status & CI_STMT_STATUS_BATCH_ADDED) && (pstmt->status & CI_STMT_STATUS_EXECUTED)))
4549  {
4551  }
4552 
4553  res = stmt_complete_batch (pstmt);
4554 
4555  return res;
4556 }
4557 
4558 #define API_EXEC_PRE() \
4559 do { \
4560  if (pstmt->status & CI_STMT_STATUS_EXECUTED) \
4561  { \
4562  res = complete_statement (pstmt); \
4563  if (res != NO_ERROR) \
4564  return res; \
4565  pstmt->status &= ~CI_STMT_STATUS_EXECUTED; \
4566  } \
4567  \
4568  if (pstmt->pconn->autocommit && pstmt->pconn->n_need_complete > 0) \
4569  { \
4570  res = complete_connection (pstmt->pconn); \
4571  if (res != NO_ERROR) \
4572  return res; \
4573  assert (pstmt->pconn->n_need_complete == 0); \
4574  } \
4575 } while (0)
4576 
4577 #define API_EXEC_POST(has_result) \
4578 do { \
4579  if (pstmt->pconn->autocommit && !(has_result)) \
4580  { \
4581  res = \
4582  cci_end_tran (pstmt->pconn->conn_handle, CCI_TRAN_COMMIT, \
4583  &pstmt->pconn->err_buf); \
4584  if (r != 0) \
4585  return err_from_cci (res); \
4586  } \
4587 } while (0)
4588 
4589 /*
4590  * ci_stmt_execute_immediate_impl -
4591  * return:
4592  * stmt():
4593  * sql():
4594  * len():
4595  * rs():
4596  * r():
4597  */
4598 static int
4599 ci_stmt_execute_immediate_impl (COMMON_API_STRUCTURE * stmt, char *sql, size_t len, CI_RESULTSET * rs, int *r)
4600 {
4601  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4602  int res;
4603  int req_handle = -1;
4604  char pp_flag = 0;
4605 
4606  /* check status */
4607  if (pstmt->status & CI_STMT_STATUS_PREPARED)
4608  {
4610  }
4611 
4612  if (pstmt->status & CI_STMT_STATUS_BATCH_ADDED)
4613  {
4615  }
4616 
4617  API_EXEC_PRE ();
4618 
4619  /* flag is inherited */
4620  if (pstmt->opt_updatable_result)
4621  {
4622  pp_flag |= CCI_PREPARE_UPDATABLE;
4623  }
4624 
4625  req_handle = cci_prepare (pstmt->pconn->conn_handle, sql, pp_flag, &pstmt->pconn->err_buf);
4626  if (req_handle < 0)
4627  {
4628  return err_from_cci (pstmt->pconn->err_buf.err_code);
4629  }
4630 
4631  pstmt->req_handle = req_handle;
4632  res = statement_execute (pstmt, &pstmt->pconn->err_buf);
4633  if (res != NO_ERROR)
4634  {
4635  (void) cci_close_req_handle (req_handle);
4636  pstmt->req_handle = -1;
4637  return res;
4638  }
4639 
4640  res = statement_get_reshandle_or_affectedrows (pstmt->pconn->bh, pstmt);
4641  if (res != NO_ERROR)
4642  {
4643  (void) cci_close_req_handle (req_handle);
4644  pstmt->req_handle = -1;
4645  return res;
4646  }
4647 
4648  if (pstmt->has_resultset)
4649  {
4650  *rs = pstmt->res_handle;
4651  pstmt->pconn->n_need_complete++;
4652  }
4653  else
4654  {
4655  *r = pstmt->affected_rows;
4656  }
4657 
4658  pstmt->status |= CI_STMT_STATUS_EXECUTED;
4659  API_EXEC_POST (pstmt->has_resultset);
4660 
4661  return NO_ERROR;
4662 }
4663 
4664 /*
4665  * ci_stmt_execute_impl -
4666  * return:
4667  * stmt():
4668  * rs():
4669  * r():
4670  */
4671 static int
4672 ci_stmt_execute_impl (COMMON_API_STRUCTURE * stmt, CI_RESULTSET * rs, int *r)
4673 {
4674  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4675  int res;
4676  int i;
4677 
4678  if (!(pstmt->status & CI_STMT_STATUS_PREPARED))
4679  {
4681  }
4682 
4683  API_EXEC_PRE ();
4684 
4685  for (i = 0; i < pstmt->num_col; i++)
4686  {
4687  VALUE_AREA *va;
4688  API_VALUE *v;
4689 
4690  res = pstmt->params->ifs->check (pstmt->params, i, CHECK_FOR_GET);
4691  if (res != NO_ERROR)
4692  {
4693  return res;
4694  }
4695 
4696  res = pstmt->params->ifs->get (pstmt->params, i, &va, &v);
4697  if (res != NO_ERROR)
4698  {
4699  return res;
4700  }
4701 
4702  if (v == NULL)
4703  {
4705  }
4706 
4707  res = api_val_bind_param (pstmt->pconn->conn, pstmt->req_handle, (API_VAL *) v, i + 1);
4708  if (res != NO_ERROR)
4709  {
4710  return res;
4711  }
4712  }
4713 
4714  res = statement_execute (pstmt, &pstmt->pconn->err_buf);
4715  if (res != NO_ERROR)
4716  {
4717  return res;
4718  }
4719 
4720  res = statement_get_reshandle_or_affectedrows (pstmt->pconn->bh, pstmt);
4721  if (res != NO_ERROR)
4722  {
4723  return res;
4724  }
4725 
4726  if (pstmt->has_resultset)
4727  {
4728  *rs = pstmt->res_handle;
4729  pstmt->pconn->n_need_complete++;
4730  }
4731  else
4732  {
4733  *r = pstmt->affected_rows;
4734  }
4735 
4736  pstmt->status |= CI_STMT_STATUS_EXECUTED;
4737  API_EXEC_POST (pstmt->has_resultset);
4738 
4739  return NO_ERROR;
4740 }
4741 
4742 /*
4743  * ci_stmt_execute_batch_impl -
4744  * return:
4745  * stmt():
4746  * br():
4747  */
4748 static int
4750 {
4751  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4752  int res;
4754 
4755  if (!(pstmt->status & CI_STMT_STATUS_BATCH_ADDED))
4756  {
4758  }
4759 
4760  res =
4761  bind_api_structure (pstmt->pconn->bh, ((COMMON_API_STRUCTURE *) (&pstmt->BR)), (COMMON_API_STRUCTURE *) pstmt,
4762  &handle);
4763  if (res != NO_ERROR)
4764  {
4765  return res;
4766  }
4767 
4768  pstmt->bres_handle = handle;
4769  if (pstmt->status & CI_STMT_STATUS_PREPARED)
4770  {
4771  res = stmt_execute_batch_sql (pstmt);
4772  }
4773  else
4774  {
4775  res = stmt_execute_batch_array (pstmt);
4776  }
4777 
4778  if (res != NO_ERROR)
4779  {
4780  (void) pstmt->pconn->bh->destroy_handle (pstmt->pconn->bh, handle);
4781  pstmt->bres_handle = -1LL;
4782  return res;
4783  }
4784 
4785  *br = handle;
4786  return NO_ERROR;
4787 }
4788 
4789 /*
4790  * ci_stmt_get_option_impl -
4791  * return:
4792  * stmt():
4793  * option():
4794  * arg():
4795  * size():
4796  */
4797 static int
4798 ci_stmt_get_option_impl (COMMON_API_STRUCTURE * stmt, CI_STATEMENT_OPTION option, void *arg, size_t size)
4799 {
4800  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4801 
4802  switch (option)
4803  {
4804  case CI_STATEMENT_OPTION_HOLD_CURSORS_OVER_COMMIT:
4805  *(int *) arg = 0; /* not implemented */
4806  break;
4807 
4808  case CI_STATEMENT_OPTION_UPDATABLE_RESULT:
4809  *(int *) arg = (pstmt->opt_updatable_result) ? 1 : 0;
4810  break;
4811 
4812  case CI_STATEMENT_OPTION_GET_GENERATED_KEYS:
4813  *(int *) arg = 0; /* not implemented */
4814  break;
4815 
4816  case CI_STATEMENT_OPTION_ASYNC_QUERY:
4817  *(int *) arg = 0;
4818  break;
4819 
4820  case CI_STATEMENT_OPTION_EXEC_CONTINUE_ON_ERROR:
4821  case CI_STATEMENT_OPTION_LAZY_EXEC:
4822  *(int *) arg = 0;
4823  break;
4824 
4825  default:
4827  break;
4828  }
4829 
4830  return NO_ERROR;
4831 }
4832 
4833 /*
4834  * ci_stmt_set_option_impl -
4835  * return:
4836  * stmt():
4837  * option():
4838  * arg():
4839  * size():
4840  */
4841 static int
4842 ci_stmt_set_option_impl (COMMON_API_STRUCTURE * stmt, CI_STATEMENT_OPTION option, void *arg, size_t size)
4843 {
4844  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4845 
4846  switch (option)
4847  {
4848 
4849  case CI_STATEMENT_OPTION_UPDATABLE_RESULT:
4850  pstmt->opt_updatable_result = *(int *) arg != 0 ? true : false;
4851  break;
4852 
4853  case CI_STATEMENT_OPTION_ASYNC_QUERY:
4854  case CI_STATEMENT_OPTION_EXEC_CONTINUE_ON_ERROR:
4855  case CI_STATEMENT_OPTION_LAZY_EXEC:
4856  case CI_STATEMENT_OPTION_GET_GENERATED_KEYS:
4857  case CI_STATEMENT_OPTION_HOLD_CURSORS_OVER_COMMIT:
4859 
4860  default:
4862  break;
4863  }
4864 
4865  return NO_ERROR;
4866 }
4867 
4868 /*
4869  * ci_stmt_prepare_impl -
4870  * return:
4871  * stmt():
4872  * sql():
4873  * len():
4874  */
4875 static int
4876 ci_stmt_prepare_impl (COMMON_API_STRUCTURE * stmt, const char *sql, size_t len)
4877 {
4878  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4879  int res;
4880  char pp_flag = 0;
4881  int req_handle;
4882  T_CCI_COL_INFO *col_info;
4883  T_CCI_CUBRID_STMT cmd_type;
4884  int num_col;
4885 
4886  /* check status */
4887  if (pstmt->status & CI_STMT_STATUS_PREPARED)
4888  {
4889  return ER_INTERFACE_GENERIC; /* already prepared */
4890  }
4891 
4892  if (pstmt->status & CI_STMT_STATUS_EXECUTED)
4893  {
4895  }
4896 
4897  if (pstmt->opt_updatable_result)
4898  {
4899  pp_flag = CCI_PREPARE_UPDATABLE;
4900  }
4901 
4902  res = cci_prepare (pstmt->pconn->conn_handle, (char *) sql, pp_flag, &pstmt->pconn->err_buf);
4903  req_handle = res;
4904  if (res < 0)
4905  {
4906  return err_from_cci (res);
4907  }
4908 
4909  col_info = cci_get_result_info (pstmt->req_handle, &cmd_type, &num_col);
4910  if (col_info == NULL)
4911  {
4912  return ER_INTERFACE_GENERIC;
4913  }
4914 
4915  pstmt->req_handle = req_handle;
4916  pstmt->got_pm_handle = false;
4917  pstmt->pm_handle = -1LL;
4918  pstmt->num_col = num_col;
4919  pstmt->cmd_type = cmd_type;
4920  pstmt->col_info = col_info;
4921  pstmt->status |= CI_STMT_STATUS_PREPARED;
4922 
4923  return NO_ERROR;
4924 }
4925 
4926 /*
4927  * ci_stmt_register_out_parameter_impl -
4928  * return:
4929  * stmt():
4930  * index():
4931  */
4932 static int
4934 {
4936 }
4937 
4938 /*
4939  * ci_stmt_get_resultset_metadata_impl -
4940  * return:
4941  * stmt():
4942  * r():
4943  */
4944 static int
4946 {
4947  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4948  RESULTSET_IMPL *pres;
4949  int res;
4950 
4951  if (!(pstmt->status & CI_STMT_STATUS_EXECUTED))
4952  {
4954  }
4955 
4956  if (!pstmt->has_resultset)
4957  {
4959  }
4960 
4961  pres = NULL;
4962  res = pstmt->pconn->bh->lookup (pstmt->pconn->bh, pstmt->res_handle, (BH_BIND **) (&pres));
4963  if (res != NO_ERROR)
4964  {
4965  return res;
4966  }
4967 
4968  assert (pres != NULL);
4969 
4970  if (pres == NULL)
4971  {
4972  return ER_INTERFACE_GENERIC;
4973  }
4974 
4975  res = lazy_bind_qres_rmeta (pres);
4976  if (res != NO_ERROR)
4977  {
4978  return res;
4979  }
4980 
4981  *r = pres->rm_handle;
4982  return NO_ERROR;
4983 }
4984 
4985 /*
4986  * ci_stmt_get_parameter_metadata_impl -
4987  * return:
4988  * stmt():
4989  * r():
4990  */
4991 static int
4993 {
4994  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
4995  int res;
4996 
4997  if (!(pstmt->status & CI_STMT_STATUS_PREPARED))
4998  {
5000  }
5001 
5002  res = lazy_bind_pstmt_pmeta (pstmt);
5003  if (res == NO_ERROR)
5004  {
5005  *r = pstmt->pm_handle;
5006  }
5007 
5008  return res;
5009 }
5010 
5011 /*
5012  * ci_stmt_get_parameter_impl -
5013  * return:
5014  * stmt():
5015  * index():
5016  * type():
5017  * addr():
5018  * len():
5019  * outlen():
5020  * isnull():
5021  */
5022 static int
5023 ci_stmt_get_parameter_impl (COMMON_API_STRUCTURE * stmt, int index, CI_TYPE type, void *addr, size_t len,
5024  size_t * outlen, bool * isnull)
5025 {
5026  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
5027  int res;
5028  VALUE_AREA *va;
5029  API_VAL *pv;
5030 
5031  if (!(pstmt->status & CI_STMT_STATUS_PREPARED))
5032  {
5034  }
5035 
5036  if (pstmt->params == NULL)
5037  {
5039  }
5040 
5041  res = pstmt->params->ifs->check (pstmt->params, index - 1, CHECK_FOR_GET);
5042  if (res != NO_ERROR)
5043  {
5044  return res;
5045  }
5046 
5047  res = pstmt->params->ifs->get (pstmt->params, index - 1, &va, (API_VALUE **) (&pv));
5048  if (res != NO_ERROR)
5049  {
5050  return res;
5051  }
5052 
5053  if (pv != NULL)
5054  {
5055  res = get_value_from_api_val (pv, type, addr, len, outlen, isnull);
5056  return res;
5057  }
5058  else
5059  {
5061  }
5062 }
5063 
5064 /*
5065  * ci_stmt_set_parameter_impl -
5066  * return:
5067  * stmt():
5068  * index():
5069  * type():
5070  * val():
5071  * size():
5072  */
5073 static int
5074 ci_stmt_set_parameter_impl (COMMON_API_STRUCTURE * stmt, int index, CI_TYPE type, void *val, size_t size)
5075 {
5076  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
5077  int res;
5078  VALUE_AREA *va;
5079  API_VAL *pv;
5080 
5081  if (!(pstmt->status & CI_STMT_STATUS_PREPARED))
5082  {
5084  }
5085 
5086  if (pstmt->params == NULL)
5087  {
5088  VALUE_INDEXER *vi;
5089 
5090  res = array_indexer_create (pstmt->num_col, &vi);
5091  if (res != NO_ERROR)
5092  {
5093  return res;
5094  }
5095  pstmt->params = vi;
5096  }
5097 
5098  res = pstmt->params->ifs->check (pstmt->params, index - 1, CHECK_FOR_GET | CHECK_FOR_SET);
5099  if (res != NO_ERROR)
5100  {
5101  return res;
5102  }
5103 
5104  res = pstmt->params->ifs->get (pstmt->params, index - 1, &va, (API_VALUE **) (&pv));
5105  if (res != NO_ERROR)
5106  {
5107  return res;
5108  }
5109 
5110  if (pv != NULL)
5111  {
5112  res = set_value_to_api_val (pv, type, val, size);
5113  return res;
5114  }
5115 
5116  assert (pv == NULL);
5117 
5118  pv = API_CALLOC (1, sizeof (*pv));
5119  if (pv == NULL)
5120  {
5122  }
5123 
5124  pv->type = CI_TYPE_NULL;
5125 
5126  res = set_value_to_api_val (pv, type, val, size);
5127  if (res != NO_ERROR)
5128  {
5129  api_val_dtor (NULL, (API_VALUE *) pv);
5130  return res;
5131  }
5132 
5133  res = pstmt->params->ifs->set (pstmt->params, index - 1, NULL, (API_VALUE *) pv);
5134  if (res != NO_ERROR)
5135  {
5136  api_val_dtor (NULL, (API_VALUE *) pv);
5137  }
5138 
5139  return res;
5140 }
5141 
5142 /*
5143  * ci_stmt_get_resultset_impl -
5144  * return:
5145  * stmt():
5146  * r():
5147  */
5148 static int
5150 {
5151  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
5152 
5153  if (!(pstmt->status & CI_STMT_STATUS_EXECUTED))
5154  {
5156  }
5157 
5158  if (!pstmt->has_resultset)
5159  {
5161  }
5162 
5163  *r = pstmt->res_handle;
5164 
5165  return NO_ERROR;
5166 }
5167 
5168 /*
5169  * ci_stmt_affected_rows_impl -
5170  * return:
5171  * stmt():
5172  * out():
5173  */
5174 static int
5176 {
5177  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
5178 
5179  if (!(pstmt->status & CI_STMT_STATUS_EXECUTED))
5180  {
5182  }
5183 
5184  *out = pstmt->affected_rows;
5185  return NO_ERROR;
5186 }
5187 
5188 /*
5189  * ci_stmt_next_result_impl -
5190  * return:
5191  * stmt():
5192  * exist_result():
5193  */
5194 static int
5196 {
5197  STATEMENT_IMPL *pstmt = (STATEMENT_IMPL *) stmt;
5198  int res;
5199 
5200  if (!(pstmt->status & CI_STMT_STATUS_EXECUTED))
5201  {
5203  }
5204 
5205  if (pstmt->curr_query_result_index + 1 > pstmt->num_query)
5206  {
5208  }
5209 
5210  pstmt->curr_query_result_index++;
5211  if (pstmt->has_resultset)
5212  {
5213  res = pstmt->pconn->bh->destroy_handle (pstmt->pconn->bh, pstmt->res_handle);
5214  if (res != NO_ERROR)
5215  {
5216  return res;
5217  }
5218  }
5219 
5220  res = cci_next_result (pstmt->req_handle, &pstmt->pconn->err_buf);
5221  if (res != 0)
5222  {
5223  if (res == CAS_ER_NO_MORE_RESULT_SET)
5224  {
5226  }
5227  else
5228  {
5229  return err_from_cci (res);
5230  }
5231  }
5232 
5233  res = statement_get_reshandle_or_affectedrows (pstmt->pconn->bh, pstmt);
5234  return res;
5235 }
5236 
5237 /*
5238  * ci_stmt_get_first_error_impl -
5239  * return:
5240  * stmt():
5241  * line():
5242  * col():
5243  * errcode():
5244  * err_msg():
5245  * size():
5246  */
5247 static int
5248 ci_stmt_get_first_error_impl (COMMON_API_STRUCTURE * stmt, int *line, int *col, int *errcode, char *err_msg,
5249  size_t size)
5250 {
5252 }
5253 
5254 /*
5255  * ci_stmt_get_next_error_impl -
5256  * return:
5257  * stmt():
5258  * line():
5259  * col():
5260  * errcode():
5261  * err_msg():
5262  * size():
5263  */
5264 static int
5265 ci_stmt_get_next_error_impl (COMMON_API_STRUCTURE * stmt, int *line, int *col, int *errcode, char *err_msg, size_t size)
5266 {
5268 }
5269 
5270 /*
5271  * ci_stmt_get_query_type_impl -
5272  * return:
5273  * stmt():
5274  * type(out):
5275  */
5276 static int
5278 {
5280 }
5281 
5282 /*
5283  * ci_stmt_get_start_line_impl -
5284  * return:
5285  * stmt():
5286  * line(out):
5287  */
5288 static int
5290 {
5292 }
5293 
5294 /*
5295  * ci_batch_res_query_count_impl -
5296  * return:
5297  * br():
5298  * count():
5299  */
5300 static int
5302 {
5303  BATCH_RESULT_IMPL *pbr = (BATCH_RESULT_IMPL *) br;
5304 
5305  *count = pbr->bptr->num_query;
5306  return NO_ERROR;
5307 }
5308 
5309 /*
5310  * ci_batch_res_get_result_impl -
5311  * return:
5312  * br():
5313  * index():
5314  * ret():
5315  * nr():
5316  */
5317 static int
5319 {
5320  BATCH_RESULT_IMPL *pbr = (BATCH_RESULT_IMPL *) br;
5321  int r;
5322 
5323  if (index > pbr->bptr->num_query)
5324  {
5326  }
5327 
5328  r = CCI_QUERY_RESULT_RESULT (pbr->bptr->query_result, index);
5329  if (r >= 0)
5330  {
5331  *nr = r;
5332  }
5333 
5334  *ret = r < 0 ? err_from_cci (r) : NO_ERROR;
5335  return NO_ERROR;
5336 }
5337 
5338 /*
5339  * ci_batch_res_get_error_impl -
5340  * return:
5341  * br():
5342  * index():
5343  * err_code():
5344  * err_msg():
5345  * buf_size():
5346  */
5347 static int
5348 ci_batch_res_get_error_impl (COMMON_API_STRUCTURE * br, int index, int *err_code, char *err_msg, size_t buf_size)
5349 {
5350  BATCH_RESULT_IMPL *pbr = (BATCH_RESULT_IMPL *) br;
5351  int r;
5352  const char *msg;
5353 
5354  if (index > pbr->bptr->num_query)
5355  {
5357  }
5358 
5359  r = CCI_QUERY_RESULT_RESULT (pbr->bptr->query_result, index);
5360  msg = CCI_QUERY_RESULT_ERR_MSG (pbr->bptr->query_result, index);
5361  if (err_code != NULL)
5362  {
5363  *err_code = r < 0 ? err_from_cci (r) : NO_ERROR;
5364  }
5365 
5366  if (err_msg != NULL)
5367  {
5368  if (buf_size <= 0)
5369  {
5371  }
5372  strncpy (err_msg, msg, buf_size);
5373  }
5374 
5375  return NO_ERROR;
5376 }
5377 
5378 /*
5379  * ci_pmeta_get_count_impl -
5380  * return:
5381  * pmeta():
5382  * count():
5383  */
5384 static int
5386 {
5387  PARAMETER_META_IMPL *pm = (PARAMETER_META_IMPL *) pmeta;
5388 
5389  *count = pm->bptr->num_col;
5390 
5391  return NO_ERROR;
5392 }
5393 
5394 /*
5395  * ci_pmeta_get_info_impl -
5396  * return:
5397  * pmeta():
5398  * index():
5399  * type():
5400  * arg():
5401  * size():
5402  */
5403 static int
5404 ci_pmeta_get_info_impl (COMMON_API_STRUCTURE * pmeta, int index, CI_PMETA_INFO_TYPE type, void *arg, size_t size)
5405 {
5406  PARAMETER_META_IMPL *pm = (PARAMETER_META_IMPL *) pmeta;
5407 
5408  switch (type)
5409  {
5410  case CI_PMETA_INFO_MODE:
5411  if (size < sizeof (int))
5412  {
5414  }
5415 
5416  *(int *) arg = 0;
5417  break;
5418 
5419  case CI_PMETA_INFO_COL_TYPE:
5420  if (size < sizeof (int))
5421  {
5423  }
5424 
5425  *(int *) arg = cci_u_type_to_type (pm->bptr->col_info[index - 1].type);
5426  break;
5427 
5428  case CI_PMETA_INFO_PRECISION:
5429  if (size < sizeof (int))
5430  {
5432  }
5433 
5434  *(int *) arg = pm->bptr->col_info[index - 1].precision;
5435  break;
5436 
5437  case CI_PMETA_INFO_SCALE:
5438  if (size < sizeof (int))
5439  {
5441  }
5442 
5443  *(int *) arg = pm->bptr->col_info[index - 1].scale;
5444  break;
5445 
5446  case CI_PMETA_INFO_NULLABLE:
5447  if (size < sizeof (int))
5448  {
5450  }
5451 
5452  *(int *) arg = pm->bptr->col_info[index - 1].is_non_null ? 0 : 1;
5453  break;
5454 
5455  default:
5457  }
5458 
5459  return NO_ERROR;
5460 }
5461 
5462 
5463 /*
5464  * ci_get_connection_opool_impl -
5465  * return:
5466  * pst():
5467  * rpool():
5468  */
5469 static int
5471 {
5472  CONNECTION_IMPL *pconn = (CONNECTION_IMPL *) pst;
5473 
5474  *rpool = (API_OBJECT_RESULTSET_POOL *) pconn->opool;
5475  return NO_ERROR;
5476 }
5477 
5478 /*
5479  * ci_collection_new_impl -
5480  * return:
5481  * conn():
5482  * coll():
5483  */
5484 static int
5485 ci_collection_new_impl (CI_CONNECTION conn, CI_COLLECTION * coll)
5486 {
5487  return xcol_create (CI_TYPE_NULL, conn, coll);
5488 }
5489 
5490 /* The only exported one */
5530 };
static int ci_collection_new_impl(CI_CONNECTION conn, CI_COLLECTION *coll)
Definition: cci_stub.c:5485
int bh_root_unlock(int rrid)
Definition: api_handle.c:944
#define dlisth_insert_before(ih, bh)
Definition: api_util.h:58
static int stmt_execute_batch_sql(STATEMENT_IMPL *pstmt)
Definition: cci_stub.c:2503
RESULTSET_IMPL * bp
Definition: cci_stub.c:147
#define dlisth_insert_after(ih, bh)
Definition: api_util.h:68
#define ER_INTERFACE_RESULTSET_CLOSED
Definition: error_code.h:1200
static int ci_conn_get_error_impl(COMMON_API_STRUCTURE *conn, int *err, char *msg, size_t size)
Definition: cci_stub.c:4441
dlisth * next
Definition: api_util.h:33
#define ER_INTERFACE_IS_NOT_BATCH_STATEMENT
Definition: error_code.h:1190
void * handle
static int api_ores_fetch(API_RESULTSET *res, int offset, CI_FETCH_POSITION pos)
Definition: cci_stub.c:2738
static int get_value_from_req_handle(CI_CONNECTION conn, int req_handle, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *is_null)
Definition: cci_stub.c:1183
int(* bind_get_first_child)(BH_INTERFACE *ifs, BH_BIND *bind, BH_BIND **pchild)
Definition: api_handle.h:67
static int create_cci_object(CCI_OBJECT_POOL *pool, CI_OID *oid, CCI_OBJECT **cobj)
Definition: cci_stub.c:3215
#define NO_ERROR
Definition: error_code.h:46
static int api_val_bind_param(CI_CONNECTION conn, int req_handle, API_VAL *pv, int index)
Definition: cci_stub.c:1143
bool has_resultset
Definition: cci_stub.c:127
static int ci_stmt_clear_batch_impl(COMMON_API_STRUCTURE *stmt)
Definition: cci_stub.c:4543
static void opool_destroy(API_OBJECT_RESULTSET_POOL *poo)
Definition: cci_stub.c:3193
API_OBJECT_RESULTSET_POOL ifs
Definition: cci_stub.c:223
int hash_insert(hash_table *ht, void *elem)
Definition: api_util.c:275
static int xcol_copy(CI_COLLECTION col, CI_COLLECTION *rcol)
Definition: cci_stub.c:4057
static API_RESULTSET_META_IFS ORMETA_IFS_
Definition: cci_stub.c:2702
void * ptr
Definition: cci_stub.c:188
static int ci_batch_res_query_count_impl(COMMON_API_STRUCTURE *br, int *count)
Definition: cci_stub.c:5301
int bh_root_release(int rrid)
Definition: api_handle.c:871
#define ER_INTERFACE_NOT_EXECUTED
Definition: error_code.h:1182
int req_handle
Definition: cci_stub.c:216
static int api_col_update(API_COLLECTION *col, long pos, CI_TYPE type, void *ptr, size_t size)
Definition: cci_stub.c:3633
int(* bind_graft)(BH_INTERFACE *ifs, BH_BIND *bind, BH_BIND *on_bind)
Definition: api_handle.h:66
void hash_destroy(hash_table *ht, ht_destroyf dtor)
Definition: api_util.c:198
static int opool_oid_get_classname(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid, char *name, size_t size)
Definition: cci_stub.c:3182
#define ER_INTERFACE_DBMS
Definition: error_code.h:1173
size_t len
Definition: cci_stub.c:189
COMMON_API_STRUCTURE_HEADER
Definition: cci_stub.c:96
static int ci_conn_connect_impl(COMMON_API_STRUCTURE *conn, const char *host, unsigned short port, const char *databasename, const char *user_name, const char *password)
Definition: cci_stub.c:4202
static int opool_ght_keyf(void *elem, void **rk)
Definition: cci_stub.c:3474
int hash_lookup(hash_table *ht, void *key, void **relem)
Definition: api_util.c:233
int(* lookup)(BH_INTERFACE *ifs, BIND_HANDLE bh, BH_BIND **bind)
Definition: api_handle.h:62
static int api_ores_update_value(API_RESULTSET *res, int index, CI_TYPE type, void *addr, size_t len)
Definition: cci_stub.c:2900
int bh_root_lock(int rrid, BH_INTERFACE **bhifs)
Definition: api_handle.c:908
char * name
Definition: cci_stub.c:2921
COMMON_API_STRUCTURE * parent
Definition: cci_stub.c:159
PARAMETER_META_IMPL PM
Definition: cci_stub.c:110
union api_val_cci_bind_s::@0 redirect
#define ER_INTERFACE_NOT_SUPPORTED_OPERATION
Definition: error_code.h:1177
int hash_delete(hash_table *ht, void *key, void **relem)
Definition: api_util.c:318
static void on_close_opool_res(RESULTSET_IMPL *impl, void *arg)
Definition: cci_stub.c:3283
int array_indexer_create(int nvalue, VALUE_INDEXER **rvi)
static int api_qres_fetch(API_RESULTSET *res, int offset, CI_FETCH_POSITION pos)
Definition: cci_stub.c:1532
#define API_CALLOC(n, s)
Definition: api_util.h:110
static int statement_execute(STATEMENT_IMPL *pstmt, T_CCI_ERROR *err_buf)
Definition: cci_stub.c:2242
#define ER_INTERFACE_BROKER
Definition: error_code.h:1199
void(* bh_destroyf)(BH_BIND *bind)
Definition: api_handle.h:31
bool opt_updatable_result
Definition: cci_stub.c:100
static void api_col_destroy(API_COLLECTION *col)
Definition: cci_stub.c:3776
void(* destroy)(VALUE_INDEXER *indexer, void(*df)(VALUE_AREA *va, API_VALUE *db))
Definition: api_common.h:225
VALUE_INDEXER * indexer
Definition: cci_stub.c:234
#define ER_INTERFACE_RESULTSET_NOT_UPDATABLE
Definition: error_code.h:1187
static int ci_stmt_execute_batch_impl(COMMON_API_STRUCTURE *stmt, CI_BATCH_RESULT *br)
Definition: cci_stub.c:4749
static void on_close_statement_res(RESULTSET_IMPL *impl, void *arg)
Definition: cci_stub.c:2427
API_COLLECTION_IFS * ifs
Definition: api_common.h:259
#define ER_INTERFACE_IS_BATCH_STATEMENT
Definition: error_code.h:1195
static void destroy_cci_object(CCI_OBJECT *obj)
Definition: cci_stub.c:3264
static int stmt_execute_batch_array(STATEMENT_IMPL *pstmt)
Definition: cci_stub.c:2551
static int opool_ht_comparef(void *key1, void *key2, int *r)
Definition: cci_stub.c:3378
CUBRID_API_FUNCTION_TABLE Cubrid_api_function_table
Definition: cci_stub.c:5491
BIND_HANDLE rm_handle
Definition: cci_stub.c:179
static int api_val_cursor_update(CI_CONNECTION conn, int req_handle, int offset, int index, API_VAL *av, T_CCI_ERROR *err_buf)
Definition: cci_stub.c:1441
bool deleted
Definition: cci_stub.c:215
static int complete_statement(STATEMENT_IMPL *pstmt)
Definition: cci_stub.c:2347
T_CCI_ERROR err_buf
Definition: cci_stub.c:227
BH_INTERFACE * bh
Definition: cci_stub.c:62
static int ci_stmt_get_parameter_impl(COMMON_API_STRUCTURE *stmt, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: cci_stub.c:5023
CI_CONNECTION conn
Definition: cci_stub.c:235
static int ci_conn_get_option_impl(COMMON_API_STRUCTURE *conn, CI_CONNECTION_OPTION option, void *arg, size_t size)
Definition: cci_stub.c:4330
static int ci_stmt_affected_rows_impl(COMMON_API_STRUCTURE *stmt, int *out)
Definition: cci_stub.c:5175
int bh_root_acquire(int *rrid, BH_ROOT_TYPE rt)
Definition: api_handle.c:817
static int ci_stmt_get_start_line_impl(COMMON_API_STRUCTURE *stmt, int *line)
Definition: cci_stub.c:5289
static int ci_stmt_set_option_impl(COMMON_API_STRUCTURE *stmt, CI_STATEMENT_OPTION option, void *arg, size_t size)
Definition: cci_stub.c:4842
static int get_value_from_tset(T_CCI_U_TYPE utype, T_CCI_SET tset, CI_TYPE type, CI_CONNECTION conn, int i, API_VAL **pv)
Definition: cci_stub.c:1283
static int ci_get_connection_opool_impl(COMMON_API_STRUCTURE *pst, API_OBJECT_RESULTSET_POOL **rpool)
Definition: cci_stub.c:5470
#define ER_INTERFACE_NOT_ENOUGH_DATA_SIZE
Definition: error_code.h:1184
static int complete_connection(CONNECTION_IMPL *impl)
Definition: cci_stub.c:547
static int ci_stmt_prepare_impl(COMMON_API_STRUCTURE *stmt, const char *sql, size_t len)
Definition: cci_stub.c:4876
int(* bind_get_next_sibling)(BH_INTERFACE *ifs, BH_BIND *bind, BH_BIND **psibling)
Definition: api_handle.h:68
static int ci_conn_set_option_impl(COMMON_API_STRUCTURE *conn, CI_CONNECTION_OPTION option, void *arg, size_t size)
Definition: cci_stub.c:4272
STATEMENT_IMPL * bptr
Definition: cci_stub.c:79
#define ER_INTERFACE_IS_NOT_PREPARED_STATEMENT
Definition: error_code.h:1194
RESULTSET_IMPL * pres
Definition: cci_stub.c:2928
void(* on_close)(RESULTSET_IMPL *pres, void *arg)
Definition: cci_stub.c:167
static int api_ores_delete_row(API_RESULTSET *res)
Definition: cci_stub.c:2805
#define ER_INTERFACE_INVALID_NAME
Definition: error_code.h:1186
static int api_qres_get_value(API_RESULTSET *res, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *is_null)
Definition: cci_stub.c:1670
static void xoid2oidstr(const CI_OID *xoid, char *oidbuf)
Definition: cci_stub.c:3302
struct VALUE_AREA VALUE_AREA
Definition: api_common.h:42
#define ER_INTERFACE_HAS_NO_RESULT_SET
Definition: error_code.h:1181
static int ci_stmt_get_first_error_impl(COMMON_API_STRUCTURE *stmt, int *line, int *col, int *errcode, char *err_msg, size_t size)
Definition: cci_stub.c:5248
static int xcol_to_cci_set(CI_COLLECTION col, T_CCI_SET *tset)
Definition: cci_stub.c:3898
CCI_OBJECT_POOL * pool
Definition: cci_stub.c:218
static int api_col_get_elem_domain_info(API_COLLECTION *col, long pos, CI_TYPE *type, int *precision, int *scale)
Definition: cci_stub.c:3701
BIND_HANDLE conn
Definition: api_common.h:258
CI_CONNECTION conn
Definition: cci_stub.c:161
VALUE_INDEXER * indexer
Definition: cci_stub.c:2440
static int opool_oid_delete(API_OBJECT_RESULTSET_POOL *poo, CI_OID *oid)
Definition: cci_stub.c:3148
int(* oid_delete)(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid)
Definition: api_common.h:171
static int api_ormeta_get_info(API_RESULTSET_META *rm, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size)
Definition: cci_stub.c:2686
char oid_buf[32]
Definition: cci_stub.c:205
static int add_batch_params_mapf(void *arg, int index, VALUE_AREA *va, API_VALUE *val)
Definition: cci_stub.c:2474
static int ci_stmt_execute_immediate_impl(COMMON_API_STRUCTURE *stmt, char *sql, size_t len, CI_RESULTSET *rs, int *r)
Definition: cci_stub.c:4599
static void api_val_cci_bind_init(API_VAL_CCI_BIND *bind, CI_CONNECTION conn, int flag)
Definition: cci_stub.c:1107
static int api_val_cci_bind_bind(CI_TYPE type, void *ptr, int len, API_VAL_CCI_BIND *bind)
Definition: cci_stub.c:899
static int opool_create(CONNECTION_IMPL *pconn, CCI_OBJECT_POOL **rpool)
Definition: cci_stub.c:3506
static void api_val_dtor(VALUE_AREA *va, API_VALUE *val)
Definition: cci_stub.c:586
static int add_batch_params_restore_mapf(void *arg, int index, VALUE_AREA *va, API_VALUE *val)
Definition: cci_stub.c:2452
#define ER_INTERFACE_CANNOT_BATCH_EXECUTE
Definition: error_code.h:1192
#define assert(x)
#define ER_INTERFACE_GENERIC
Definition: error_code.h:1179
static int get_value_from_api_val(const API_VAL *pv, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: cci_stub.c:739
bool got_rm_handle
Definition: cci_stub.c:178
static int api_qrmeta_get_info(API_RESULTSET_META *rm, int index, CI_RMETA_INFO_TYPE type, void *arg, size_t size)
Definition: cci_stub.c:2036
T_CCI_CUBRID_STMT cmd_type
Definition: cci_stub.c:181
int(* bind_to_handle)(BH_INTERFACE *ifs, BH_BIND *bind, BIND_HANDLE *bh)
Definition: api_handle.h:63
static void resultset_impl_dtor(BH_BIND *bind)
Definition: cci_stub.c:1986
static void init_statement_impl(STATEMENT_IMPL *pstmt, CONNECTION_IMPL *pconn)
Definition: cci_stub.c:2216
static int ci_stmt_get_option_impl(COMMON_API_STRUCTURE *stmt, CI_STATEMENT_OPTION option, void *arg, size_t size)
Definition: cci_stub.c:4798
#define ER_INTERFACE_NO_MORE_RESULT
Definition: error_code.h:1183
static API_COLLECTION_IFS COL_IFS_
Definition: cci_stub.c:3783
#define dlisth_delete(h_)
Definition: api_util.h:50
static int ci_stmt_get_parameter_metadata_impl(COMMON_API_STRUCTURE *stmt, CI_PARAMETER_METADATA *r)
Definition: cci_stub.c:4992
BH_INTERFACE * bh
Definition: cci_stub.c:162
static int api_col_insert(API_COLLECTION *col, long pos, CI_TYPE type, void *ptr, size_t size)
Definition: cci_stub.c:3579
static int api_qres_clear_updates(API_RESULTSET *res)
Definition: cci_stub.c:1593
static int ci_batch_res_get_result_impl(COMMON_API_STRUCTURE *br, int index, int *ret, int *nr)
Definition: cci_stub.c:5318
static int ci_create_connection_impl(CI_CONNECTION *conn)
Definition: cci_stub.c:4129
static API_RESULTSET_IFS ORES_IFS_
Definition: cci_stub.c:3079
static int api_ores_clear_updates(API_RESULTSET *res)
Definition: cci_stub.c:2783
static int lazy_bind_qres_rmeta(RESULTSET_IMPL *pres)
Definition: cci_stub.c:1471
static void api_val_cci_bind_clear(API_VAL_CCI_BIND *bind)
Definition: cci_stub.c:1120
hash_table * ght
Definition: cci_stub.c:226
static int rv
Definition: area_alloc.c:52
struct API_VALUE API_VALUE
Definition: api_common.h:43
int(* map)(VALUE_INDEXER *indexer, int(*mapf)(void *, int, VALUE_AREA *, API_VALUE *), void *arg)
Definition: api_common.h:222
CI_TYPE type
Definition: cci_stub.c:187
static int ci_stmt_get_resultset_impl(COMMON_API_STRUCTURE *stmt, CI_RESULTSET *r)
Definition: cci_stub.c:5149
static int api_qres_tell(API_RESULTSET *res, int *offset)
Definition: cci_stub.c:1577
static int create_resultset_impl(CI_CONNECTION conn, BH_INTERFACE *bh, int req_handle, T_CCI_ERROR *err_buf, COMMON_API_STRUCTURE *parent, bool updatable, void *arg, void(*on_close)(RESULTSET_IMPL *, void *), API_RESULTSET_IFS *resifs, API_RESULTSET_META_IFS *rmifs, RESULTSET_IMPL **rpres)
Definition: cci_stub.c:1923
#define NULL
Definition: freelistheap.h:34
int str_to_int32(int *ret_p, char **end_p, const char *str_p, int base)
Definition: porting.c:2346
static void api_qres_destroy(API_RESULTSET *res)
Definition: cci_stub.c:1888
int curr_query_result_index
Definition: cci_stub.c:132
static int lazy_bind_pstmt_pmeta(STATEMENT_IMPL *pstmt)
Definition: cci_stub.c:2163
#define ER_INTERFACE_IS_PREPARED_STATEMENT
Definition: error_code.h:1193
static int api_col_length(API_COLLECTION *col, int *len)
Definition: cci_stub.c:3558
static int ci_stmt_add_batch_query_impl(COMMON_API_STRUCTURE *stmt, const char *sql, size_t len)
Definition: cci_stub.c:4459
int(* oid_get_classname)(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid, char *name, size_t size)
Definition: api_common.h:172
if(extra_options)
Definition: dynamic_load.c:958
static int opool_ht_keyf(void *elem, void **rk)
Definition: cci_stub.c:3442
static int api_ormeta_get_count(API_RESULTSET_META *rm, int *count)
Definition: cci_stub.c:2660
#define err(fd,...)
Definition: porting.h:431
static int bind_api_structure(BH_INTERFACE *bh, COMMON_API_STRUCTURE *s, COMMON_API_STRUCTURE *parent, BIND_HANDLE *handle)
Definition: cci_stub.c:380
static int ci_pmeta_get_info_impl(COMMON_API_STRUCTURE *pmeta, int index, CI_PMETA_INFO_TYPE type, void *arg, size_t size)
Definition: cci_stub.c:5404
static int api_qres_update_value(API_RESULTSET *res, int index, CI_TYPE type, void *addr, size_t len)
Definition: cci_stub.c:1768
static void statement_impl_dtor(BH_BIND *bind)
Definition: cci_stub.c:2189
static int api_qres_delete_row(API_RESULTSET *res)
Definition: cci_stub.c:1652
static int ci_stmt_set_parameter_impl(COMMON_API_STRUCTURE *stmt, int index, CI_TYPE type, void *val, size_t size)
Definition: cci_stub.c:5074
T_CCI_BIT bit_val
Definition: cci_stub.c:201
static int ci_err_set_impl(int err_code)
Definition: cci_stub.c:4186
static API_RESULTSET_META_IFS QRMETA_IFS_
Definition: cci_stub.c:2152
BIND_HANDLE res_handle
Definition: cci_stub.c:128
#define API_FREE(p)
Definition: api_util.h:112
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
API_VAL_CCI_BIND * binds
Definition: cci_stub.c:2932
static int ci_conn_create_statement_impl(COMMON_API_STRUCTURE *conn, CI_STATEMENT *stmt)
Definition: cci_stub.c:4239
T_CCI_A_TYPE atype
Definition: cci_stub.c:196
int(* check)(VALUE_INDEXER *indexer, int index, CHECK_PURPOSE pup)
Definition: api_common.h:218
CONNECTION_IMPL * pconn
Definition: cci_stub.c:224
static int err_from_cci(int err)
Definition: cci_stub.c:415
int(* delete)(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **rval)
Definition: api_common.h:224
static int api_ores_apply_update(API_RESULTSET *res)
Definition: cci_stub.c:2976
bool got_pm_handle
Definition: cci_stub.c:111
static int api_ores_tell(API_RESULTSET *res, int *offset)
Definition: cci_stub.c:2761
static T_CCI_U_TYPE type_to_cci_u_type(CI_TYPE type)
Definition: cci_stub.c:675
static int opool_ht_hashf(void *key, unsigned int *rv)
Definition: cci_stub.c:3423
static void opool_ht_elem_dtor(void *elem)
Definition: cci_stub.c:3460
static int api_ores_get_resultset_metadata(API_RESULTSET *res, API_RESULTSET_META **rimpl)
Definition: cci_stub.c:2714
static int rc
Definition: serial.c:50
#define API_VAL_CCI_BIND_FLAG_SET
Definition: cci_stub.c:210
static int api_col_get_elem(API_COLLECTION *col, long pos, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: cci_stub.c:3746
T_CCI_DATE data_val
Definition: cci_stub.c:202
static int api_col_delete(API_COLLECTION *col, long pos)
Definition: cci_stub.c:3668
T_CCI_COL_INFO * col_info
Definition: cci_stub.c:182
CI_TYPE type
Definition: cci_stub.c:233
static int api_qres_apply_update(API_RESULTSET *res)
Definition: cci_stub.c:1867
CCI_OBJECT_POOL * opool
Definition: cci_stub.c:67
CUBRID_STMT_TYPE
Definition: cas_dbms_util.h:40
static int ci_stmt_get_query_type_impl(COMMON_API_STRUCTURE *stmt, CUBRID_STMT_TYPE *type)
Definition: cci_stub.c:5277
int(* get)(VALUE_INDEXER *indexer, int index, VALUE_AREA **rva, API_VALUE **rv)
Definition: api_common.h:220
CI_CONNECTION conn
Definition: cci_stub.c:60
#define strlen(s1)
Definition: intl_support.c:43
static int get_type_value_size(CI_TYPE type, int *len)
Definition: cci_stub.c:828
int(* get_object_resultset)(API_OBJECT_RESULTSET_POOL *pool, CI_OID *oid, API_RESULTSET **rres)
Definition: api_common.h:170
T_CCI_SET tset
Definition: cci_stub.c:206
int list_indexer_create(VALUE_INDEXER **rvi)
static int api_qres_get_value_by_name(API_RESULTSET *res, const char *name, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: cci_stub.c:1738
static int ci_conn_commit_impl(COMMON_API_STRUCTURE *conn)
Definition: cci_stub.c:4394
T_CCI_QUERY_RESULT * query_result
Definition: cci_stub.c:131
RESULTSET_IMPL * pres
Definition: cci_stub.c:217
int(* insert)(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *dval)
Definition: api_common.h:223
static int ci_stmt_next_result_impl(COMMON_API_STRUCTURE *stmt, bool *exist_result)
Definition: cci_stub.c:5195
static int statement_get_reshandle_or_affectedrows(BH_INTERFACE *bh, STATEMENT_IMPL *pstmt)
Definition: cci_stub.c:2292
static int api_qres_get_resultset_metadata(API_RESULTSET *res, API_RESULTSET_META **rimpl)
Definition: cci_stub.c:1501
static void connection_impl_dtor(BH_BIND *bind)
Definition: cci_stub.c:491
static CI_TYPE cci_u_type_to_type(T_CCI_U_TYPE utype)
Definition: cci_stub.c:612
T_CCI_COL_INFO * col_info
Definition: cci_stub.c:115
static int api_ores_get_value(API_RESULTSET *res, int index, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *is_null)
Definition: cci_stub.c:2844
static void api_ores_destroy(API_RESULTSET *res)
Definition: cci_stub.c:3073
static void opool_ght_elem_dtor(void *elem)
Definition: cci_stub.c:3492
static int xcol_elem_cci_bind_mapf(void *arg, int index, VALUE_AREA *va, API_VALUE *av)
Definition: cci_stub.c:3871
void(* destroy)(API_OBJECT_RESULTSET_POOL *pool)
Definition: api_common.h:173
#define ER_INTERFACE_PARAM_IS_NOT_SET
Definition: error_code.h:1189
int i
Definition: dynamic_load.c:954
#define API_MALLOC(s)
Definition: api_util.h:111
static int cci_set_to_xcol(CI_CONNECTION conn, T_CCI_SET tset, CI_COLLECTION *col)
Definition: cci_stub.c:3998
CONNECTION_IMPL * pconn
Definition: cci_stub.c:97
BATCH_ARY_ITEM * bai
Definition: cci_stub.c:2439
#define API_VAL_CCI_BIND_FLAG_GET
Definition: cci_stub.c:209
RESULTSET_META_IMPL RM
Definition: cci_stub.c:153
API_COLLECTION col
Definition: cci_stub.c:232
static int ores_apply_updatef(void *arg, int index, VALUE_AREA *va, API_VALUE *v)
Definition: cci_stub.c:2944
static void init_connection_impl(CONNECTION_IMPL *impl, int rid, CI_CONNECTION conn, BH_INTERFACE *bh, int conn_handle, CCI_OBJECT_POOL *pool)
Definition: cci_stub.c:521
#define dlisth_is_empty(h)
Definition: api_util.h:48
int(* destroy_handle)(BH_INTERFACE *ifs, BIND_HANDLE bh)
Definition: api_handle.h:61
int(* alloc_handle)(BH_INTERFACE *ifs, BH_BIND *bind, BIND_HANDLE *bh)
Definition: api_handle.h:60
enum impl_handle_type IMPL_HANDLE_TYPE
Definition: cci_stub.c:40
static int oidstr2xoid(const char *oidstr, CI_CONNECTION conn, CI_OID *xoid)
Definition: cci_stub.c:3326
CI_OID xoid
Definition: cci_stub.c:214
#define dlisth_init(h)
Definition: api_util.h:42
static int api_qrmeta_get_count(API_RESULTSET_META *rm, int *count)
Definition: cci_stub.c:2014
UINT64 BIND_HANDLE
Definition: api_handle.h:28
hash_table * ht
Definition: cci_stub.c:225
static void xcol_elem_dtor(VALUE_AREA *va, API_VALUE *av)
Definition: cci_stub.c:3800
int(* set)(VALUE_INDEXER *indexer, int index, VALUE_AREA *va, API_VALUE *val)
Definition: api_common.h:221
char sql[1]
Definition: cci_stub.c:85
static int set_value_to_api_val(API_VAL *pv, CI_TYPE type, void *addr, size_t len)
Definition: cci_stub.c:782
static int ci_batch_res_get_error_impl(COMMON_API_STRUCTURE *br, int index, int *err_code, char *err_msg, size_t buf_size)
Definition: cci_stub.c:5348
T_CCI_A_TYPE atype
Definition: cci_stub.c:2923
static API_RESULTSET_IFS QRES_IFS_
Definition: cci_stub.c:1893
static int ci_conn_close_impl(COMMON_API_STRUCTURE *conn)
Definition: cci_stub.c:4224
VALUE_INDEXER_IFS * ifs
Definition: api_common.h:208
static int ci_stmt_get_resultset_metadata_impl(COMMON_API_STRUCTURE *stmt, CI_RESULTSET_METADATA *r)
Definition: cci_stub.c:4945
BIND_HANDLE pm_handle
Definition: cci_stub.c:112
static char * host
#define ER_INTERFACE_INVALID_ARGUMENT
Definition: error_code.h:1174
#define API_EXEC_POST(has_result)
Definition: cci_stub.c:4577
int(* length)(VALUE_INDEXER *indexer, int *len)
Definition: api_common.h:219
VALUE_INDEXER * params
Definition: cci_stub.c:116
static int ci_stmt_register_out_parameter_impl(COMMON_API_STRUCTURE *stmt, int index)
Definition: cci_stub.c:4933
static int opool_get_object_resultset(API_OBJECT_RESULTSET_POOL *poo, CI_OID *oid, API_RESULTSET **rres)
Definition: cci_stub.c:3100
static int stmt_complete_batch(STATEMENT_IMPL *pstmt)
Definition: cci_stub.c:2595
API_VAL * ary[1]
Definition: cci_stub.c:91
#define ER_INTERFACE_CANNOT_CLEAR_BATCH
Definition: error_code.h:1191
T_CCI_ERROR * err_buf
Definition: cci_stub.c:164
BATCH_RESULT_IMPL BR
Definition: cci_stub.c:140
static int ci_stmt_get_next_error_impl(COMMON_API_STRUCTURE *stmt, int *line, int *col, int *errcode, char *err_msg, size_t size)
Definition: cci_stub.c:5265
static int api_ores_get_value_by_name(API_RESULTSET *res, const char *name, CI_TYPE type, void *addr, size_t len, size_t *outlen, bool *isnull)
Definition: cci_stub.c:2873
VALUE_INDEXER * updated_values
Definition: cci_stub.c:174
static void xcol_destroy(CI_COLLECTION col)
Definition: cci_stub.c:3851
const char ** p
Definition: dynamic_load.c:945
static int ci_conn_rollback_impl(COMMON_API_STRUCTURE *conn)
Definition: cci_stub.c:4416
BIND_HANDLE bres_handle
Definition: cci_stub.c:141
int hash_new(int bucket_sz, ht_hashf hashf, ht_keyf keyf, ht_comparef comparef, hash_table **rht)
Definition: api_util.c:166
static int xcol_create(CI_TYPE type, CI_CONNECTION conn, CI_COLLECTION *rcol)
Definition: cci_stub.c:3818
STATEMENT_IMPL * bptr
Definition: cci_stub.c:73
#define ER_INTERFACE_NO_MORE_MEMORY
Definition: error_code.h:1198
static int ci_stmt_execute_impl(COMMON_API_STRUCTURE *stmt, CI_RESULTSET *rs, int *r)
Definition: cci_stub.c:4672
T_CCI_ERROR err_buf
Definition: cci_stub.c:58
static int ci_stmt_add_batch_impl(COMMON_API_STRUCTURE *stmt)
Definition: cci_stub.c:4495
#define API_EXEC_PRE()
Definition: cci_stub.c:4558
char * value
Definition: cci_stub.c:2922
static int ci_pmeta_get_count_impl(COMMON_API_STRUCTURE *pmeta, int *count)
Definition: cci_stub.c:5385
CI_CONNECTION conn
Definition: cci_stub.c:194
T_CCI_CUBRID_STMT cmd_type
Definition: cci_stub.c:114
static int qres_apply_updatef(void *arg, int index, VALUE_AREA *va, API_VALUE *v)
Definition: cci_stub.c:1845