CUBRID Engine  latest
db_vdb.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  * db_vdb.c - Stubs for SQL interface functions.
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <sys/timeb.h>
31 #include <time.h>
32 #include <assert.h>
33 
34 #include "authenticate.h"
35 #include "db.h"
36 #include "dbi.h"
37 #include "db_query.h"
38 #include "error_manager.h"
39 #include "chartype.h"
40 #include "system_parameter.h"
41 #include "environment_variable.h"
42 #include "memory_alloc.h"
43 #include "parser.h"
44 #include "parser_message.h"
45 #include "object_domain.h"
46 #include "object_primitive.h"
47 #include "schema_manager.h"
48 #include "view_transform.h"
49 #include "execute_statement.h"
50 #include "locator_cl.h"
51 #include "server_interface.h"
52 #include "api_compat.h"
53 #include "network_interface_cl.h"
54 #include "transaction_cl.h"
55 #include "dbtype.h"
56 #include "util_func.h"
57 #include "xasl.h"
58 
59 #define BUF_SIZE 1024
60 
61 #define MAX_SERVER_TIME_CACHE 60 /* secs */
62 
63 enum
64 {
69 };
70 
71 static struct timeb base_server_timeb = { 0, 0, 0, 0 };
72 static struct timeb base_client_timeb = { 0, 0, 0, 0 };
73 
74 static int get_dimension_of (PT_NODE ** array);
75 static DB_SESSION *db_open_local (void);
76 static DB_SESSION *initialize_session (DB_SESSION * session);
77 static int db_execute_and_keep_statement_local (DB_SESSION * session, int stmt_ndx, DB_QUERY_RESULT ** result);
78 static DB_OBJLIST *db_get_all_chosen_classes (int (*p) (MOBJ o));
79 static int is_vclass_object (MOBJ class_);
80 static char *get_reasonable_predicate (DB_ATTRIBUTE * att);
81 static void update_execution_values (PARSER_CONTEXT * parser, int result, CUBRID_STMT_TYPE statement_type);
82 static void copy_execution_values (EXECUTION_STATE_VALUES * source, EXECUTION_STATE_VALUES * destination);
83 static int values_list_to_values_array (PARSER_CONTEXT * parser, PT_NODE * values_list, DB_VALUE_ARRAY * values_array);
84 static int set_prepare_info_into_list (DB_PREPARE_INFO * prepare_info, PT_NODE * statement);
85 static PT_NODE *char_array_to_name_list (PARSER_CONTEXT * parser, char **names, int length);
86 static int do_process_prepare_statement (DB_SESSION * session, PT_NODE * statement);
87 static int do_get_prepared_statement_info (DB_SESSION * session, int stmt_idx);
88 static int do_set_user_host_variables (DB_SESSION * session, PT_NODE * using_list);
90 static int do_recompile_and_execute_prepared_statement (DB_SESSION * session, PT_NODE * statement,
91  DB_QUERY_RESULT ** result);
92 static int do_process_deallocate_prepare (DB_SESSION * session, PT_NODE * statement);
93 static bool is_allowed_as_prepared_statement (PT_NODE * node);
95 static bool db_check_limit_need_recompile (PARSER_CONTEXT * parser, PT_NODE * statement, int xasl_flag);
96 
98 static PT_NODE *pt_has_modified_class_helper (PARSER_CONTEXT * parser, PT_NODE * tree, void *arg, int *continue_walk);
99 static bool db_can_execute_statement_with_autocommit (PARSER_CONTEXT * parser, PT_NODE * statement);
100 
101 /*
102  * get_dimemsion_of() - returns the number of elements of a null-terminated
103  * pointer array
104  * returns : number of elements of array
105  * array (in): a null-terminated array of pointers
106  */
107 static int
109 {
110  int rank = 0;
111 
112  if (!array)
113  {
114  return rank;
115  }
116 
117  while (*array++)
118  {
119  rank++;
120  }
121 
122  return rank;
123 }
124 
125 /*
126  * db_statement_count() - This function returns the number of statements
127  * in a session.
128  * return : number of statements in the session
129  * session(in): compiled session
130  */
131 int
133 {
134  int retval;
135 
136  if (session == NULL)
137  {
138  return 0;
139  }
140 
141  retval = get_dimension_of (session->statements);
142 
143  return (retval);
144 }
145 
146 /*
147  * db_open_local() - Starts a new SQL empty compile session
148  * returns : new DB_SESSION
149  */
150 static DB_SESSION *
152 {
153  DB_SESSION *session = NULL;
154 
155  session = (DB_SESSION *) malloc (sizeof (DB_SESSION));
156  if (session == NULL)
157  {
159  return NULL;
160  }
161 
162  session->parser = parser_create_parser ();
163  if (session->parser == NULL)
164  {
165  free_and_init (session);
166  return NULL;
167  }
168 
169  assert (session->parser->query_id == NULL_QUERY_ID);
170 
171  session->stage = NULL;
172  session->dimension = 0;
173  session->stmt_ndx = 0;
174  session->type_list = NULL;
175  session->line_offset = 0;
176  session->include_oid = DB_NO_OIDS;
177  session->statements = NULL;
178  session->is_subsession_for_prepared = false;
179  session->next = NULL;
180 
181  return session;
182 }
183 
184 /*
185  * initialize_session() -
186  * returns : DB_SESSION *, NULL if fails
187  * session(in/out):
188  */
189 static DB_SESSION *
191 {
192  assert (session != NULL && session->statements != NULL);
193 
194  session->dimension = get_dimension_of (session->statements);
195 
196  return session;
197 }
198 
199 /*
200  * db_open_buffer_local() - Please refer to the db_open_buffer() function
201  * returns : new DB_SESSION
202  * buffer(in): contains query text to be compiled
203  */
204 DB_SESSION *
205 db_open_buffer_local (const char *buffer)
206 {
207  DB_SESSION *session;
208 
209  CHECK_1ARG_NULL (buffer);
210 
211  session = db_open_local ();
212 
213  if (session)
214  {
215  session->statements = parser_parse_string_with_escapes (session->parser, buffer, false);
216  if (session->statements)
217  {
218  return initialize_session (session);
219  }
220  }
221 
222  return session;
223 }
224 
225 /*
226  * db_open_buffer() - Starts a new SQL compile session on a nul terminated
227  * string
228  * return:new DB_SESSION
229  * buffer(in) : contains query text to be compiled
230  */
231 DB_SESSION *
232 db_open_buffer (const char *buffer)
233 {
234  DB_SESSION *session;
235 
236  CHECK_1ARG_NULL (buffer);
238 
239  session = db_open_buffer_local (buffer);
240 
241  return session;
242 }
243 
244 
245 /*
246  * db_open_file() - Starts a new SQL compile session on a query file
247  * returns : new DB_SESSION
248  * file(in): contains query text to be compiled
249  */
250 DB_SESSION *
251 db_open_file (FILE * file)
252 {
253  DB_SESSION *session;
254 
256 
257  session = db_open_local ();
258  if (session)
259  {
260  session->statements = parser_parse_file (session->parser, file);
261  if (session->statements)
262  {
263  return initialize_session (session);
264  }
265  }
266 
267  return session;
268 }
269 
270 /*
271  * db_make_session_for_one_statement_execution() -
272  * return:
273  * file(in) :
274  */
275 DB_SESSION *
277 {
278  DB_SESSION *session;
279 
281 
282  session = db_open_local ();
283  if (session)
284  {
285  pt_init_one_statement_parser (session->parser, file);
287  }
288 
289  return session;
290 }
291 
292 /*
293  * db_parse_one_statement() -
294  * return:
295  * session(in) :
296  */
297 int
299 {
300  if (session->dimension > 0)
301  {
302  /* check if this statement is skipped */
303  if (session->type_list)
304  {
305  db_free_query_format (session->type_list[0]);
306  }
307  if (session->statements[0])
308  {
309  parser_free_tree (session->parser, session->statements[0]);
310  session->statements[0] = NULL;
311  }
312 
313  session->dimension = 0;
314  session->stmt_ndx = 0;
315 
316  session->parser->stack_top = 0;
317  if (session->stage)
318  {
319  session->stage[0] = StatementInitialStage;
320  }
321  }
322 
323  if (parse_one_statement (1) == 0 && !pt_has_error (session->parser) && session->parser->stack_top > 0
324  && session->parser->node_stack != NULL)
325  {
326  session->parser->statements = (PT_NODE **) parser_alloc (session->parser, 2 * sizeof (PT_NODE *));
327  if (session->parser->statements == NULL)
328  {
329  return -1;
330  }
331 
332  session->parser->statements[0] = session->parser->node_stack[0];
333  session->parser->statements[1] = NULL;
334 
335  session->statements = session->parser->statements;
336  session->dimension = get_dimension_of (session->statements);
337 
338  return session->dimension;
339  }
340  else
341  {
342  session->parser->statements = NULL;
343  return -1;
344  }
345 }
346 
347 /*
348  * db_get_parser_line_col() -
349  * return:
350  * session(in) :
351  * line(out) :
352  * col(out) :
353  */
354 int
355 db_get_parser_line_col (DB_SESSION * session, int *line, int *col)
356 {
357  if (line)
358  {
359  *line = session->parser->line;
360  }
361  if (col)
362  {
363  *col = session->parser->column;
364  }
365  return 0;
366 }
367 
368 /*
369  * db_open_file_name() - This functions allocates and initializes a session and
370  * parses the named file. Similar to db_open_file() except that it takes a
371  * name rather than a file handle.
372  * return : new session
373  * name(in): file name
374  */
375 DB_SESSION *
376 db_open_file_name (const char *name)
377 {
378  FILE *fp;
379  DB_SESSION *session;
380 
382 
383  session = db_open_local ();
384  if (session)
385  {
386  fp = fopen (name, "r");
387  if (fp != NULL)
388  {
389  session->statements = parser_parse_file (session->parser, fp);
390  fclose (fp);
391  }
392  if (session->statements)
393  {
394  return initialize_session (session);
395  }
396  }
397 
398  return session;
399 }
400 
401 static void
402 db_calculate_current_time (struct timeb *tb)
403 {
404  assert (tb != nullptr);
405 
406  // use chrono functions to populate timeb
407  time_t sec;
408  int millisec;
409  util_get_second_and_ms_since_epoch (&sec, &millisec);
410  tb->time = sec;
411  tb->millitm = (unsigned short) millisec;
412 }
413 
414 /*
415  * db_calculate_current_server_time () -
416  * return:
417  * parser(in) :
418  * server_info(in) :
419  */
420 static void
422 {
423 
424  struct tm *c_time_struct;
425  DB_DATETIME datetime;
426 
427  struct timeb curr_server_timeb;
428  struct timeb curr_client_timeb;
429  int diff_mtime;
430  int diff_time;
431 
432  if (base_server_timeb.time == 0)
433  {
434  return;
435  }
436 
437  db_calculate_current_time (&curr_client_timeb);
438  diff_time = (int) (curr_client_timeb.time - base_client_timeb.time);
439  diff_mtime = curr_client_timeb.millitm - base_client_timeb.millitm;
440 
441  if (diff_time > MAX_SERVER_TIME_CACHE)
442  {
443  base_server_timeb.time = 0;
444  }
445  else
446  {
447  curr_server_timeb.time = base_server_timeb.time;
448  curr_server_timeb.millitm = base_server_timeb.millitm;
449 
450  /* timeb.millitm is unsigned short, so should prevent underflow */
451  if (diff_mtime < 0)
452  {
453  curr_server_timeb.time--;
454  curr_server_timeb.millitm += 1000;
455  }
456 
457  curr_server_timeb.time += diff_time;
458  curr_server_timeb.millitm += diff_mtime;
459 
460  if (curr_server_timeb.millitm >= 1000)
461  {
462  curr_server_timeb.time++;
463  curr_server_timeb.millitm -= 1000;
464  }
465 
466  c_time_struct = localtime (&curr_server_timeb.time);
467  if (c_time_struct == NULL)
468  {
469  base_server_timeb.time = 0;
470  }
471  else
472  {
473  db_datetime_encode (&datetime, c_time_struct->tm_mon + 1, c_time_struct->tm_mday,
474  c_time_struct->tm_year + 1900, c_time_struct->tm_hour, c_time_struct->tm_min,
475  c_time_struct->tm_sec, curr_server_timeb.millitm);
476 
477  db_make_datetime (&parser->sys_datetime, &datetime);
478  db_make_timestamp (&parser->sys_epochtime, (DB_TIMESTAMP) curr_server_timeb.time);
479  }
480  }
481 }
482 
483 /*
484  * db_set_base_server_time() -
485  * return:
486  * server_info(in) :
487  */
488 static void
490 {
491  struct tm c_time_struct;
492  DB_TIME time_val;
493  DB_DATETIME *dt = db_get_datetime (db_val);
494 
495  time_val = dt->time / 1000; /* milliseconds to seconds */
496  db_tm_encode (&c_time_struct, &dt->date, &time_val);
497 
498  base_server_timeb.millitm = dt->time % 1000; /* set milliseconds */
499 
500  base_server_timeb.time = mktime (&c_time_struct);
502 }
503 
504 /*
505  * db_compile_statement_local() -
506  * return:
507  * session(in) :
508  */
509 int
511 {
513  int stmt_ndx;
514  PT_NODE *statement = NULL;
515  PT_NODE *statement_result = NULL;
516  DB_QUERY_TYPE *qtype, *q;
517  CUBRID_STMT_TYPE cmd_type;
518  int err;
519  static long seed = 0;
520 
521  /* obvious error checking - invalid parameter */
522  if (!session || !session->parser)
523  {
525  return er_errid ();
526  }
527  /* no statement was given in the session */
528  if (session->dimension == 0 || !session->statements)
529  {
530  /* if the parser already has something wrong - syntax error */
531  if (pt_has_error (session->parser))
532  {
533  pt_report_to_ersys (session->parser, PT_SYNTAX);
534  return er_errid ();
535  }
536 
538  return er_errid ();
539  }
540  /* check the end of statements */
541  if (session->stmt_ndx == session->dimension)
542  {
543  /* return 0 if all statement were compiled */
544  return 0;
545  }
546 
547  /* allocate memory for session->type_list and session->stage if not allocated */
548  if (session->type_list == NULL)
549  {
550  size_t size = session->dimension * sizeof (DB_QUERY_TYPE *) + session->dimension * sizeof (char);
551  void *p = malloc (size);
552  if (p == NULL)
553  {
556  }
557  (void) memset (p, 0, size);
558  session->type_list = (DB_QUERY_TYPE **) p;
559  session->stage = (char *) p + session->dimension * sizeof (DB_QUERY_TYPE *);
560  }
561 
562  /*
563  * Compilation Stage
564  */
565 
566  /* the statements in this session have been parsed without error and it is time to compile the next statement */
567  parser = session->parser;
568  stmt_ndx = session->stmt_ndx++;
569  statement = session->statements[stmt_ndx];
570  statement->flag.use_plan_cache = 0;
571  statement->flag.use_query_cache = 0;
572 
574 
575  /* check if the statement is already processed */
576  if (session->stage[stmt_ndx] >= StatementPreparedStage)
577  {
578  return stmt_ndx + 1;
579  }
580 
581  /* forget about any previous parsing errors, if any */
582  pt_reset_error (parser);
583 
584  /* get type list describing the output columns titles of the given query */
585  cmd_type = pt_node_to_cmd_type (statement);
586  qtype = NULL;
587  if (cmd_type == CUBRID_STMT_SELECT)
588  {
589  qtype = pt_get_titles (parser, statement);
590  /* to prevent a memory leak, register the query type list to session */
591  session->type_list[stmt_ndx] = qtype;
592  }
593  if (cmd_type == CUBRID_STMT_EXECUTE_PREPARE)
594  {
595  /* we don't actually have the statement which will be executed and we need to get some information about it from
596  * the server */
597  int err = do_get_prepared_statement_info (session, stmt_ndx);
598  if (err != NO_ERROR)
599  {
600  return err;
601  }
602  }
603  /* prefetch and lock classes to avoid deadlock */
604  (void) pt_class_pre_fetch (parser, statement);
605  if (pt_has_error (parser))
606  {
607  pt_report_to_ersys_with_statement (parser, PT_SYNTAX, statement);
608  return er_errid ();
609  }
610 
611  if (seed == 0)
612  {
613  srand48 (seed = (long) time (NULL));
614  }
615 
616  /* do semantic check for the statement */
617  statement_result = pt_compile (parser, statement);
618 
619  if (statement_result == NULL || pt_has_error (parser))
620  {
621  pt_report_to_ersys_with_statement (parser, PT_SEMANTIC, statement);
622  return er_errid ();
623  }
624  statement = statement_result;
625 
626  /* get type list describing the output columns titles of the given query */
627  if (cmd_type == CUBRID_STMT_SELECT)
628  {
629  /* for a select-type query of the form: SELECT * FROM class c we store into type_list the nice column headers:
630  * c.attr1 attr2 c.attr3 before they get fully resolved by mq_translate(). */
631  if (!qtype)
632  {
633  qtype = pt_get_titles (parser, statement);
634  /* to prevent a memory leak, register the query type list to session */
635  session->type_list[stmt_ndx] = qtype;
636  }
637  if (qtype)
638  {
639  /* NOTE, this is here on purpose. If something is busting because it tries to continue corresponding this
640  * type information and the list file columns after having jacked with the list file, by for example adding a
641  * hidden OID column, fix the something else. This needs to give the results as user views the query, ie
642  * related to the original text. It may guess wrong about attribute/column updatability. Thats what they
643  * asked for. */
644  qtype = pt_fillin_type_size (parser, statement, qtype, DB_NO_OIDS, false, false);
645 
646  /* check implicit oid included for excluding result cache */
647  for (q = qtype; q; q = q->next)
648  {
649  if (q->col_type == DB_COL_PATH)
650  {
651  statement->info.query.flag.do_not_cache = 1;
652  break;
653  }
654  }
655  }
656  }
657 
658  /* translate views or virtual classes into base classes */
659  statement_result = mq_translate (parser, statement);
660  if (!statement_result || pt_has_error (parser))
661  {
662  pt_report_to_ersys_with_statement (parser, PT_SEMANTIC, statement);
663  return er_errid ();
664  }
665  statement = statement_result;
666 
667  /* prefetch and lock translated real classes to avoid deadlock */
668  (void) pt_class_pre_fetch (parser, statement);
669  if (pt_has_error (parser))
670  {
671  pt_report_to_ersys_with_statement (parser, PT_SYNTAX, statement);
672  return er_errid ();
673  }
674 
675  /* validate include_oid setting in the session */
676  if (session->include_oid)
677  {
678  if (mq_updatable (parser, statement) == PT_UPDATABLE)
679  {
680  if (session->include_oid == DB_ROW_OIDS)
681  {
682  (void) pt_add_row_oid (parser, statement);
683  }
684  }
685  else
686  {
687  /* disallow OID column for non-updatable query */
688  session->include_oid = DB_NO_OIDS;
689  }
690  }
691 
692  /* so now, the statement is compiled */
693  session->statements[stmt_ndx] = statement;
694  session->stage[stmt_ndx] = StatementCompiledStage;
695 
696 
697  /*
698  * Preparation Stage
699  */
700 
701  statement->xasl_id = NULL; /* bullet proofing */
702 
703  /* New interface of do_prepare_statement()/do_execute_statment() is used only when the XASL cache is enabled. If it
704  * is disabled, old interface of do_statement() will be used instead. do_statement() makes a XASL everytime rather
705  * than using XASL cache. Also, it can be executed in the server without touching the XASL cache by calling
706  * prepare_and_execute_query(). */
708  {
709  if (session->is_subsession_for_prepared)
710  {
711  /* cast host variables to their expected domain, before XASL generation. */
712  session->parser->flag.set_host_var = 0;
714  if (err < 0)
715  {
716  if (pt_has_error (parser))
717  {
718  pt_report_to_ersys_with_statement (parser, PT_SEMANTIC, statement);
719  return er_errid ();
720  }
721  return err;
722  }
723  }
724 
725  /* now, prepare the statement by calling do_prepare_statement() */
726  err = do_prepare_statement (parser, statement);
727 #if 0
728  if (err == ER_QPROC_INVALID_XASLNODE)
729  {
730  /* There is a kind of problem in the XASL cache. It is possible when the cache entry was deleted by the
731  * other. In this case, retry to prepare once more (generate and stored the XASL again). */
732  statement->xasl_id = NULL;
733  er_clear ();
734  /* execute the statement by calling do_statement() */
735  err = do_prepare_statement (parser, statement);
736  }
737 #endif
738  if (err < 0)
739  {
740  if (pt_has_error (parser))
741  {
742  pt_report_to_ersys_with_statement (parser, PT_SEMANTIC, statement);
743  return er_errid ();
744  }
745  return err;
746  }
747  }
748 
749  /* so now, the statement is prepared */
750  session->stage[stmt_ndx] = StatementPreparedStage;
751 
752  return stmt_ndx + 1;
753 }
754 
755 /*
756  * db_compile_statement() - This function compiles the next statement in the
757  * session. The first compilation reports any syntax errors that occurred
758  * in the entire session.
759  * return: an integer that is the relative statement ID of the next statement
760  * within the session, with the first statement being statement number 1.
761  * If there are no more statements in the session (end of statements), 0 is
762  * returned. If an error occurs, the return code is negative.
763  * session(in) : session handle
764  */
765 int
767 {
768  int statement_id;
769 
770  er_clear ();
771 
773 
774  statement_id = db_compile_statement_local (session);
775 
776  return statement_id;
777 }
778 
779 /*
780  * db_rewind_statement() -
781  * return:
782  * session(in) :
783  */
784 void
786 {
787  if (session->dimension == session->stmt_ndx)
788  {
789  session->stmt_ndx = 1;
790  }
791 }
792 
793 /*
794  * db_session_is_last_statement() -
795  * return:
796  * session(in) :
797  */
798 int
800 {
801  assert (session->dimension > 0);
802  return session->dimension == session->stmt_ndx;
803 }
804 
805 /*
806  * db_set_client_cache_time() -
807  * return:
808  * session(in) :
809  * stmt_ndx(in) :
810  * cache_time(in) :
811  */
812 int
814 {
815  PT_NODE *statement;
816  int result = NO_ERROR;
817 
818  if (!session || !session->parser || session->dimension == 0 || !session->statements || stmt_ndx < 1
819  || stmt_ndx > session->dimension || !(statement = session->statements[stmt_ndx - 1]))
820  {
822  result = er_errid ();
823  }
824  else
825  {
826  if (cache_time)
827  {
828  statement->cache_time = *cache_time;
829  statement->flag.clt_cache_check = 1;
830  }
831  }
832 
833  return result;
834 }
835 
836 /*
837  * db_get_jdbccachehint() -
838  * return:
839  * session(in) :
840  * stmt_ndx(in) :
841  * life_time(out) :
842  */
843 bool
844 db_get_jdbccachehint (DB_SESSION * session, int stmt_ndx, int *life_time)
845 {
846  PT_NODE *statement;
847 
848  /* obvious error checking - invalid parameter */
849  if (!session || !session->parser || session->dimension == 0 || !session->statements || stmt_ndx < 1
850  || stmt_ndx > session->dimension || !(statement = session->statements[stmt_ndx - 1]))
851  {
852  return false;
853  }
854 
855  if (statement->info.query.q.select.hint & PT_HINT_JDBC_CACHE)
856  {
857  if (statement->info.query.q.select.jdbc_life_time)
858  {
859  if (life_time != NULL && statement->info.query.q.select.jdbc_life_time->info.name.original != NULL)
860  {
861  *life_time = atoi (statement->info.query.q.select.jdbc_life_time->info.name.original);
862  }
863  return true;
864  }
865  }
866 
867  return false;
868 }
869 
870 /*
871  * db_get_useplancache() -
872  * return:
873  * session(in) :
874  * stmt_ndx(in) :
875  * life_time(out) :
876  */
877 bool
878 db_get_cacheinfo (DB_SESSION * session, int stmt_ndx, bool * use_plan_cache, bool * use_query_cache)
879 {
880  PT_NODE *statement;
881 
882  /* obvious error checking - invalid parameter */
883  if (!session || !session->parser || session->dimension == 0 || !session->statements || stmt_ndx < 1
884  || stmt_ndx > session->dimension || !(statement = session->statements[stmt_ndx - 1]))
885  {
886  return false;
887  }
888 
889  if (use_plan_cache)
890  {
891  if (statement->flag.use_plan_cache)
892  {
893  *use_plan_cache = true;
894  }
895  else
896  {
897  *use_plan_cache = false;
898  }
899  }
900 
901  if (use_query_cache)
902  {
903  if (statement->flag.use_query_cache)
904  {
905  *use_query_cache = true;
906  }
907  else
908  {
909  *use_query_cache = false;
910  }
911  }
912 
913  return true;
914 }
915 
916 /*
917  * db_get_errors() - This function returns a list of errors that occurred during
918  * compilation. NULL is returned if no errors occurred.
919  * returns : compilation error list
920  * session(in): session handle
921  *
922  * note : A call to the db_get_next_error() function can be used to examine
923  * each error. You do not free this list of errors.
924  */
927 {
928  DB_SESSION_ERROR *result;
929 
930  if (!session || !session->parser)
931  {
932  result = NULL;
933  }
934  else
935  {
936  result = pt_get_errors (session->parser);
937  }
938 
939  return result;
940 }
941 
942 /*
943  * db_get_next_error() - This function returns the line and column number of
944  * the next error that was passed in the compilation error list.
945  * return : next error in compilation error list
946  * errors (in) : DB_SESSION_ERROR iterator
947  * line(out): source line number of error
948  * col(out): source column number of error
949  *
950  * note : Do not free this list of errors.
951  */
953 db_get_next_error (DB_SESSION_ERROR * errors, int *line, int *col)
954 {
955  DB_SESSION_ERROR *result;
956  int stmt_no;
957  const char *e_msg = NULL;
958 
959  if (!errors)
960  {
961  return NULL;
962  }
963 
964  result = pt_get_next_error (errors, &stmt_no, line, col, &e_msg);
965  if (e_msg)
966  {
968  }
969 
970  return result;
971 }
972 
973 /*
974  * db_get_warnings: This function returns a list of warnings that occurred
975  * during the compilation. NULL is returned if no warnings are found.
976  * A non-NULL return value indicates that one or more warnings occurred
977  * during compilation.
978  * returns: DB_SESSION_WARNING iterator if there were any compilation warnings,
979  * NULL, otherwise.
980  * session(in): session handle
981  *
982  * note : Do not free this list of warnings.
983  */
986 {
987  DB_SESSION_WARNING *result;
988 
989  if (!session || !session->parser)
990  {
991  result = NULL;
992  }
993  else
994  {
995  result = pt_get_warnings (session->parser);
996  }
997 
998  return result;
999 }
1000 
1001 /*
1002  * db_get_next_warning: This function returns the line and column number of the
1003  * next warning that was passed in the compilation warning list.
1004  * returns: DB_SESSION_WARNING iterator if there are more compilation warnings
1005  * NULL, otherwise.
1006  * warnings(in) : DB_SESSION_WARNING iterator
1007  * line(out): source line number of warning
1008  * col(out): source column number of warning
1009  *
1010  * note : Do not free this list of warnings.
1011  */
1013 db_get_next_warning (DB_SESSION_WARNING * warnings, int *line, int *col)
1014 {
1015  DB_SESSION_WARNING *result;
1016  int stmt_no;
1017  const char *e_msg = NULL;
1018 
1019  if (!warnings)
1020  {
1021  return NULL;
1022  }
1023 
1024  result = pt_get_next_error (warnings, &stmt_no, line, col, &e_msg);
1025  if (e_msg)
1026  {
1028  }
1029 
1030  return result;
1031 }
1032 
1033 /*
1034  * db_session_set_holdable () - mark session as holdable
1035  * return : void
1036  * session (in) :
1037  * holdable (in) :
1038  */
1039 void
1040 db_session_set_holdable (DB_SESSION * session, bool holdable)
1041 {
1042  if (session == NULL || session->parser == NULL)
1043  {
1044  return;
1045  }
1046  session->parser->flag.is_holdable = holdable ? 1 : 0;
1047 }
1048 
1049 /*
1050  * db_session_set_xasl_cache_pinned () - mark query as xasl cache pinned
1051  * return : void
1052  * session (in) :
1053  * is_pinned (in) :
1054  * recompile (in) :
1055  */
1056 void
1057 db_session_set_xasl_cache_pinned (DB_SESSION * session, bool is_pinned, bool recompile)
1058 {
1059  if (session == NULL || session->parser == NULL)
1060  {
1061  return;
1062  }
1063  session->parser->flag.is_xasl_pinned_reference = is_pinned ? 1 : 0;
1064  session->parser->flag.recompile_xasl_pinned = recompile ? 1 : 0;
1065 }
1066 
1067 /*
1068  * db_session_set_return_generated_keys () - return generated keys for insert
1069  * statements
1070  * return : void
1071  * session (in) :
1072  * return_generated_keys (in) :
1073  */
1074 void
1075 db_session_set_return_generated_keys (DB_SESSION * session, bool return_generated_keys)
1076 {
1077  if (session == NULL || session->parser == NULL)
1078  {
1079  return;
1080  }
1081  session->parser->flag.return_generated_keys = return_generated_keys ? 1 : 0;
1082 }
1083 
1084 /*
1085  * db_get_line_col_of_1st_error() - get the source line & column of first error
1086  * returns: 1 if there were any query compilation errors, 0, otherwise.
1087  * session(in) : contains the SQL query that has just been compiled
1088  * linecol(out): the source line & column of first error if any
1089  *
1090  * note : DO NOT USE THIS FUNCTION. USE db_get_errors & db_get_next_error
1091  * instead. This function is provided for the sole purpose of
1092  * facilitating conversion of old code.
1093  */
1094 int
1096 {
1097  if (!session || !session->parser || !pt_has_error (session->parser))
1098  {
1099  if (linecol)
1100  {
1101  linecol->err_lineno = linecol->err_posno = 0;
1102  }
1103  return 0;
1104  }
1105  else
1106  {
1107  PT_NODE *errors;
1108  int stmt_no;
1109  const char *msg;
1110 
1111  errors = pt_get_errors (session->parser);
1112  if (linecol)
1113  pt_get_next_error (errors, &stmt_no, &linecol->err_lineno, &linecol->err_posno, &msg);
1114  return 1;
1115  }
1116 }
1117 
1118 /*
1119  * db_number_of_input_markers() -
1120  * return : number of host variable input markers in statement
1121  * session(in): compilation session
1122  * stmt(in): statement number of compiled statement
1123  */
1124 int
1126 {
1128  PT_NODE *statement;
1129  int result = 0;
1130 
1131  if (!session || !(parser = session->parser) || !session->statements || stmt < 1 || stmt > session->dimension
1132  || !(statement = session->statements[stmt - 1]))
1133  {
1135  result = er_errid ();
1136  }
1137  else
1138  {
1139  result = parser->host_var_count;
1140  }
1141 
1142  return result;
1143 }
1144 
1145 /*
1146  * db_number_of_output_markers() -
1147  * return : number of host variable output markers in statement
1148  * session(in): compilation session
1149  * stmt(in): statement number of compiled statement
1150  */
1151 int
1153 {
1155  PT_NODE *statement;
1156  int result = 0;
1157 
1158  if (!session || !(parser = session->parser) || !session->statements || stmt < 1 || stmt > session->dimension
1159  || !(statement = session->statements[stmt - 1]))
1160  {
1162  result = er_errid ();
1163  }
1164  else
1165  {
1166  (void) parser_walk_tree (parser, statement, pt_count_output_markers, &result, NULL, NULL);
1167  }
1168 
1169  return result;
1170 }
1171 
1172 /*
1173  * db_get_input_markers() -
1174  * return : host variable input markers list in statement
1175  * session(in): compilation session
1176  * stmt(in): statement number of compiled statement
1177  */
1178 DB_MARKER *
1180 {
1182  PT_NODE *statement;
1183  DB_MARKER *result = NULL;
1184  PT_HOST_VARS *hv;
1185 
1186  if (!session || !(parser = session->parser) || !session->statements || stmt < 1 || stmt > session->dimension
1187  || !(statement = session->statements[stmt - 1]) || pt_has_error (parser))
1188  {
1190  result = NULL;
1191  }
1192  else
1193  {
1194  hv = pt_host_info (parser, statement);
1195  result = pt_get_input_host_vars (hv);
1196  pt_free_host_info (hv);
1197  }
1198 
1199  return result;
1200 }
1201 
1202 /*
1203  * db_get_output_markers() -
1204  * return : host variable output markers list in statement
1205  * session(in): compilation session
1206  * stmt(in): statement number of compiled statement
1207  */
1208 DB_MARKER *
1210 {
1212  PT_NODE *statement;
1213  DB_MARKER *result = NULL;
1214  PT_HOST_VARS *hv;
1215 
1216  if (!session || !(parser = session->parser) || !session->statements || stmt < 1 || stmt > session->dimension
1217  || !(statement = session->statements[stmt - 1]) || pt_has_error (parser))
1218  {
1220  result = NULL;
1221  }
1222  else
1223  {
1224  hv = pt_host_info (parser, statement);
1225  result = pt_get_output_host_vars (hv);
1226  pt_free_host_info (hv);
1227  }
1228 
1229  return result;
1230 }
1231 
1232 /*
1233  * db_marker_next: This function returns the next marker in the list
1234  * return : the next host variable (input/output) marker in the list or NULL
1235  * marker(in): DB_MARKER
1236  */
1237 DB_MARKER *
1239 {
1240  DB_MARKER *result = NULL;
1241 
1242  if (marker)
1243  {
1244  result = pt_node_next (marker);
1245  }
1246 
1247  return result;
1248 }
1249 
1250 /*
1251  * db_marker_index() - This function return the index of an host variable
1252  * (input/output) marker
1253  * return : index of an marker
1254  * marker(in): DB_MARKER
1255  */
1256 int
1258 {
1259  int result = -1;
1260 
1261  if (marker)
1262  {
1263  result = pt_host_var_index (marker);
1264  }
1265 
1266  return result;
1267 }
1268 
1269 /*
1270  * db_marker_domain() - This function returns the domain of an host variable
1271  * (input/output) marker
1272  * return : domain of marker
1273  * marker(in): DB_MARKER
1274  */
1275 DB_DOMAIN *
1277 {
1278  DB_DOMAIN *result = NULL;
1279 
1280  if (marker)
1281  {
1282  result = marker->expected_domain;
1283  if (result == NULL)
1284  {
1285  result = pt_node_to_db_domain (NULL, marker, NULL);
1286  }
1287  }
1288  /* it is safet to call pt_node_to_db_domain() without parser */
1289 
1290  return result;
1291 }
1292 
1293 /*
1294  * db_is_input_marker() - Returns true iff it is the host variable input marker
1295  * return : boolean
1296  * marker(in): DB_MARKER
1297  */
1298 bool
1300 {
1301  bool result = false;
1302 
1303  if (marker)
1304  {
1305  result = pt_is_input_hostvar (marker);
1306  }
1307 
1308  return result;
1309 }
1310 
1311 /*
1312  * db_is_output_marker() - Returns true iff it is the host variable
1313  * output marker
1314  * return : boolean
1315  * marker(in): DB_MARKER
1316  */
1317 bool
1319 {
1320  bool result = false;
1321 
1322  if (marker)
1323  {
1324  result = pt_is_output_hostvar (marker);
1325  }
1326 
1327  return result;
1328 }
1329 
1330 /*
1331  * db_get_query_type_list() - This function returns a type list that describes
1332  * the columns of a SELECT statement. This includes the column title, data
1333  * type, and size. The statement ID must have been returned by a previously
1334  * successful call to the db_compile_statement() function. The query type
1335  * list is freed by using the db_query_format_free() function.
1336  * return : query type.
1337  * session(in): session handle
1338  * stmt(in): statement id
1339  */
1340 DB_QUERY_TYPE *
1341 db_get_query_type_list (DB_SESSION * session, int stmt_ndx)
1342 {
1343  PT_NODE *statement;
1344  DB_QUERY_TYPE *qtype;
1345  CUBRID_STMT_TYPE cmd_type;
1346 
1347  /* obvious error checking - invalid parameter */
1348  if (!session || !session->parser)
1349  {
1351  return NULL;
1352  }
1353  /* no statement was given in the session */
1354  if (session->dimension == 0 || !session->statements)
1355  {
1357  return NULL;
1358  }
1359  /* invalid parameter */
1360  statement = session->statements[--stmt_ndx];
1361  if (stmt_ndx < 0 || stmt_ndx >= session->dimension || !statement)
1362  {
1364  return NULL;
1365  }
1366  /* check if the statement is compiled and prepared */
1367  if (session->stage[stmt_ndx] < StatementPreparedStage)
1368  {
1370  return NULL;
1371  }
1372 
1373  /* make DB_QUERY_TYPE structure to return */
1374 
1375  if (statement != NULL && statement->node_type == PT_EXECUTE_PREPARE)
1376  {
1377  return db_cp_query_type (session->type_list[stmt_ndx], true);
1378  }
1379 
1380  cmd_type = pt_node_to_cmd_type (statement);
1381  if (cmd_type == CUBRID_STMT_SELECT)
1382  {
1383  PT_NODE *select_list = pt_get_select_list (session->parser, statement);
1384  if (pt_length_of_select_list (select_list, EXCLUDE_HIDDEN_COLUMNS) > 0)
1385  {
1386  /* duplicate one from stored list */
1387  qtype = db_cp_query_type (session->type_list[stmt_ndx], true);
1388  }
1389  else
1390  {
1391  qtype = NULL;
1392  }
1393  }
1394  else
1395  {
1396  /* make new one containing single value */
1397  qtype = db_alloc_query_format (1);
1398  if (qtype)
1399  {
1400  switch (cmd_type)
1401  {
1402  case CUBRID_STMT_CALL:
1403  qtype->db_type = pt_node_to_db_type (statement);
1404  break;
1405  case CUBRID_STMT_INSERT:
1406  /* the type of result of INSERT is object */
1407  qtype->db_type = DB_TYPE_OBJECT;
1408  break;
1413  /* the type of result of some command is integer */
1414  qtype->db_type = DB_TYPE_INTEGER;
1415  break;
1416  default:
1417  break;
1418  }
1419  }
1420  }
1421 
1422  return qtype;
1423 }
1424 
1425 /*
1426  * db_get_query_type_ptr() - This function returns query_type of query result
1427  * return : result->query_type
1428  * result(in): query result
1429  */
1430 DB_QUERY_TYPE *
1432 {
1433  return (result->query_type);
1434 }
1435 
1436 /*
1437  * db_get_start_line() - This function returns source line position of
1438  * a query statement
1439  * return : stmt's source line position
1440  * session(in): contains the SQL query that has been compiled
1441  * stmt(in): int returned by a successful compilation
1442  */
1443 int
1445 {
1446  int retval;
1448  PT_NODE *statement;
1449 
1450  if (!session || !(parser = session->parser) || !session->statements || stmt < 1 || stmt > session->dimension
1451  || !(statement = session->statements[stmt - 1]))
1452  {
1454  retval = er_errid ();
1455  }
1456  else
1457  {
1458  retval = pt_statement_line_number (statement);
1459  }
1460 
1461  return (retval);
1462 }
1463 
1464 /*
1465  * db_get_statement_type() - This function returns query statement node type
1466  * return : stmt's node type
1467  * session(in): contains the SQL query that has been compiled
1468  * stmt(in): statement id returned by a successful compilation
1469  *
1470  * todo: is this acceptable? to return both error code and statement type?
1471  */
1472 int
1474 {
1475  int retval;
1477  PT_NODE *statement;
1478 
1479  if (!session || !(parser = session->parser) || !session->statements || stmt < 1 || stmt > session->dimension
1480  || !(statement = session->statements[stmt - 1]))
1481  {
1483  retval = er_errid ();
1484  }
1485  else
1486  {
1487  if (statement != NULL && statement->node_type == PT_EXECUTE_PREPARE)
1488  {
1489  retval = statement->info.execute.stmt_type;
1490  }
1491  else
1492  {
1493  retval = pt_node_to_cmd_type (statement);
1494  }
1495  }
1496 
1497  return retval;
1498 }
1499 
1500 /*
1501  * db_include_oid() - This function set the session->parser->oid_included flag
1502  * return : void
1503  * session(in): the current session context
1504  * include_oid(in): non-zero means include oid,
1505  * zero means don't include it.
1506  */
1507 void
1508 db_include_oid (DB_SESSION * session, int include_oid)
1509 {
1510  if (!session)
1511  {
1512  return;
1513  }
1514 
1515  session->include_oid = include_oid;
1516 }
1517 
1518 /*
1519  * db_push_values() - This function set session->parser->host_variables
1520  * & host_var_count
1521  * return : integer, negative implies error.
1522  * session(in): contains the SQL query that has been compiled
1523  * count(in): number of elements in in_values table
1524  * in_values(in): a table of host_variable initialized DB_VALUEs
1525  */
1526 int
1527 db_push_values (DB_SESSION * session, int count, DB_VALUE * in_values)
1528 {
1530 
1531  if (session)
1532  {
1533  parser = session->parser;
1534  if (parser)
1535  {
1536  pt_set_host_variables (parser, count, in_values);
1537 
1538  if (parser->host_var_count > 0 && parser->flag.set_host_var == 0)
1539  {
1540  if (pt_has_error (session->parser))
1541  {
1542  /* This error can occur when using the statement pooling */
1544  /* forget about any previous compilation errors, if any */
1545  pt_reset_error (session->parser);
1546 
1547  return ER_PT_SEMANTIC;
1548  }
1549  }
1550  }
1551  }
1552 
1553  return NO_ERROR;
1554 }
1555 
1556 /*
1557  * db_get_hostvars() -
1558  * return:
1559  * session(in) :
1560  */
1561 DB_VALUE *
1563 {
1564  return session->parser->host_variables;
1565 }
1566 
1567 /*
1568  * db_get_lock_classes() -
1569  * return:
1570  * session(in) :
1571  */
1572 char **
1574 {
1575  if (session == NULL || session->parser == NULL)
1576  {
1577  return NULL;
1578  }
1579 
1580  return (char **) (session->parser->lcks_classes);
1581 }
1582 
1583 /*
1584  * db_execute_and_keep_statement_local() - This function executes the SQL
1585  * statement identified by the stmt argument and returns the result.
1586  * The statement ID must have already been returned by a successful call
1587  * to the db_open_file() function or the db_open_buffer() function that
1588  * came from a call to the db_compile_statement()function. The compiled
1589  * statement is preserved, and may be executed again within the same
1590  * transaction.
1591  * return : error status, if execution failed
1592  * number of affected objects, if a success & stmt is a SELECT,
1593  * UPDATE, DELETE, or INSERT
1594  * session(in) : contains the SQL query that has been compiled
1595  * stmt(in) : int returned by a successful compilation
1596  * result(out): query results descriptor
1597  */
1598 static int
1600 {
1602  PT_NODE *statement;
1603  DB_QUERY_RESULT *qres;
1604  DB_VALUE *val;
1605  int err = NO_ERROR;
1606  int server_info_bits;
1607 
1608  SEMANTIC_CHK_INFO sc_info = { NULL, NULL, 0, 0, 0, false, false };
1610 
1611  if (result != NULL)
1612  {
1613  *result = NULL;
1614  }
1615 
1616  /* obvious error checking - invalid parameter */
1617  if (!session || !session->parser)
1618  {
1620  return er_errid ();
1621  }
1622  /* no statement was given in the session */
1623  if (session->dimension == 0 || !session->statements)
1624  {
1626  return er_errid ();
1627  }
1628  /* invalid parameter */
1629  stmt_ndx--;
1630  if (stmt_ndx < 0 || stmt_ndx >= session->dimension || !session->statements[stmt_ndx])
1631  {
1633  return er_errid ();
1634  }
1635 
1636  /* valid host variable was not set before */
1637  if (session->parser->host_var_count > 0 && session->parser->flag.set_host_var == 0)
1638  {
1639  if (pt_has_error (session->parser))
1640  {
1642  /* forget about any previous compilation errors, if any */
1643  pt_reset_error (session->parser);
1644  }
1645  else
1646  {
1647  /* parsed statement has some host variable parameters (input marker '?'), but no host variable (DB_VALUE
1648  * array) was set by db_push_values() API */
1650  }
1651  return er_errid ();
1652  }
1653 
1654  /* if the parser already has something wrong - semantic error */
1655  if (session->stage[stmt_ndx] < StatementExecutedStage && pt_has_error (session->parser))
1656  {
1658  return er_errid ();
1659  }
1660 
1661  /*
1662  * Execution Stage
1663  */
1664  er_clear ();
1665 
1666  parser = session->parser;
1667 
1668  /* initialization */
1669  assert (parser != NULL);
1670  parser->query_id = NULL_QUERY_ID;
1671  parser->flag.is_in_and_list = false;
1672 
1673  /* now, we have a statement to execute */
1674  statement = session->statements[stmt_ndx];
1675 
1676  /* if the statement was not compiled and prepared, do it */
1677  if (session->stage[stmt_ndx] < StatementPreparedStage)
1678  {
1679  session->stmt_ndx = stmt_ndx;
1680  if (db_compile_statement_local (session) < 0)
1681  {
1682  assert (er_errid () != NO_ERROR);
1683  return er_errid ();
1684  }
1685  }
1686 
1687  /* forget about any previous compilation errors, if any */
1688  pt_reset_error (parser);
1689 
1690  /* get sys_date, sys_time, sys_timestamp, sys_datetime values from the server */
1691  server_info_bits = 0; /* init */
1692  if (statement->flag.si_datetime || (statement->node_type == PT_CREATE_ENTITY || statement->node_type == PT_ALTER))
1693  {
1694  /* Some create and alter statement require the server timestamp even though it does not explicitly refer
1695  * timestamp-related pseudocolumns. For instance, create table foo (a timestamp default systimestamp); create
1696  * view v_foo as select * from foo; */
1698 
1699  if (base_server_timeb.time == 0)
1700  {
1701  server_info_bits |= SI_SYS_DATETIME;
1702  }
1703  }
1704 
1705  if (statement->flag.si_tran_id && DB_IS_NULL (&parser->local_transaction_id))
1706  {
1707  /* if it was reset in the previous execution step, fills it now */
1708  server_info_bits |= SI_LOCAL_TRANSACTION_ID;
1709  }
1710 
1711  /* request to the server */
1712  if (server_info_bits)
1713  {
1714  err = qp_get_server_info (parser, server_info_bits);
1715  if (err != NO_ERROR)
1716  {
1717  return err;
1718  }
1719  }
1720 
1721  if (server_info_bits & SI_SYS_DATETIME)
1722  {
1724  }
1725 
1726  if (statement->node_type == PT_PREPARE_STATEMENT)
1727  {
1728  err = do_process_prepare_statement (session, statement);
1730  assert (result == NULL || *result == NULL);
1731  return err;
1732  }
1733  else if (statement->node_type == PT_EXECUTE_PREPARE)
1734  {
1735  bool do_recompile = false;
1736  if (statement->info.execute.stmt_type == CUBRID_STMT_SELECT)
1737  {
1738  if (!statement->xasl_id || XASL_ID_IS_NULL (statement->xasl_id) || statement->info.execute.recompile)
1739  {
1740  do_recompile = true;
1741  }
1742  }
1743  else
1744  {
1745  do_recompile = true;
1746  }
1747 
1748  if (do_recompile)
1749  {
1750  return do_recompile_and_execute_prepared_statement (session, statement, result);
1751  }
1752  }
1753  else if (statement->node_type == PT_DEALLOCATE_PREPARE)
1754  {
1755  err = do_process_deallocate_prepare (session, statement);
1757  assert (result == NULL || *result == NULL);
1758  return err;
1759  }
1760 
1761  /* New interface of do_prepare_statement()/do_execute_statment() is used only when the XASL cache is enabled. If it
1762  * is disabled, old interface of do_statement() will be used instead. do_statement() makes a XASL everytime rather
1763  * than using XASL cache. Also, it can be executed in the server without touching the XASL cache by calling
1764  * prepare_and_execute_query(). */
1765  do_Trigger_involved = false;
1766 
1767  pt_null_etc (statement);
1768  if (statement->xasl_id == NULL && ((cls_status = pt_has_modified_class (parser, statement)) != DB_CLASS_NOT_MODIFIED))
1769  {
1770  if (cls_status == DB_CLASS_MODIFIED)
1771  {
1774  }
1775  else
1776  {
1777  assert (cls_status == DB_CLASS_ERROR);
1778  assert (er_errid () != NO_ERROR);
1779  err = er_errid ();
1780  }
1781  }
1782  else if (prm_get_integer_value (PRM_ID_XASL_CACHE_MAX_ENTRIES) > 0 && statement->flag.cannot_prepare == 0)
1783  {
1784  /* now, execute the statement by calling do_execute_statement() */
1785  err = do_execute_statement (parser, statement);
1787  && session->stage[stmt_ndx] == StatementPreparedStage)
1788  || (err == ER_QPROC_XASLNODE_RECOMPILE_REQUESTED && session->stage[stmt_ndx] == StatementExecutedStage))
1789  {
1790  /* The cache entry was deleted before 'execute' */
1791  if (statement->xasl_id)
1792  {
1793  pt_free_statement_xasl_id (statement);
1794  }
1795 
1796  cls_status = pt_has_modified_class (parser, statement);
1797  if (cls_status == DB_CLASS_NOT_MODIFIED)
1798  {
1799  /* forget all errors */
1800  er_clear ();
1801  pt_reset_error (parser);
1802  parser->query_id = NULL_QUERY_ID; /* reset to re-try */
1803 
1804  /* retry the statement by calling do_prepare/execute_statement() */
1805  if (do_prepare_statement (parser, statement) == NO_ERROR)
1806  {
1807  err = do_execute_statement (parser, statement);
1808  }
1809  }
1810  else if (cls_status == DB_CLASS_MODIFIED)
1811  {
1814  }
1815  else
1816  {
1817  assert (cls_status == DB_CLASS_ERROR);
1818  assert (er_errid () != NO_ERROR);
1819  err = er_errid ();
1820  }
1821  }
1822  }
1823  else
1824  {
1825  /* bind and resolve host variables */
1826  assert (parser->host_var_count >= 0 && parser->auto_param_count >= 0);
1827  if (parser->host_var_count > 0)
1828  {
1829  assert (parser->flag.set_host_var == 1);
1830  }
1831  if (parser->host_var_count > 0 || parser->auto_param_count > 0)
1832  {
1833  /* In this case, pt_bind_values_to_hostvars() will change PT_HOST_VAR node. Must duplicate the statement and
1834  * execute with the new one and free the copied one before returning */
1835  statement = parser_copy_tree_list (parser, statement);
1836  statement = mq_reset_ids_in_statement (parser, statement);
1837 
1838  sc_info.top_node = statement;
1839  sc_info.donot_fold = false;
1840 
1841  if (!(statement = pt_bind_values_to_hostvars (parser, statement))
1842  || !(statement = pt_resolve_names (parser, statement, &sc_info))
1843  || !(statement = pt_semantic_type (parser, statement, &sc_info)))
1844  {
1845  /* something wrong */
1846  if (er_errid () == NO_ERROR)
1847  {
1849  }
1850  if (pt_has_error (parser))
1851  {
1852  pt_report_to_ersys_with_statement (parser, PT_SYNTAX, statement);
1853  pt_reset_error (parser);
1854  }
1855  if (statement != session->statements[stmt_ndx])
1856  {
1857  parser_free_tree (parser, statement);
1858  }
1859  assert (er_errid () != NO_ERROR);
1860  return er_errid ();
1861  }
1862  }
1863 
1864  err = do_statement (parser, statement);
1865  }
1866 
1867  do_Trigger_involved = false;
1868  if (err < 0)
1869  {
1870  /* Do not override original error id with */
1871  if (er_errid () == NO_ERROR && pt_has_error (parser) && err != ER_QPROC_INVALID_XASLNODE)
1872  {
1873  pt_report_to_ersys_with_statement (parser, PT_EXECUTION, statement);
1874  err = er_errid ();
1875  }
1876  /* free the allocated list_id area before leaving */
1877  pt_free_query_etc_area (parser, statement);
1878  }
1879 
1880  /* so now, the statement is executed */
1881  session->stage[stmt_ndx] = StatementExecutedStage;
1882 
1883  /* execution succeeded, maybe. process result of the query */
1884  if (result && !(err < 0))
1885  {
1886  qres = NULL;
1887 
1888  if (statement->flag.clt_cache_reusable)
1889  {
1891  if (qres == NULL)
1892  {
1893  assert (er_errid () != NO_ERROR);
1894  err = er_errid ();
1895  }
1896  }
1897  else
1898  {
1899  CUBRID_STMT_TYPE stmt_type = pt_node_to_cmd_type (statement);
1900  switch (stmt_type)
1901  {
1902  case CUBRID_STMT_SELECT:
1904  /* Check whether pt_new_query_result_descriptor() fails. Similar tests are required for
1905  * CUBRID_STMT_INSERT and CUBRID_STMT_CALL cases. */
1906  qres = pt_new_query_result_descriptor (parser, statement);
1907  if (qres)
1908  {
1909  /* get number of rows as result */
1910  err = db_query_tuple_count (qres);
1911  qres->query_type = db_cp_query_type (session->type_list[stmt_ndx], false);
1912  qres->res.s.stmt_id = stmt_ndx;
1913  }
1914  else
1915  {
1916  assert (er_errid () != NO_ERROR);
1917  err = er_errid ();
1918  }
1919  break;
1920 
1921  case CUBRID_STMT_DO:
1922  pt_free_query_etc_area (parser, statement);
1923  break;
1924 
1929  case CUBRID_STMT_EVALUATE:
1930  case CUBRID_STMT_CALL:
1931  case CUBRID_STMT_INSERT:
1932  case CUBRID_STMT_GET_STATS:
1933  /* csql (in csql.c) may throw away any non-null *result, but we create a DB_QUERY_RESULT structure anyway
1934  * for other callers of db_execute that use the *result like esql_cli.c */
1935  if (pt_is_server_insert_with_generated_keys (parser, statement))
1936  {
1937  qres = pt_new_query_result_descriptor (parser, statement);
1938  if (qres)
1939  {
1940  /* get number of rows as result */
1941  qres->query_type = db_cp_query_type (session->type_list[stmt_ndx], false);
1942  qres->res.s.stmt_id = stmt_ndx;
1943  }
1944  else
1945  {
1946  assert (er_errid () != NO_ERROR);
1947  err = er_errid ();
1948  }
1949  break;
1950  }
1951 
1952  if (stmt_type == CUBRID_STMT_INSERT
1954  {
1955  val = db_value_create ();
1956  if (val == NULL)
1957  {
1958  assert (er_errid () != NO_ERROR);
1959  err = er_errid ();
1960  break;
1961  }
1962  db_make_object (val, NULL);
1963  }
1964  else
1965  {
1966  val = (DB_VALUE *) pt_node_etc (statement);
1967  }
1968 
1969  if (val)
1970  {
1971  /* got a result, so use it */
1972  qres = db_get_db_value_query_result (val);
1973  if (qres)
1974  {
1975  /* get number of rows as result */
1976  int row_count = err;
1977  err = db_query_tuple_count (qres);
1978  /* We have a special case for REPLACE INTO: pt_node_etc (statement) holds only the inserted row
1979  * but we might have done a delete before. For this case, if err>row_count we will not change the
1980  * row count */
1981  if (stmt_type == CUBRID_STMT_INSERT)
1982  {
1983  if ((DB_VALUE_DOMAIN_TYPE (val) == DB_TYPE_OBJECT && DB_IS_NULL (val))
1984  || (statement->info.insert.do_replace && row_count > err))
1985  {
1986  err = row_count;
1987  }
1988  }
1989  }
1990  else
1991  {
1992  assert (er_errid () != NO_ERROR);
1993  err = er_errid ();
1994  }
1995 
1996  /* db_get_db_value_query_result copied val, so free val */
1997  db_value_free (val);
1998  pt_null_etc (statement);
1999  }
2000  else
2001  {
2002  /* avoid changing err. it should have been meaningfully set. if err = 0, uci_static will set SQLCA to
2003  * SQL_NOTFOUND! */
2004  }
2005  break;
2006 
2007  default:
2008  break;
2009  } /* switch (pt_node_to_cmd_type()) */
2010 
2011  } /* else */
2012 
2013  *result = qres;
2014  } /* if (result) */
2015 
2016  /* Do not override original error id with */
2017  /* last error checking */
2018  if (er_errid () == NO_ERROR && pt_has_error (parser) && err != ER_QPROC_INVALID_XASLNODE)
2019  {
2020  pt_report_to_ersys_with_statement (parser, PT_EXECUTION, statement);
2021  err = er_errid ();
2022  }
2023 
2024  /* reset the parser values */
2025  if (statement->flag.si_datetime)
2026  {
2027  db_make_null (&parser->sys_datetime);
2028  db_make_null (&parser->sys_epochtime);
2029  }
2030  if (statement->flag.si_tran_id)
2031  {
2033  }
2034 
2035  update_execution_values (parser, err, pt_node_to_cmd_type (statement));
2036 
2037  /* free if the statement was duplicated for host variable binding */
2038  if (statement != session->statements[stmt_ndx])
2039  {
2040  parser_free_tree (parser, statement);
2041  }
2042 
2043  return err;
2044 }
2045 
2046 static void
2047 update_execution_values (PARSER_CONTEXT * parser, int result, CUBRID_STMT_TYPE statement_type)
2048 {
2049  if (result < 0)
2050  {
2051  parser->execution_values.row_count = -1;
2052  }
2053  else if (statement_type == CUBRID_STMT_UPDATE || statement_type == CUBRID_STMT_INSERT
2054  || statement_type == CUBRID_STMT_DELETE)
2055  {
2056  parser->execution_values.row_count = result;
2057  }
2058  else
2059  {
2060  parser->execution_values.row_count = -1;
2061  }
2063 }
2064 
2065 static void
2067 {
2068  assert (destination != NULL && source != NULL);
2069  destination->row_count = source->row_count;
2070 }
2071 
2072 static int
2073 values_list_to_values_array (PARSER_CONTEXT * parser, PT_NODE * values_list, DB_VALUE_ARRAY * values_array)
2074 {
2075  DB_VALUE_ARRAY values;
2076  PT_NODE *current_value = values_list;
2077  int i = 0;
2078  int err = NO_ERROR;
2079 
2080  values.size = 0;
2081  values.vals = NULL;
2082 
2083  if (parser == NULL || values_array == NULL || values_array->size != 0 || values_array->vals != NULL)
2084  {
2085  assert (false);
2087  err = er_errid ();
2088  goto error_exit;
2089  }
2090 
2091  if (values_list == NULL)
2092  {
2093  return NO_ERROR;
2094  }
2095  while (current_value != NULL)
2096  {
2097  values.size++;
2098  current_value = current_value->next;
2099  }
2100 
2101  values.vals = (DB_VALUE *) malloc (values.size * sizeof (DB_VALUE));
2102  if (values.vals == NULL)
2103  {
2105  err = er_errid ();
2106  goto error_exit;
2107  }
2108 
2109  for (i = 0; i < values.size; ++i)
2110  {
2111  db_make_null (&values.vals[i]);
2112  }
2113  for (current_value = values_list, i = 0; current_value != NULL; current_value = current_value->next, ++i)
2114  {
2115  if (current_value->node_type == PT_EXPR && current_value->info.expr.op == PT_EVALUATE_VARIABLE)
2116  {
2117  /* this is a session variable */
2118  DB_VALUE val;
2119  DB_VALUE *name;
2120 
2121  assert (current_value->info.expr.arg1->node_type == PT_VALUE);
2122 
2123  name = pt_value_to_db (parser, current_value->info.expr.arg1);
2124  db_make_null (&val);
2125  if (db_get_variable (name, &val) != NO_ERROR)
2126  {
2127  assert (er_errid () != NO_ERROR);
2128  err = er_errid ();
2129  goto error_exit;
2130  }
2131  pr_clone_value (&val, &values.vals[i]);
2132  pr_clear_value (&val);
2133  }
2134  else
2135  {
2136  DB_VALUE *db_val = NULL;
2137 
2138  db_val = pt_value_to_db (parser, current_value);
2139  if (db_val == NULL)
2140  {
2142  err = er_errid ();
2143  goto error_exit;
2144  }
2145  pr_clone_value (db_val, &values.vals[i]);
2146  }
2147  }
2148 
2149  values_array->size = values.size;
2150  values_array->vals = values.vals;
2151  values.size = 0;
2152  values.vals = NULL;
2153 
2154  return err;
2155 
2156 error_exit:
2157 
2158  if (values.vals != NULL)
2159  {
2160  db_value_clear_array (&values);
2161  free_and_init (values.vals);
2162  values.size = 0;
2163  }
2164  return err;
2165 }
2166 
2167 static int
2169 {
2170  int length = 0;
2171  PT_NODE *name = NULL;
2172 
2173  assert (prepare_info->into_list == NULL);
2174 
2175  prepare_info->into_count = 0;
2176 
2177  if (pt_node_to_cmd_type (statement) != CUBRID_STMT_SELECT)
2178  {
2179  return NO_ERROR;
2180  }
2181 
2182  if (statement->info.query.into_list == NULL)
2183  {
2184  return NO_ERROR;
2185  }
2186 
2187  length = pt_length_of_list (statement->info.query.into_list);
2188  if (length == 0)
2189  {
2190  return NO_ERROR;
2191  }
2192 
2193  prepare_info->into_list = (char **) malloc (length * sizeof (char *));
2194  if (prepare_info->into_list == NULL)
2195  {
2196  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, length * sizeof (char *));
2197  goto error;
2198  }
2199  name = statement->info.query.into_list;
2200  length = 0;
2201  while (name)
2202  {
2203  if (PT_IS_NAME_NODE (name))
2204  {
2205  if (name->info.name.original == NULL)
2206  {
2207  prepare_info->into_list[length] = NULL;
2208  }
2209  else
2210  {
2211  char *into_name = (char *) malloc (strlen (name->info.name.original) + 1);
2212  if (into_name == NULL)
2213  {
2215  (size_t) (strlen (name->info.name.original) + 1));
2216  goto error;
2217  }
2218  memcpy (into_name, name->info.name.original, strlen (name->info.name.original));
2219  into_name[strlen (name->info.name.original)] = 0;
2220  prepare_info->into_list[length] = into_name;
2221  }
2222  }
2223  else
2224  {
2225  prepare_info->into_list[length] = NULL;
2226  }
2227  length++;
2228  name = name->next;
2229  }
2230 
2231  prepare_info->into_count = length;
2232  return NO_ERROR;
2233 
2234 error:
2235  if (prepare_info->into_list != NULL)
2236  {
2237  int i = 0;
2238  for (i = 0; i < length; i++)
2239  {
2240  if (prepare_info->into_list[i] != NULL)
2241  {
2242  free_and_init (prepare_info->into_list[i]);
2243  }
2244  }
2245  free_and_init (prepare_info->into_list);
2246  }
2247  return ER_FAILED;
2248 }
2249 
2250 static PT_NODE *
2251 char_array_to_name_list (PARSER_CONTEXT * parser, char **names, int length)
2252 {
2253  PT_NODE *name = NULL;
2254  PT_NODE *list = NULL;
2255  int i;
2256 
2257  for (i = 0; i < length; i++)
2258  {
2259  name = pt_name (parser, names[i]);
2260  list = parser_append_node (name, list);
2261  }
2262 
2263  return list;
2264 }
2265 
2266 /*
2267  * do_process_prepare_statement () - execute a 'PREPARE STMT FROM ...'
2268  * statement
2269  * return: error code or NO_ERROR
2270  * session (in) : client session for this statement
2271  * statement (in) : the statement
2272  */
2273 static int
2275 {
2276  DB_PREPARE_INFO prepare_info;
2277  DB_SESSION *prepared_session = NULL;
2278  int prepared_statement_ndx = 0;
2279  PT_NODE *prepared_stmt = NULL;
2280  const char *const name = statement->info.prepare.name->info.name.original;
2281  const char *const statement_literal = (char *) statement->info.prepare.statement->info.value.data_value.str->bytes;
2282  int err = NO_ERROR;
2283  char *stmt_info = NULL;
2284  int info_len = 0;
2285  assert (statement->node_type == PT_PREPARE_STATEMENT);
2286  db_init_prepare_info (&prepare_info);
2287 
2288  prepared_session = db_open_buffer_local (statement_literal);
2289  if (prepared_session == NULL)
2290  {
2291  assert (er_errid () != NO_ERROR);
2292  err = er_errid ();
2293  goto cleanup;
2294  }
2295 
2296  /* we need to copy all the relevant settings */
2297  prepared_session->include_oid = session->include_oid;
2298 
2299  prepared_statement_ndx = db_compile_statement_local (prepared_session);
2300  if (prepared_statement_ndx < 0)
2301  {
2302  err = prepared_statement_ndx;
2303  goto cleanup;
2304  }
2305 
2306  err = db_check_single_query (prepared_session);
2307  if (err != NO_ERROR)
2308  {
2311  goto cleanup;
2312  }
2313 
2314  assert (prepared_statement_ndx == 1);
2315  assert (prepared_session->dimension == 1);
2316  assert (prepared_session->statements[0] != NULL);
2317 
2318  prepared_stmt = prepared_session->statements[0];
2319 
2320  if (!is_allowed_as_prepared_statement (prepared_stmt))
2321  {
2323  err = ER_FAILED;
2324  goto cleanup;
2325  }
2326 
2327  if (prepared_session->parser->host_var_count > 0 && !is_allowed_as_prepared_statement_with_hv (prepared_stmt))
2328  {
2330  pt_show_node_type (prepared_session->statements[0]));
2331  err = ER_FAILED;
2332  goto cleanup;
2333  }
2334 
2335  /* set statement literal */
2336  prepare_info.statement = (char *) statement_literal;
2337  /* set columns */
2338  prepare_info.columns = prepared_session->type_list[0];
2339  /* set statement type */
2340  prepare_info.stmt_type = pt_node_to_cmd_type (prepared_stmt);
2341  /* set host variables */
2342  prepare_info.host_variables.size =
2343  prepared_session->parser->host_var_count + prepared_session->parser->auto_param_count;
2344  prepare_info.host_variables.vals = prepared_session->parser->host_variables;
2345  prepare_info.host_var_expected_domains = prepared_session->parser->host_var_expected_domains;
2346  /* set autoparam count */
2347  prepare_info.auto_param_count = prepared_session->parser->auto_param_count;
2348  /* set recompile */
2349  prepare_info.recompile = prepared_stmt->flag.recompile;
2350  /* set OIDs included */
2351  if (prepare_info.stmt_type == CUBRID_STMT_SELECT)
2352  {
2353  prepare_info.oids_included = prepared_stmt->info.query.oids_included;
2354  }
2355 
2356  err = set_prepare_info_into_list (&prepare_info, prepared_stmt);
2357  if (err != NO_ERROR)
2358  {
2359  goto cleanup;
2360  }
2361 
2362  err = db_pack_prepare_info (&prepare_info, &stmt_info);
2363  if (err < 0)
2364  {
2365  goto cleanup;
2366  }
2367  info_len = err;
2368 
2369  err = csession_create_prepared_statement (name, prepared_stmt->alias_print, stmt_info, info_len);
2370 
2371 cleanup:
2372  if (err < 0 && name != NULL)
2373  {
2374  /* clear the previously cached one with the same name if exists */
2375  er_stack_push ();
2377  er_stack_pop ();
2378  }
2379 
2380  if (stmt_info != NULL)
2381  {
2382  free_and_init (stmt_info);
2383  }
2384 
2385  if (prepared_session)
2386  {
2387  db_close_session_local (prepared_session);
2388  }
2389 
2390  if (prepare_info.into_list != NULL)
2391  {
2392  int i = 0;
2393  for (i = 0; i < prepare_info.into_count; i++)
2394  {
2395  free_and_init (prepare_info.into_list[i]);
2396  }
2397  free_and_init (prepare_info.into_list);
2398  }
2399 
2400  return err;
2401 }
2402 
2403 /*
2404  * do_get_prepared_statement_info () - get prepared statement information
2405  * return : error code or NO_ERROR
2406  * session (in) : client session context
2407  * stmt_idx (in) : statement index
2408  */
2409 static int
2411 {
2412  const char *name = NULL;
2413  char *stmt_info = NULL;
2414  XASL_ID xasl_id;
2415  int err = NO_ERROR, i = 0;
2416  DB_VALUE *hv = NULL;
2417  PT_NODE *statement = session->statements[stmt_idx];
2418  PARSER_CONTEXT *parser = session->parser;
2419  DB_PREPARE_INFO prepare_info;
2420  DB_QUERY_TYPE *col = NULL;
2421  XASL_NODE_HEADER xasl_header;
2422 
2424  db_init_prepare_info (&prepare_info);
2425 
2426  name = statement->info.execute.name->info.name.original;
2427  err = csession_get_prepared_statement (name, &xasl_id, &stmt_info, &xasl_header);
2428  if (err != NO_ERROR)
2429  {
2430  return err;
2431  }
2432 
2433  db_unpack_prepare_info (&prepare_info, stmt_info);
2434 
2435  statement->info.execute.column_count = 0;
2436  col = prepare_info.columns;
2437  while (col)
2438  {
2439  statement->info.execute.column_count++;
2440  col = col->next;
2441  }
2442 
2443  /* set session type list */
2444  session->type_list[stmt_idx] = prepare_info.columns;
2445 
2446  statement->info.execute.into_list =
2447  char_array_to_name_list (session->parser, prepare_info.into_list, prepare_info.into_count);
2448 
2449  statement->info.execute.stmt_type = prepare_info.stmt_type;
2450 
2451  /* set query */
2452  statement->info.execute.query = pt_make_string_value (parser, prepare_info.statement);
2453  if (statement->info.execute.query == NULL)
2454  {
2455  PT_INTERNAL_ERROR (parser, "allocate new node");
2456  }
2457  statement->info.execute.recompile = prepare_info.recompile;
2458  statement->info.execute.oids_included = prepare_info.oids_included;
2459 
2460  XASL_ID_COPY (&statement->info.execute.xasl_id, &xasl_id);
2461 
2462  /* restore host variables used by this statement */
2463  for (i = 0, hv = parser->host_variables; i < parser->host_var_count + parser->auto_param_count; i++, hv++)
2464  {
2465  pr_clear_value (hv);
2466  }
2467 
2468  if (parser->host_variables)
2469  {
2470  free_and_init (parser->host_variables);
2471  }
2472 
2473  if (parser->host_var_expected_domains)
2474  {
2476  }
2477 
2478  parser->auto_param_count = 0;
2479  parser->host_var_count = 0;
2480 
2481  parser->auto_param_count = prepare_info.auto_param_count;
2482  parser->host_variables = prepare_info.host_variables.vals;
2484  parser->host_var_count = prepare_info.host_variables.size - prepare_info.auto_param_count;
2485 
2486  err = do_set_user_host_variables (session, statement->info.execute.using_list);
2487  if (err != NO_ERROR)
2488  {
2489  goto cleanup;
2490  }
2491 
2492  parser->host_var_count += prepare_info.auto_param_count;
2493  parser->auto_param_count = 0;
2494  parser->flag.set_host_var = 1;
2495 
2496  /* Multi range optimization check: if host-variables were used (not auto-parameterized), the orderby_num () limit may
2497  * change and invalidate or validate multi range optimization. Check if query needs to be recompiled. */
2498  if (!XASL_ID_IS_NULL (&xasl_id) /* xasl_id should not be null */
2499  && !statement->info.execute.recompile /* recompile is already planned */
2500  && (prepare_info.host_variables.size > prepare_info.auto_param_count))
2501  {
2502  /* query has to be multi range opt candidate */
2504  {
2505  if (db_check_limit_need_recompile (parser, statement, xasl_header.xasl_flag))
2506  {
2507  /* need recompile, set XASL_ID to NULL */
2508  XASL_ID_SET_NULL (&statement->info.execute.xasl_id);
2509  }
2510  }
2511  }
2512 
2513 cleanup:
2514  if (stmt_info != NULL)
2515  {
2516  free_and_init (stmt_info);
2517  }
2518  if (prepare_info.statement != NULL)
2519  {
2520  free_and_init (prepare_info.statement);
2521  }
2522  if (prepare_info.into_list != NULL)
2523  {
2524  for (i = 0; i < prepare_info.into_count; i++)
2525  {
2526  if (prepare_info.into_list[i] != NULL)
2527  {
2528  free_and_init (prepare_info.into_list[i]);
2529  }
2530  }
2531  free_and_init (prepare_info.into_list);
2532  }
2533  return err;
2534 }
2535 
2536 /*
2537  * do_cast_host_variables_to_expected_domain () - After compilation phase,
2538  * cast all host variables to
2539  * their expected domains
2540  *
2541  * return : error code
2542  * session (in) : db_session
2543  */
2544 static int
2546 {
2547  int hv_count = session->parser->host_var_count;
2548  DB_VALUE *host_vars = session->parser->host_variables;
2549  TP_DOMAIN **expected_domains = session->parser->host_var_expected_domains;
2550  DB_VALUE *hv = NULL;
2551  TP_DOMAIN *hv_dom = NULL, *d = NULL;
2552  int i = 0;
2553 
2554  for (i = 0; i < hv_count; i++)
2555  {
2556  int prec;
2557  DB_TYPE typ;
2558 
2559  hv = &host_vars[i];
2560  typ = db_value_type (hv);
2561  prec = db_value_precision (hv);
2562  hv_dom = expected_domains[i];
2563  if (TP_DOMAIN_TYPE (hv_dom) == DB_TYPE_UNKNOWN || hv_dom->type->id == DB_TYPE_ENUMERATION)
2564  {
2565  /* skip casting enum and unknown type values */
2566  continue;
2567  }
2568  if (tp_value_cast_preserve_domain (hv, hv, hv_dom, false, true) != DOMAIN_COMPATIBLE)
2569  {
2572  d);
2573  tp_domain_free (d);
2575  pt_reset_error (session->parser);
2576  return ER_PT_EXECUTE;
2577  }
2578 
2579  if (TP_IS_CHAR_TYPE (hv_dom->type->id))
2580  {
2581  if (hv_dom->type->id != typ && (typ == DB_TYPE_VARCHAR || typ == DB_TYPE_VARNCHAR))
2582  {
2583  db_value_domain_init (hv, typ, prec, 0);
2584  }
2585  }
2586  }
2587 
2588  session->parser->flag.set_host_var = 1;
2589 
2590  return NO_ERROR;
2591 }
2592 
2593 /*
2594  * do_set_user_host_variables () - Set host variables values in parser from
2595  * using_list
2596  *
2597  * return : error code
2598  * session (in) : db_session
2599  * using_list (in) : list of db_values
2600  */
2601 static int
2603 {
2604  DB_VALUE_ARRAY values_array;
2605  int err = NO_ERROR;
2606 
2607  values_array.size = 0;
2608  values_array.vals = NULL;
2609 
2610  if (values_list_to_values_array (session->parser, using_list, &values_array) != NO_ERROR)
2611  {
2612  assert (er_errid () != NO_ERROR);
2613  return er_errid ();
2614  }
2615 
2616  if (session->parser->host_var_count != values_array.size)
2617  {
2619  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, err, 2, values_array.size, session->parser->host_var_count);
2620  }
2621  else
2622  {
2623  err = db_push_values (session, values_array.size, values_array.vals);
2624  }
2625 
2626  db_value_clear_array (&values_array);
2627  free_and_init (values_array.vals);
2628  values_array.size = 0;
2629 
2630  return err;
2631 }
2632 
2633 /*
2634  * db_check_limit_need_recompile () - Check if statement has to be recompiled
2635  * for limit optimizations with supplied
2636  * limit value
2637  *
2638  * return : true if recompile is needed, false otherwise
2639  * parser (in) : parser context for statement
2640  * statement (in) : execute prepare statement
2641  * xasl_flag (in) : flag specifying limit optimizations used in XASL
2642  *
2643  * NOTE: This function attempts to evaluate superior limit for orderby_num ()
2644  * without doing a full statement recompile.
2645  */
2646 static bool
2648 {
2649  DB_SESSION *session = NULL;
2650  PT_NODE *query = NULL;
2651  bool do_recompile = false;
2652  DB_VALUE *save_host_variables = NULL;
2653  TP_DOMAIN **save_host_var_expected_domains = NULL;
2654  int save_host_var_count, save_auto_param_count;
2655 
2656  if (statement->node_type != PT_EXECUTE_PREPARE)
2657  {
2658  /* statement must be execute prepare */
2659  return false;
2660  }
2661  if (statement->info.execute.stmt_type != CUBRID_STMT_SELECT)
2662  {
2663  return false;
2664  }
2665 
2666  assert (statement->info.execute.query->node_type == PT_VALUE);
2667  assert (statement->info.execute.query->type_enum == PT_TYPE_CHAR);
2668 
2669  session = db_open_buffer_local ((char *) statement->info.execute.query->info.value.data_value.str->bytes);
2670  if (session == NULL)
2671  {
2672  /* error opening session */
2673  return false;
2674  }
2675 
2676  if (session->dimension != 1)
2677  {
2678  /* need full recompile */
2679  do_recompile = true;
2680  goto exit;
2681  }
2682  query = session->statements[0];
2683  assert (PT_IS_QUERY (query));
2684 
2685  /* set host variable info */
2686  save_auto_param_count = session->parser->auto_param_count;
2687  save_host_var_count = session->parser->host_var_count;
2688  save_host_variables = session->parser->host_variables;
2689  save_host_var_expected_domains = session->parser->host_var_expected_domains;
2690 
2691  session->parser->host_variables = parent_parser->host_variables;
2692  session->parser->host_var_expected_domains = parent_parser->host_var_expected_domains;
2693  session->parser->host_var_count = parent_parser->host_var_count;
2694  session->parser->auto_param_count = parent_parser->auto_param_count;
2695  session->parser->flag.set_host_var = 1;
2696 
2697  if (pt_recompile_for_limit_optimizations (session->parser, query, xasl_flag))
2698  {
2699  /* need recompile */
2700  do_recompile = true;
2701  }
2702 
2703  /* restore host variable info */
2704  session->parser->host_variables = save_host_variables;
2705  session->parser->host_var_expected_domains = save_host_var_expected_domains;
2706  session->parser->auto_param_count = save_auto_param_count;
2707  session->parser->host_var_count = save_host_var_count;
2708  session->parser->flag.set_host_var = 0;
2709 
2710 exit:
2711  /* clean up */
2712  if (session != NULL)
2713  {
2714  db_close_session (session);
2715  }
2716  return do_recompile;
2717 }
2718 
2719 /*
2720  * do_recompile_and_execute_prepared_statement () - compile and execute a
2721  * prepared statement
2722  * return : error code or NO_ERROR
2723  * session (in) : client session context
2724  * statement (in) : statement to be executed
2725  * result (out) : execution result
2726  */
2727 static int
2729 {
2730  int err = NO_ERROR;
2731  int idx = 0;
2732  DB_SESSION *new_session = NULL;
2733  assert (statement->info.execute.query->node_type == PT_VALUE);
2734  assert (statement->info.execute.query->type_enum == PT_TYPE_CHAR);
2735 
2736  new_session = db_open_buffer_local ((char *) statement->info.execute.query->info.value.data_value.str->bytes);
2737  if (new_session == NULL)
2738  {
2739  assert (er_errid () != NO_ERROR);
2740  return er_errid ();
2741  }
2742 
2743  new_session->is_subsession_for_prepared = true;
2744 
2745  /* add the new session to the subsessions list */
2746  if (session->next == NULL)
2747  {
2748  session->next = new_session;
2749  }
2750  else
2751  {
2752  new_session->next = session->next;
2753  session->next = new_session;
2754  }
2755 
2756  if (statement->info.execute.recompile)
2757  {
2758  new_session->statements[0]->flag.recompile = statement->info.execute.recompile;
2759  }
2760 
2761  /* set host variable values in new session */
2762  assert (session->parser->flag.set_host_var == 1);
2763  err = do_set_user_host_variables (new_session, statement->info.execute.using_list);
2764  if (err != NO_ERROR)
2765  {
2766  return err;
2767  }
2768  new_session->parser->flag.set_host_var = 0;
2769  idx = db_compile_statement (new_session);
2770  if (idx < 0)
2771  {
2772  assert (er_errid () != NO_ERROR);
2773  return er_errid ();
2774  }
2775 
2776  if (new_session->parser->flag.set_host_var == 0)
2777  {
2778  /* Cast host variable to expected domain, if not already casted in db_compile_statement. */
2779  err = do_cast_host_variables_to_expected_domain (new_session);
2780  if (err != NO_ERROR)
2781  {
2782  return err;
2783  }
2784  }
2785 
2786  new_session->parser->flag.is_holdable = session->parser->flag.is_holdable;
2787  new_session->parser->flag.is_auto_commit = session->parser->flag.is_auto_commit;
2788  return db_execute_and_keep_statement_local (new_session, 1, result);
2789 }
2790 
2791 /*
2792  * do_process_deallocate_prepare () - deallocate a prepared statement
2793  * return: error code or NO_ERROR
2794  * session (in) : client session context
2795  * statement (in) : statement to be deallocated
2796  */
2797 static int
2799 {
2800  const char *const name = statement->info.prepare.name->info.name.original;
2801  return csession_delete_prepared_statement (name);
2802 }
2803 
2804 /*
2805  * is_allowed_as_prepared_statement () - check if node type is a valid
2806  * prepared statement
2807  * return: true if node is valid prepared statement, false otherwise
2808  * node (in): parse tree node to check
2809  */
2810 static bool
2812 {
2813  assert (node);
2814 
2815  switch (node->node_type)
2816  {
2817  case PT_PREPARE_STATEMENT:
2818  case PT_EXECUTE_PREPARE:
2819  case PT_DEALLOCATE_PREPARE:
2820  return false;
2821 
2822  default:
2823  return true;
2824  }
2825 }
2826 
2827 /*
2828  * is_allowed_as_prepared_statement_with_hv () - check if node type is a valid
2829  * prepared statement that can
2830  * accept hostvars
2831  * return: true if node is valid prepared statement, false otherwise
2832  * node (in): parse tree node to check
2833  */
2834 static bool
2836 {
2837  assert (node);
2838 
2839  switch (node->node_type)
2840  {
2841  case PT_SELECT:
2842  case PT_UNION:
2843  case PT_DIFFERENCE:
2844  case PT_INTERSECTION:
2845 
2846  case PT_INSERT:
2847  case PT_UPDATE:
2848  case PT_DELETE:
2849  case PT_MERGE:
2850 
2851  case PT_DO:
2852  case PT_METHOD_CALL:
2854  case PT_EVALUATE:
2855  return true;
2856 
2857  case PT_CREATE_ENTITY:
2858  return (node->info.create_entity.entity_type == PT_CLASS);
2859 
2860  default:
2861  return false;
2862  }
2863 }
2864 
2865 
2866 /*
2867  * db_has_modified_class()
2868  *
2869  * return:
2870  * session(in):
2871  * stmt_id(in):
2872  */
2874 db_has_modified_class (DB_SESSION * session, int stmt_id)
2875 {
2876  DB_CLASS_MODIFICATION_STATUS cls_status;
2877  PT_NODE *statement;
2878 
2879  assert (session != NULL);
2880  assert (stmt_id < session->dimension);
2881 
2882  cls_status = DB_CLASS_NOT_MODIFIED;
2883  if (stmt_id < session->dimension)
2884  {
2885  statement = session->statements[stmt_id];
2886  if (statement != NULL)
2887  {
2888  cls_status = pt_has_modified_class (session->parser, statement);
2889  }
2890  }
2891 
2892  return cls_status;
2893 }
2894 
2895 /*
2896  * db_execute_and_keep_statement() - Please refer to the
2897  * db_execute_and_keep_statement_local() function
2898  * return : error status, if execution failed
2899  * number of affected objects, if a success & stmt is a SELECT,
2900  * UPDATE, DELETE, or INSERT
2901  * session(in) : contains the SQL query that has been compiled
2902  * stmt(in) : int returned by a successful compilation
2903  * result(out): query results descriptor
2904  */
2905 int
2906 db_execute_and_keep_statement (DB_SESSION * session, int stmt_ndx, DB_QUERY_RESULT ** result)
2907 {
2908  int err;
2909 
2911 
2913 
2914  err = db_execute_and_keep_statement_local (session, stmt_ndx, result);
2915 
2917 
2918  return err;
2919 }
2920 
2921 /*
2922  * db_execute_statement_local() - This function executes the SQL statement
2923  * identified by the stmt argument and returns the result. The
2924  * statement ID must have already been returned by a previously successful
2925  * call to the db_compile_statement() function.
2926  * returns : error status, if execution failed
2927  * number of affected objects, if a success & stmt is a
2928  * SELECT, UPDATE, DELETE, or INSERT
2929  * session(in) : contains the SQL query that has been compiled
2930  * stmt(in) : int returned by a successful compilation
2931  * result(out): query results descriptor
2932  *
2933  * note : You must free the results of calling this function by using the
2934  * db_query_end() function. The resources for the identified compiled
2935  * statement (not its result) are freed. Consequently, the statement may
2936  * not be executed again.
2937  */
2938 int
2939 db_execute_statement_local (DB_SESSION * session, int stmt_ndx, DB_QUERY_RESULT ** result)
2940 {
2941  int err;
2942  PT_NODE *statement;
2943 
2944  if (session == NULL)
2945  {
2947  return ER_OBJ_INVALID_ARGUMENTS;
2948  }
2949 
2950  err = db_execute_and_keep_statement_local (session, stmt_ndx, result);
2951 
2952  statement = session->statements[stmt_ndx - 1];
2953  if (statement != NULL)
2954  {
2955  /* free XASL_ID allocated by query_prepare() before freeing the statement */
2956  pt_free_statement_xasl_id (statement);
2957  parser_free_tree (session->parser, statement);
2958  session->statements[stmt_ndx - 1] = NULL;
2959  }
2960 
2961  return err;
2962 }
2963 
2964 /*
2965  * db_execute_statement() - Please refer to the
2966  * db_execute_statement_local() function
2967  * returns : error status, if execution failed
2968  * number of affected objects, if a success & stmt is a
2969  * SELECT, UPDATE, DELETE, or INSERT
2970  * session(in) : contains the SQL query that has been compiled
2971  * stmt(in) : int returned by a successful compilation
2972  * result(out): query results descriptor
2973  *
2974  * NOTE: db_execute_statement should be used only as entry point for statement
2975  * execution. Otherwise, db_execute_statement_local should be used.
2976  */
2977 int
2978 db_execute_statement (DB_SESSION * session, int stmt_ndx, DB_QUERY_RESULT ** result)
2979 {
2980  int err;
2981 
2983 
2985 
2986  err = db_execute_statement_local (session, stmt_ndx, result);
2987 
2989 
2990  return err;
2991 }
2992 
2993 /*
2994  * db_open_buffer_and_compile_first_statement () - The function will open
2995  * buffer for SQL query string
2996  * and will compile the first
2997  * statement in the list.
2998  *
2999  * return : Error code.
3000  * CSQL_query (in) : SQL query string.
3001  * query_error (in) : Saved query error for output.
3002  * include_oid (in) : Include OID mode.
3003  * session (out) : Generated session.
3004  * stmt_no (out) : Compiled statement number.
3005  */
3006 int
3007 db_open_buffer_and_compile_first_statement (const char *CSQL_query, DB_QUERY_ERROR * query_error, int include_oid,
3008  DB_SESSION ** session, int *stmt_no)
3009 {
3010  int error = NO_ERROR;
3011  DB_SESSION_ERROR *errs;
3012 
3014 
3015  /* Open buffer and generate session */
3016  *session = db_open_buffer_local (CSQL_query);
3017  if (*session == NULL)
3018  {
3019  assert (er_errid () != NO_ERROR);
3020  return (er_errid ());
3021  }
3022 
3023  /* Compile the statement */
3024  db_include_oid (*session, include_oid);
3025  *stmt_no = db_compile_statement_local (*session);
3026 
3027  errs = db_get_errors (*session);
3028  if (errs != NULL)
3029  {
3030  int line, col;
3031 
3032  (void) db_get_next_error (errs, &line, &col);
3033 
3034  assert (er_errid () != NO_ERROR);
3035  error = er_errid ();
3036  if (query_error)
3037  {
3038  query_error->err_lineno = line;
3039  query_error->err_posno = col;
3040  }
3041  }
3042 
3043  if (*stmt_no < 0 || error < 0)
3044  {
3045  db_close_session_local (*session);
3046  *session = NULL;
3047  assert (er_errid () != NO_ERROR);
3048  return (er_errid ());
3049  }
3050 
3051  return error;
3052 }
3053 
3054 /*
3055  * db_compile_and_execute_local () - Default compile and execute for local
3056  * calls. See description for
3057  * db_compile_and_execute_queries_internal.
3058  *
3059  * return : Error code.
3060  * CSQL_query (in) : SQL query string.
3061  * result (out) : Statements results.
3062  * query_error (out) : Saved query error for output.
3063  *
3064  * NOTE: Do not call this function as statement execution entry point. It is
3065  * targeted for internal execution calls only!.
3066  */
3067 int
3068 db_compile_and_execute_local (const char *CSQL_query, void *result, DB_QUERY_ERROR * query_error)
3069 {
3070  /* Default local compile & execute statements will use: - No oids for include OID mode. - True for execution, not
3071  * compile only. - Synchronous execution. - This is called during other statement execution, so false for new
3072  * statements. */
3073  return db_compile_and_execute_queries_internal (CSQL_query, result, query_error, DB_NO_OIDS, 1, false);
3074 }
3075 
3076 /*
3077  * db_compile_and_execute_queries_internal () - Compiles CSQL_query, executes
3078  * all statements and returns
3079  * results.
3080  *
3081  * return : Error code.
3082  * CSQL_query (in) : SQL query string.
3083  * result (out) : Statements results.
3084  * query_error (out) : Saved query error for output.
3085  * include_oid (in) : Include OID mode.
3086  * execute (in) : True if query should also be executed. If argument
3087  * is false, it will only be compiled.
3088  * is_new_statement (in) : True these are new statements. If false they are
3089  * considered as sub-execution for another statement.
3090  *
3091  * NOTE: If executed statements are not part of another statement execution,
3092  * before compiling each statement, the snapshot for current transaction
3093  * must be invalidated.
3094  */
3095 int
3096 db_compile_and_execute_queries_internal (const char *CSQL_query, void *result, DB_QUERY_ERROR * query_error,
3097  int include_oid, int execute, bool is_new_statement)
3098 {
3099  int error; /* return code from funcs */
3100  int stmt_no; /* compiled stmt number */
3101  DB_SESSION *session = NULL;
3102 
3103  if (result)
3104  {
3105  /* Initialize result */
3106  *(char **) result = NULL;
3107  }
3108 
3109  if (is_new_statement)
3110  {
3111  /* invalidate snapshot before compile/execution take place */
3114  }
3115 
3116  /* Open buffer and compile first statement */
3117  error = db_open_buffer_and_compile_first_statement (CSQL_query, query_error, include_oid, &session, &stmt_no);
3118  if (session == NULL)
3119  {
3120  /* In case of error, the session is freed */
3121  return error;
3122  }
3123 
3124  if (execute)
3125  {
3126  /* Execute query and compile next one as long as there are statements left. */
3127  while (stmt_no > 0)
3128  {
3129  /* Execute current query */
3130  error = db_execute_statement_local (session, stmt_no, (DB_QUERY_RESULT **) result);
3131  if (error < 0)
3132  {
3133  break;
3134  }
3135  /* Need to compile and execute next query. Make sure that current MVCC Snapshot is invalidated for READ
3136  * COMMITTED isolation. */
3137  if (is_new_statement)
3138  {
3140 
3142  }
3143  /* Compile a new statement */
3144  stmt_no = db_compile_statement_local (session);
3145  }
3146  }
3147  else if (result)
3148  {
3149  /* Save query types as result */
3150  *(DB_QUERY_TYPE **) result = db_get_query_type_list (session, stmt_no);
3151  if (is_new_statement)
3152  {
3154 
3156  }
3157  }
3158 
3159  db_close_session_local (session);
3160 
3161  return error;
3162 }
3163 
3164 /*
3165  * db_set_system_generated_statement () -
3166  *
3167  * returns : error status, if an invalid session is given
3168  * NO_ERROR
3169  * session(in) : contains the SQL query that has been compiled
3170  *
3171  */
3172 int
3174 {
3176 
3177  if (session == NULL || session->parser == NULL)
3178  {
3180  return ER_OBJ_INVALID_ARGUMENTS;
3181  }
3182 
3183  session->parser->flag.is_system_generated_stmt = 1;
3184 
3185  return NO_ERROR;
3186 }
3187 
3188 /*
3189  * db_drop_statement() - This function frees the resources allocated to a
3190  * compiled statement
3191  * return : void
3192  * session(in) : session handle
3193  * stmt(in) : statement id returned by a successful compilation
3194  */
3195 void
3197 {
3198  PT_NODE *statement;
3199 
3200  statement = session->statements[stmt - 1];
3201  if (statement != NULL)
3202  {
3203  pt_free_statement_xasl_id (statement);
3204  parser_free_tree (session->parser, statement);
3205  session->statements[stmt - 1] = NULL;
3206  session->stage[stmt - 1] = StatementInitialStage;
3207  }
3208 }
3209 
3210 /*
3211  * db_drop_all_statements() - This function frees the resources allocated
3212  * to a session's compiled statements
3213  * rerutn : void
3214  * session(in) : session handle contains the SQL queries that have been
3215  * compiled
3216  */
3217 void
3219 {
3220  PT_NODE *statement;
3221  int stmt;
3222 
3223  for (stmt = 0; stmt < session->dimension; stmt++)
3224  {
3225  statement = session->statements[stmt];
3226  if (statement != NULL)
3227  {
3228  pt_free_statement_xasl_id (statement);
3229  parser_free_tree (session->parser, statement);
3230  session->statements[stmt] = NULL;
3231  session->stage[stmt] = StatementInitialStage;
3232  }
3233  }
3234  session->dimension = session->stmt_ndx = 0;
3235 }
3236 
3237 /*
3238  * db_close_session_local() - This function frees all resources of this session
3239  * except query results
3240  * return : void
3241  * session(in) : session handle
3242  */
3243 void
3245 {
3247  DB_SESSION *prepared;
3248  int i;
3249 
3250  if (!session)
3251  {
3252  return;
3253  }
3254  prepared = session->next;
3255  while (prepared)
3256  {
3257  DB_SESSION *next = prepared->next;
3258  assert (prepared->is_subsession_for_prepared);
3259  prepared->next = NULL;
3260  db_close_session_local (prepared);
3261  prepared = next;
3262  }
3263  parser = session->parser;
3264  for (i = 0; i < session->dimension; i++)
3265  {
3266  PT_NODE *statement;
3267  if (session->type_list && session->type_list[i])
3268  {
3269  db_free_query_format (session->type_list[i]);
3270  }
3271  if (session->statements)
3272  {
3273  statement = session->statements[i];
3274  if (statement != NULL)
3275  {
3276  pt_free_statement_xasl_id (statement);
3277  parser_free_tree (parser, statement);
3278  session->statements[i] = NULL;
3279  }
3280  }
3281  }
3282 
3283  session->dimension = session->stmt_ndx = 0;
3284  if (session->type_list)
3285  {
3286  free_and_init (session->type_list); /* see db_compile_statement_local() */
3287  }
3288 
3289  if (parser->host_variables)
3290  {
3291  DB_VALUE *hv;
3292 
3293  for (i = 0, hv = parser->host_variables; i < parser->host_var_count + parser->auto_param_count; i++, hv++)
3294  {
3295  db_value_clear (hv);
3296  }
3297  free_and_init (parser->host_variables);
3298  }
3299 
3300  if (parser->host_var_expected_domains)
3301  {
3303  }
3304 
3305  parser->host_var_count = parser->auto_param_count = 0;
3306 
3307  pt_free_orphans (session->parser);
3308  parser_free_parser (session->parser);
3309 
3310  free_and_init (session);
3311 }
3312 
3313 /*
3314  * db_close_session() - Please refer to the db_close_session_local() function
3315  * return: void
3316  * session(in) : session handle
3317  */
3318 void
3320 {
3321  db_close_session_local (session);
3322 }
3323 
3324 
3325 /*
3326  * db_get_all_chosen_classes() - This function returns list of all classes
3327  * that pass a predicate
3328  * return : list of class objects that pass a given predicate, if all OK,
3329  * NULL otherwise.
3330  * p(in) : a predicate function
3331  *
3332  * note : the caller is responsible for freeing the list with a call to
3333  * db_objlist_free.
3334  *
3335  */
3336 static DB_OBJLIST *
3338 {
3339  LIST_MOPS *lmops;
3340  DB_OBJLIST *objects, *last, *new_;
3341  int i;
3342 
3343  objects = NULL;
3344  lmops = NULL;
3345  if (au_check_user () == NO_ERROR)
3346  {
3347  /* make sure we have a user */
3348  last = NULL;
3350  /* probably should make sure we push here because the list could be long */
3351  if (lmops != NULL)
3352  {
3353  for (i = 0; i < lmops->num; i++)
3354  {
3355  /* is it necessary to have this check ? */
3356  if (!WS_IS_DELETED (lmops->mops[i]) && lmops->mops[i] != sm_Root_class_mop)
3357  {
3358  /* should have a ext_ append function */
3359  new_ = ml_ext_alloc_link ();
3360  if (new_ == NULL)
3361  {
3362  goto memory_error;
3363  }
3364  new_->op = lmops->mops[i];
3365  new_->next = NULL;
3366  if (last != NULL)
3367  {
3368  last->next = new_;
3369  }
3370  else
3371  {
3372  objects = new_;
3373  }
3374  last = new_;
3375  }
3376  }
3377  locator_free_list_mops (lmops);
3378  }
3379  }
3380  return (objects);
3381 
3382 memory_error:
3383  if (lmops != NULL)
3384  {
3385  locator_free_list_mops (lmops);
3386  }
3387  if (objects)
3388  {
3389  ml_ext_free (objects);
3390  }
3391  return NULL;
3392 }
3393 
3394 /*
3395  * is_vclass_object() -
3396  * return:
3397  * class(in) :
3398  */
3399 static int
3401 {
3402  return sm_get_class_type ((SM_CLASS *) class_) == SM_VCLASS_CT;
3403 }
3404 
3405 /*
3406  * db_get_all_vclasses_on_ldb() - This function returns list of all ldb
3407  * virtual classes
3408  * return : list of all ldb virtual class objects if all OK,
3409  * NULL otherwise.
3410  */
3411 DB_OBJLIST *
3413 {
3414  return NULL;
3415 }
3416 
3417 /*
3418  * db_get_all_vclasses() - This function returns list of all virtual classes
3419  * returns : list of all virtual class objects if all OK,
3420  * NULL otherwise.
3421  */
3422 DB_OBJLIST *
3424 {
3425  DB_OBJLIST *retval;
3426 
3428 
3429  return (retval);
3430 }
3431 
3432 
3433 /*
3434  * db_validate_query_spec() - This function checks that a query_spec is
3435  * compatible with a given {vclass} object
3436  * return : an ER status code if an error was found, NO_ERROR otherwise.
3437  * vclass(in) : an {vclass} object
3438  * query_spec(in) : a query specification string
3439  */
3440 int
3441 db_validate_query_spec (DB_OBJECT * vclass, const char *query_spec)
3442 {
3443  PARSER_CONTEXT *parser = NULL;
3444  PT_NODE **spec = NULL;
3445  int rc = NO_ERROR, is_vclass = 0;
3446  const char *const vclass_name = db_get_class_name (vclass);
3447 
3448  if (vclass_name == NULL)
3449  {
3452  return rc;
3453  }
3454 
3455  is_vclass = db_is_vclass (vclass);
3456  if (is_vclass < 0)
3457  {
3458  return is_vclass;
3459  }
3460  if (!is_vclass)
3461  {
3463  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, rc, 1, vclass_name);
3464  return rc;
3465  }
3466 
3467  parser = parser_create_parser ();
3468  if (parser == NULL)
3469  {
3470  rc = ER_GENERIC_ERROR;
3471  return rc;
3472  }
3473 
3474  spec = parser_parse_string_use_sys_charset (parser, query_spec);
3475  if (spec != NULL && !pt_has_error (parser))
3476  {
3477  rc = pt_validate_query_spec (parser, *spec, vclass);
3478  }
3479  else
3480  {
3481  pt_report_to_ersys (parser, PT_SYNTAX);
3482  rc = er_errid ();
3483  }
3484 
3485  parser_free_parser (parser);
3486 
3487  return rc;
3488 }
3489 
3490 /*
3491  * get_reasonable_predicate() - This function determines if we can compose
3492  * any reasonable predicate against this attribute and return that predicate
3493  * returns: a reasonable predicate against att if one exists, NULL otherwise
3494  * att(in) : an instance attribute
3495  */
3496 static char *
3498 {
3499  static char predicate[300];
3500  const char *att_name, *cond;
3501 
3502  if (!att || db_attribute_is_shared (att) || !(att_name = db_attribute_name (att)))
3503  {
3504  return NULL;
3505  }
3506 
3507  switch (db_attribute_type (att))
3508  {
3509  case DB_TYPE_INTEGER:
3510  case DB_TYPE_FLOAT:
3511  case DB_TYPE_DOUBLE:
3512  case DB_TYPE_SHORT:
3513  case DB_TYPE_BIGINT:
3514  case DB_TYPE_MONETARY:
3515  cond = " = 1 ";
3516  break;
3517 
3518  case DB_TYPE_STRING:
3519  cond = " = 'x' ";
3520  break;
3521 
3522  case DB_TYPE_OBJECT:
3523  cond = " is null ";
3524  break;
3525 
3526  case DB_TYPE_SET:
3527  case DB_TYPE_MULTISET:
3528  case DB_TYPE_SEQUENCE:
3529  cond = " = {} ";
3530  break;
3531 
3532  case DB_TYPE_TIME:
3533  cond = " = '09:30' ";
3534  break;
3535 
3536  case DB_TYPE_TIMESTAMP:
3537  case DB_TYPE_TIMESTAMPLTZ:
3538  cond = " = '10/15/1986 5:45 am' ";
3539  break;
3540 
3541  case DB_TYPE_TIMESTAMPTZ:
3542  cond = " = '10/15/1986 5:45 am +00:00' ";
3543  break;
3544 
3545  case DB_TYPE_DATETIME:
3546  case DB_TYPE_DATETIMELTZ:
3547  cond = " = '10/15/1986 5:45:15.135 am' ";
3548  break;
3549 
3550  case DB_TYPE_DATETIMETZ:
3551  cond = " = '10/15/1986 5:45:15.135 am +00:00' ";
3552  break;
3553 
3554  case DB_TYPE_DATE:
3555  cond = " = '10/15/1986' ";
3556  break;
3557 
3558  default:
3559  return NULL;
3560  }
3561 
3562  snprintf (predicate, sizeof (predicate) - 1, "%s%s", att_name, cond);
3563  return predicate;
3564 }
3565 
3566 /*
3567  * db_validate() - This function checks if a {class|vclass} definition
3568  * is reasonable
3569  * returns : an ER status code if an error was found, NO_ERROR otherwise.
3570  * vc(in) : a {class|vclass} object
3571  */
3572 int
3574 {
3575  int retval = NO_ERROR;
3576  DB_QUERY_SPEC *specs;
3577  const char *s, *separator = " where ";
3578  char buffer[BUF_SIZE], *pred, *bufp, *newbuf;
3579  DB_QUERY_RESULT *result = NULL;
3580  DB_ATTRIBUTE *attributes;
3581  int len, limit = BUF_SIZE;
3582 
3584 
3585  if (!vc)
3586  {
3588  retval = er_errid ();
3589  }
3590  else
3591  {
3592  retval = db_is_any_class (vc);
3593  if (retval < 0)
3594  {
3595  return retval;
3596  }
3597  if (!retval)
3598  {
3600  retval = er_errid ();
3601  }
3602  else
3603  {
3604 
3605  for (specs = db_get_query_specs (vc); specs; specs = db_query_spec_next (specs))
3606  {
3607  s = db_query_spec_string (specs);
3608  if (s)
3609  {
3610  retval = db_validate_query_spec (vc, s);
3611  if (retval < 0)
3612  {
3613  break;
3614  }
3615  }
3616  }
3617  }
3618  }
3619 
3620  if (retval >= 0)
3621  {
3622  strcpy (buffer, "select count(*) from ");
3623  strcat (buffer, db_get_class_name (vc));
3624  attributes = db_get_attributes (vc);
3625  len = (int) strlen (buffer);
3626  bufp = buffer;
3627 
3628  while (attributes)
3629  {
3630  pred = get_reasonable_predicate (attributes);
3631  if (pred)
3632  {
3633  /* make sure we have enough room in the buffer */
3634  len += (int) (strlen (separator) + strlen (pred));
3635  if (len >= limit)
3636  {
3637  /* increase buffer by BUF_SIZE */
3638  limit += BUF_SIZE;
3639  newbuf = (char *) malloc (limit * sizeof (char));
3640  if (newbuf == NULL)
3641  {
3642  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, limit * sizeof (char));
3643  break; /* ran out of memory */
3644  }
3645 
3646  /* copy old buffer into new buffer and switch */
3647  strcpy (newbuf, bufp);
3648  if (bufp != buffer)
3649  {
3650  free_and_init (bufp);
3651  }
3652  bufp = newbuf;
3653  }
3654  /* append another predicate */
3655  strcat (bufp, separator);
3656  strcat (bufp, pred);
3657  separator = " and ";
3658  }
3659  attributes = db_attribute_next (attributes);
3660  }
3661 
3662  retval = db_compile_and_execute_local (bufp, &result, NULL);
3663  if (result)
3664  {
3665  db_query_end (result);
3666  }
3667  if (bufp != buffer)
3668  {
3669  free_and_init (bufp);
3670  }
3671  }
3672 
3673  return retval;
3674 }
3675 
3676 /*
3677  * db_free_query() - If an implicit query was executed, free the query on the
3678  * server.
3679  * returns : void
3680  * session(in) : session handle
3681  */
3682 void
3684 {
3685  pt_end_query (session->parser, NULL_QUERY_ID);
3686 }
3687 
3688 /*
3689  * db_check_single_query() - This function checks to see if there is only
3690  * one statement given, and that it is a valid query statement.
3691  * return : error code
3692  * session(in) : session handle
3693  */
3694 int
3696 {
3697  if (session->dimension > 1)
3698  {
3699  return ER_IT_MULTIPLE_STATEMENT;
3700  }
3701 
3702  return NO_ERROR;
3703 }
3704 
3705 #if !defined (SERVER_MODE)
3706 /*
3707  * db_get_parser() - This function returns session's parser
3708  * returns: session->parser
3709  * session (in): session handle
3710  *
3711  * note : This is a debugging function.
3712  */
3715 {
3716  return session->parser;
3717 }
3718 #endif /* !defined (SERVER_MODE) */
3719 
3720 /*
3721  * db_get_statement() - This function returns session's statement for id
3722  * arguments: session (IN): compilation session
3723  * returns: PT_NODE
3724  *
3725  * note : This is a debugging function only.
3726  *
3727  */
3728 DB_NODE *
3729 db_get_statement (DB_SESSION * session, int id)
3730 {
3731  return session->statements[id];
3732 }
3733 
3734 /*
3735  * db_get_parameters() - This function returns a list of the parameters in the
3736  * specified statement. There is no implied ordering in the returned list
3737  * Parameter names appear once in the returned list, even if they appear
3738  * more than once in the statement.
3739  * return: DB_PARAMETER iterator if there were any parameters in the statement
3740  * session(in): session handle
3741  * statement(in): statement number
3742  */
3743 DB_PARAMETER *
3744 db_get_parameters (DB_SESSION * session, int statement_id)
3745 {
3746  DB_PARAMETER *result = NULL;
3747  DB_NODE *statement;
3748 
3749  if (!session || !session->parser || !session->statements || statement_id < 1 || statement_id > session->dimension
3750  || !(statement = session->statements[statement_id - 1]) || pt_has_error (session->parser))
3751  {
3753  result = NULL;
3754  }
3755  else
3756  {
3757  result = pt_get_parameters (session->parser, statement);
3758  }
3759 
3760  return result;
3761 }
3762 
3763 /*
3764  * db_parameter_next() - This function returns the next parameter in a
3765  * parameter list or NULL if at the end of the parameter list. The
3766  * value given for param must not be NULL Returns the next parameter
3767  * in a parameter list or NULL if at the end of the list.
3768  * return : next parameter in a parameter list
3769  * param(in) : a parameter
3770  */
3771 DB_PARAMETER *
3773 {
3774  DB_PARAMETER *result = NULL;
3775 
3776  if (param)
3777  {
3778  result = pt_node_next (param);
3779  }
3780 
3781  return result;
3782 }
3783 
3784 /*
3785  * db_parameter_name() - This function returns the name for the given
3786  * parameter. param must not be a NULL value.
3787  * return : parameter name
3788  * param(in) : a parameter
3789  */
3790 const char *
3792 {
3793  const char *result = NULL;
3794 
3795  if (param)
3796  {
3797  result = pt_string_part (param);
3798  }
3799 
3800  return result;
3801 }
3802 
3803 /*
3804  * db_bind_parameter_name() -
3805  * return: error code
3806  * name(in) : parameter name
3807  * value(in) : value to be associated
3808  *
3809  * note : This function is analogous to other database vendors' use of the
3810  * term bind in that it is an association with a variable location.
3811  */
3812 int
3813 db_bind_parameter_name (const char *name, DB_VALUE * value)
3814 {
3815  return pt_associate_label_with_value_check_reference (name, value);
3816 }
3817 
3818 /*
3819  * db_query_produce_updatable_result() -
3820  * return:
3821  * session(in) :
3822  * stmt_ndx(in) :
3823  */
3824 int
3826 {
3827  PT_NODE *statement;
3828 
3829  /* obvious error checking - invalid parameter */
3830  if (!session || !session->parser)
3831  {
3833  return er_errid ();
3834  }
3835  /* no statement was given in the session */
3836  if (session->dimension == 0 || !session->statements)
3837  {
3839  return er_errid ();
3840  }
3841  /* invalid parameter */
3842  statement = session->statements[--stmt_ndx];
3843  if (stmt_ndx < 0 || stmt_ndx >= session->dimension || !statement)
3844  {
3846  return er_errid ();
3847  }
3848  /* check if the statement is compiled and prepared */
3849  if (session->stage[stmt_ndx] < StatementPreparedStage)
3850  {
3852  return er_errid ();
3853  }
3854 
3855  if (statement->node_type == PT_SELECT || statement->node_type == PT_UNION)
3856  {
3857  return statement->info.query.oids_included;
3858  }
3859  else
3860  {
3861  return false;
3862  }
3863 }
3864 
3865 /*
3866  * db_invalidate_mvcc_snapshot_before_statement () - When MVCC is enabled,
3867  * server uses a snapshot to
3868  * filter data. Snapshot is
3869  * obtained with the first
3870  * fetch or execution on
3871  * server and should be
3872  * invalidated before
3873  * executing a new statement.
3874  *
3875  * return : Void.
3876  *
3877  * NOTE: When Repeatable Reads and Serializable Isolation are implemented for
3878  * MVCC, snapshot must be invalidated only on commit/rollback.
3879  */
3880 void
3882 {
3884  {
3885  /* Do not invalidate snapshot after each statement */
3886  return;
3887  }
3888 
3889  /* set value of tm_Tran_invalidate_snapshot to 1 in order to invalidate the snapshot next time when we go to server. */
3890 
3892 
3893  /* Increment snapshot version in work space */
3895 }
3896 
3897 /*
3898  * db_set_read_fetch_instance_version () - Set read fetch instance version
3899  *
3900  * return : Void.
3901  * read_Fetch_Instance_Version(in): read fetch instance version to set
3902  */
3903 void
3905 {
3906  tm_Tran_read_fetch_instance_version = read_Fetch_Instance_Version;
3907 }
3908 
3909 /*
3910  * pt_has_modified_class -
3911  * return:
3912  *
3913  * parser(in):
3914  * statement(in/out):
3915  */
3918 {
3920 
3921  parser_walk_tree (parser, statement, pt_has_modified_class_helper, &status, NULL, NULL);
3922 
3923  return status;
3924 }
3925 
3926 /*
3927  * pt_has_modified_class_helper -
3928  * return:
3929  *
3930  * parser(in):
3931  * node(in/out):
3932  * arg(in/out):
3933  * continue_walk(in/out):
3934  */
3935 static PT_NODE *
3936 pt_has_modified_class_helper (PARSER_CONTEXT * parser, PT_NODE * node, void *arg, int *continue_walk)
3937 {
3939  PT_NODE *class_;
3940  MOP clsmop = NULL;
3941  SM_CLASS *sm_class = NULL;
3942  int error = NO_ERROR;
3943 
3944  if (*status != DB_CLASS_NOT_MODIFIED)
3945  {
3946  *continue_walk = PT_STOP_WALK;
3947  return node;
3948  }
3949 
3950  *continue_walk = PT_CONTINUE_WALK;
3951  if (node->node_type == PT_SPEC)
3952  {
3953  for (class_ = node->info.spec.flat_entity_list; class_; class_ = class_->next)
3954  {
3955  clsmop = class_->info.name.db_object;
3956 
3957  if (clsmop == NULL)
3958  {
3959  continue;
3960  }
3961 
3962  if (clsmop->decached)
3963  {
3964  /* the class might be aborted. */
3965  *status = DB_CLASS_MODIFIED;
3966  }
3967  else
3968  {
3969  error = au_fetch_class_force (clsmop, &sm_class, AU_FETCH_READ);
3970  if (error != NO_ERROR)
3971  {
3972  if (error == ER_HEAP_UNKNOWN_OBJECT)
3973  {
3974  /* the class might be dropped. */
3975  *status = DB_CLASS_MODIFIED;
3976  }
3977  else
3978  {
3979  *status = DB_CLASS_ERROR;
3980  }
3981  }
3982  }
3983  if (*status != DB_CLASS_NOT_MODIFIED)
3984  {
3985  /* don't revisit leaves */
3986  *continue_walk = PT_STOP_WALK;
3987  break;
3988  }
3989 
3990  if (sm_get_class_type (sm_class) != SM_CLASS_CT)
3991  {
3992  continue;
3993  }
3994 
3995  if (class_->info.name.db_object_chn == NULL_CHN)
3996  {
3998  }
3999  else if (class_->info.name.db_object_chn != locator_get_cache_coherency_number (clsmop))
4000  {
4001  *status = DB_CLASS_MODIFIED;
4002 
4003  /* don't revisit leaves */
4004  *continue_walk = PT_STOP_WALK;
4005  break;
4006  }
4007  }
4008  }
4009 
4010  return node;
4011 }
4012 
4013 /*
4014  * db_set_statement_auto_commit () - Init statement auto commit.
4015  *
4016  * return : error code.
4017  * session(in): compiled session
4018  * auto_commit(in): true, if auto commit
4019  *
4020  * Note: This function filters out the statements that can't be executed with commit. In order to execute statement
4021  * with commit, the following condition must be satisfied: autocommit mode, no other communication with server
4022  * is needed after executing query with commit. Thus, if query with commit is executed, the broker can't send
4023  * other fetch, flush or requests to server. However, the client can send various requests before executing
4024  * query with commit. Considering this, the optimization can't be applied for queries executed broker side
4025  * (triggers, views involved), queries having OID included, multi statements. Currently, the optimization
4026  * is used for SELECT/UPDATE/DELETE/INSERT. In future, we have to consider optimization for other query type.
4027  * Also, additional filters may be added later in this functions.
4028  */
4029 int
4030 db_set_statement_auto_commit (DB_SESSION * session, bool auto_commit)
4031 {
4032  PT_NODE *statement;
4033  int stmt_ndx;
4034  int error_code;
4035  bool has_user_trigger;
4036  int dimension;
4037 
4038  assert (session != NULL);
4039 
4040  /* check parameters */
4041  if (session->dimension == 0 || session->statements == NULL)
4042  {
4044  return er_errid ();
4045  }
4046 
4047  stmt_ndx = session->stmt_ndx - 1;
4048  statement = session->statements[stmt_ndx];
4049  if (stmt_ndx < 0 || stmt_ndx >= session->dimension || statement == NULL)
4050  {
4052  return er_errid ();
4053  }
4054 
4055  /* check if the statement is compiled and prepared */
4056  if (session->stage[stmt_ndx] < StatementPreparedStage)
4057  {
4059  return er_errid ();
4060  }
4061 
4062  /* Set parser auto commit. */
4063  session->parser->flag.is_auto_commit = auto_commit ? 1 : 0;
4064 
4065  /* Init statement auto commit. */
4066  statement->flag.use_auto_commit = 0;
4067 
4068  if (!auto_commit || !db_session_is_last_statement (session))
4069  {
4070  return NO_ERROR;
4071  }
4072 
4073  if (session->dimension > 1)
4074  {
4075  /* Search for select. */
4076  if (!session->parser->flag.is_holdable)
4077  {
4078  /* Check all statements. */
4079  dimension = session->dimension;
4080  }
4081  else
4082  {
4083  /* Check all statements, except the last one. */
4084  dimension = session->dimension - 1;
4085  }
4086 
4087  for (int i = 0; i < dimension; i++)
4088  {
4089  if (session->statements[i] != NULL && PT_IS_QUERY_NODE_TYPE (session->statements[i]->node_type))
4090  {
4091  /* Avoid situation when the driver requests data after closing cursors. */
4092  return NO_ERROR;
4093  }
4094  }
4095  }
4096 
4097  /* Check whether statement can use auto commit. */
4098  error_code = tr_has_user_trigger (&has_user_trigger);
4099  if (error_code != NO_ERROR)
4100  {
4101  return error_code;
4102  }
4103 
4104  if (has_user_trigger)
4105  {
4106  /* Triggers must be executed before commit. Disable optimization. */
4107  return NO_ERROR;
4108  }
4109 
4110  if (db_can_execute_statement_with_autocommit (session->parser, statement))
4111  {
4112  statement->flag.use_auto_commit = 1;
4113  }
4114 
4115  return NO_ERROR;
4116 }
4117 
4118 /*
4119  * db_can_execute_statement_with_autocommit () - Check whether the statement can be executed with commit.
4120  *
4121  * return : true, if the statement can be executed with commit.
4122  * parser(in): the parser
4123  * statement(in): the statement
4124  *
4125  */
4126 static bool
4128 {
4129  bool has_name_oid = false;
4130  int info_hints;
4131  PT_NODE *arg1, *arg2;
4132  bool can_execute_statement_with_commit;
4133 
4134  assert (parser != NULL && statement != NULL);
4135 
4136  /* Here you can add more statements, if you think that is safe to execute them with commit.
4137  * For now, we care about optimizing most common queries.
4138  */
4139  can_execute_statement_with_commit = false;
4140 
4141  switch (statement->node_type)
4142  {
4143  case PT_SELECT:
4144  /* Check whether the optimization can be used. Disable it, if several broker/server requests are needed. */
4145  if (!statement->info.query.oids_included && statement->info.query.into_list == NULL)
4146  {
4149  if ((statement->info.query.q.select.hint & info_hints) == 0)
4150  {
4151  (void) parser_walk_tree (parser, statement->info.query.q.select.list, pt_has_name_oid,
4152  &has_name_oid, NULL, NULL);
4153  if (!has_name_oid)
4154  {
4155  can_execute_statement_with_commit = true;
4156  }
4157  }
4158  }
4159  break;
4160 
4161  case PT_INSERT:
4162  /* Do not use optimization in case of insert execution on broker side */
4163  if (statement->info.insert.execute_with_commit_allowed)
4164  {
4165  can_execute_statement_with_commit = true;
4166  }
4167  break;
4168 
4169  case PT_UPDATE:
4170  /* Do not use optimization in case of update execution on broker side */
4171  if (statement->info.update.execute_with_commit_allowed)
4172  {
4173  can_execute_statement_with_commit = true;
4174  }
4175  break;
4176 
4177  case PT_DELETE:
4178  /* Do not use optimization in case of delete execution on broker side */
4179  if (statement->info.delete_.execute_with_commit_allowed)
4180  {
4181  /* If del_stmt_list is not null, we may need several broker/server requests */
4182  if (statement->info.delete_.del_stmt_list == NULL)
4183  {
4184  can_execute_statement_with_commit = true;
4185  }
4186  }
4187  break;
4188 
4189  case PT_MERGE:
4190  if (statement->info.merge.flags & PT_MERGE_INFO_SERVER_OP)
4191  {
4192  can_execute_statement_with_commit = true;
4193  }
4194  break;
4195 
4196  case PT_UNION:
4197  case PT_INTERSECTION:
4198  case PT_DIFFERENCE:
4199  arg1 = statement->info.query.q.union_.arg1;
4200  arg2 = statement->info.query.q.union_.arg2;
4201 
4202  /* At least one argument must be not null to enable the optimization. */
4203  if (arg1 != NULL)
4204  {
4205  if (arg2 != NULL)
4206  {
4207  if (db_can_execute_statement_with_autocommit (parser, arg1)
4208  && db_can_execute_statement_with_autocommit (parser, arg2))
4209  {
4210  can_execute_statement_with_commit = true;
4211  }
4212  }
4213  else if (db_can_execute_statement_with_autocommit (parser, arg1))
4214  {
4215  can_execute_statement_with_commit = true;
4216  }
4217  }
4218  else if (arg2 != NULL)
4219  {
4220  if (db_can_execute_statement_with_autocommit (parser, arg2))
4221  {
4222  can_execute_statement_with_commit = true;
4223  }
4224  }
4225  break;
4226 
4227  // TODO - what else? for instance, other dmls, ddls.
4228  default:
4229  break;
4230  }
4231 
4232  return can_execute_statement_with_commit;
4233 }
4234 
4235 int
4236 db_get_line_of_statement (DB_SESSION * session, int stmt_id)
4237 {
4238  assert (session->statements != NULL);
4239 
4240  // Safeguards
4241  if (stmt_id <= 0 || stmt_id > session->dimension || session->statements == NULL
4242  || session->statements[stmt_id - 1] == NULL)
4243  {
4244  // stmt_id is not valid.
4245  return -1;
4246  }
4247 
4248  // Get last statement
4249  return session->statements[stmt_id - 1]->line_number;
4250 }
unsigned decached
Definition: work_space.h:152
LC_FETCH_VERSION_TYPE
Definition: locator.h:178
PT_NODE * pt_name(PARSER_CONTEXT *parser_ptr, const char *name)
unsigned is_system_generated_stmt
Definition: parse_tree.h:3623
#define ER_QPROC_XASLNODE_RECOMPILE_REQUESTED
Definition: error_code.h:1595
#define pt_is_output_hostvar(n)
Definition: parse_tree.h:270
PT_NODE * pt_compile(PARSER_CONTEXT *parser, PT_NODE *volatile statement)
Definition: compile.c:380
PT_NODE * next
Definition: parse_tree.h:3447
PT_NAME_INFO name
Definition: parse_tree.h:3318
unsigned execute_with_commit_allowed
Definition: parse_tree.h:2079
int db_unpack_prepare_info(DB_PREPARE_INFO *info, char *buffer)
Definition: db_query.c:537
static PT_NODE * char_array_to_name_list(PARSER_CONTEXT *parser, char **names, int length)
Definition: db_vdb.c:2251
int db_open_buffer_and_compile_first_statement(const char *CSQL_query, DB_QUERY_ERROR *query_error, int include_oid, DB_SESSION **session, int *stmt_no)
Definition: db_vdb.c:3007
int db_make_datetime(DB_VALUE *value, const DB_DATETIME *datetime)
unsigned execute_with_commit_allowed
Definition: parse_tree.h:2348
#define PT_IS_QUERY(n)
Definition: parse_tree.h:296
#define WS_IS_DELETED(mop)
Definition: work_space.h:284
PT_NODE * pt_get_errors(PARSER_CONTEXT *parser)
#define NO_ERROR
Definition: error_code.h:46
PT_UNION_INFO union_
Definition: parse_tree.h:2782
int do_statement(PARSER_CONTEXT *parser, PT_NODE *statement)
static DB_SESSION * db_open_local(void)
Definition: db_vdb.c:151
int pt_host_var_index(const PT_NODE *hv)
bool pt_recompile_for_limit_optimizations(PARSER_CONTEXT *parser, PT_NODE *statement, int xasl_flag)
void er_stack_push(void)
PT_UPDATE_INFO update
Definition: parse_tree.h:3353
PT_MERGE_INFO merge
Definition: parse_tree.h:3315
PT_NODE * query
Definition: parse_tree.h:3162
PT_NODE ** parser_parse_string_use_sys_charset(PARSER_CONTEXT *parser, const char *buffer)
PT_STATEMENT_INFO info
Definition: parse_tree.h:3487
TP_DOMAIN * expected_domain
Definition: parse_tree.h:3452
DB_VALUE * vals
Definition: dbtype_def.h:1100
PT_NODE * into_list
Definition: parse_tree.h:2771
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
PARSER_CONTEXT * db_get_parser(DB_SESSION *session)
Definition: db_vdb.c:3714
void * parser_alloc(const PARSER_CONTEXT *parser, const int length)
Definition: parse_tree.c:951
DB_NODE * db_get_statement(DB_SESSION *session, int id)
Definition: db_vdb.c:3729
#define pt_is_input_hostvar(n)
Definition: parse_tree.h:269
int do_prepare_statement(PARSER_CONTEXT *parser, PT_NODE *statement)
DB_ATTRIBUTE * db_get_attributes(DB_OBJECT *obj)
Definition: db_info.c:908
#define ER_SM_NOT_A_VIRTUAL_CLASS
Definition: error_code.h:568
char * MOBJ
Definition: work_space.h:174
char ** into_list
Definition: db_query.h:152
PT_NODE * pt_node_next(const PT_NODE *node)
PT_NODE * pt_class_pre_fetch(PARSER_CONTEXT *parser, PT_NODE *statement)
Definition: compile.c:431
DB_QUERY_RESULT * pt_make_cache_hit_result_descriptor(void)
static bool is_allowed_as_prepared_statement(PT_NODE *node)
Definition: db_vdb.c:2811
DB_DOMAIN * pt_type_enum_to_db_domain(const PT_TYPE_ENUM t)
Definition: parse_dbi.c:1549
PT_NODE ** parser_parse_file(PARSER_CONTEXT *parser, FILE *file)
PT_NODE * mq_translate(PARSER_CONTEXT *parser, PT_NODE *volatile node)
void pt_report_to_ersys_with_statement(PARSER_CONTEXT *parser, const PT_ERROR_TYPE error_type, PT_NODE *statement)
Definition: query_result.c:338
unsigned use_query_cache
Definition: parse_tree.h:3469
PT_NODE * into_list
Definition: parse_tree.h:3164
int db_is_vclass(DB_OBJECT *op)
Definition: db_virt.c:681
DB_TYPE
Definition: dbtype_def.h:670
PT_NODE * pt_get_warnings(const PARSER_CONTEXT *parser)
#define ER_FAILED
Definition: error_code.h:47
void db_close_session_local(DB_SESSION *session)
Definition: db_vdb.c:3244
DB_TYPE db_type
Definition: db_query.h:60
DB_QUERY_RESULT * db_get_db_value_query_result(DB_VALUE *val)
Definition: db_query.c:1998
static void db_set_base_server_time(DB_VALUE *db_val)
Definition: db_vdb.c:489
PT_SPEC_INFO spec
Definition: parse_tree.h:3346
unsigned is_xasl_pinned_reference
Definition: parse_tree.h:3616
static void update_execution_values(PARSER_CONTEXT *parser, int result, CUBRID_STMT_TYPE statement_type)
Definition: db_vdb.c:2047
PT_NODE * pt_get_select_list(PARSER_CONTEXT *parser, PT_NODE *query)
Definition: query_result.c:404
PT_NODE * arg2
Definition: parse_tree.h:2664
static bool is_allowed_as_prepared_statement_with_hv(PT_NODE *node)
Definition: db_vdb.c:2835
#define ER_QPROC_INVALID_XASLNODE
Definition: error_code.h:532
DB_OBJLIST * ml_ext_alloc_link(void)
Definition: work_space.c:4777
int tr_has_user_trigger(bool *has_user_trigger)
static int values_list_to_values_array(PARSER_CONTEXT *parser, PT_NODE *values_list, DB_VALUE_ARRAY *values_array)
Definition: db_vdb.c:2073
void pt_reset_error(PARSER_CONTEXT *parser)
PT_NODE ** statements
Definition: parse_tree.h:3549
int db_query_end(DB_QUERY_RESULT *result)
Definition: db_query.c:3362
int db_make_object(DB_VALUE *value, DB_C_OBJECT *obj)
const char * pt_show_node_type(PT_NODE *node)
int au_check_user(void)
PT_NODE * pt_get_next_error(PT_NODE *errors, int *stmt_no, int *line_no, int *col_no, const char **msg)
PT_EXPR_INFO expr
Definition: parse_tree.h:3299
int db_is_any_class(MOP obj)
Definition: db_info.c:356
#define ER_IT_EMPTY_STATEMENT
Definition: error_code.h:502
PT_NODE ** statements
Definition: api_compat.h:38
PARSER_CONTEXT * parser_create_parser(void)
Definition: parse_tree.c:1169
PT_TYPE_ENUM pt_db_to_type_enum(const DB_TYPE t)
Definition: parse_dbi.c:2595
SM_CLASS_TYPE sm_get_class_type(SM_CLASS *class_)
struct pt_query_info::@123 flag
PT_EXECUTE_INFO execute
Definition: parse_tree.h:3297
int locator_get_cache_coherency_number(MOP mop)
Definition: locator_cl.c:2171
int db_get_start_line(DB_SESSION *session, int stmt)
Definition: db_vdb.c:1444
union pt_query_info::@124 q
static DB_SESSION * initialize_session(DB_SESSION *session)
Definition: db_vdb.c:190
PT_NODE * pt_bind_values_to_hostvars(PARSER_CONTEXT *parser, PT_NODE *node)
DB_DOMAIN * pt_node_to_db_domain(PARSER_CONTEXT *parser, PT_NODE *node, const char *class_name)
Definition: parse_dbi.c:2244
unsigned set_host_var
Definition: parse_tree.h:3605
void pt_set_host_variables(PARSER_CONTEXT *parser, int count, DB_VALUE *values)
Definition: parse_dbi.c:3086
int db_set_system_generated_statement(DB_SESSION *session)
Definition: db_vdb.c:3173
DB_SESSION * next
Definition: api_compat.h:42
unsigned is_auto_commit
Definition: parse_tree.h:3624
PT_NODE * jdbc_life_time
Definition: parse_tree.h:2702
int tm_Tran_invalidate_snapshot
int er_errid(void)
const char * pt_string_part(const PT_NODE *tbl)
PT_NODE * pt_count_output_markers(PARSER_CONTEXT *parser, PT_NODE *node, void *arg, int *continue_walk)
void locator_free_list_mops(LIST_MOPS *mops)
Definition: locator_cl.c:2978
void db_rewind_statement(DB_SESSION *session)
Definition: db_vdb.c:785
PT_NODE * pt_get_output_host_vars(const PT_HOST_VARS *hv)
#define ER_IT_INVALID_SESSION
Definition: error_code.h:501
DB_VALUE * host_variables
Definition: parse_tree.h:3560
static int do_recompile_and_execute_prepared_statement(DB_SESSION *session, PT_NODE *statement, DB_QUERY_RESULT **result)
Definition: db_vdb.c:2728
static void db_calculate_current_server_time(PARSER_CONTEXT *parser)
Definition: db_vdb.c:421
const char * db_attribute_name(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1065
void ws_increment_mvcc_snapshot_version(void)
Definition: work_space.c:4987
int db_attribute_is_shared(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1429
DB_CLASS_MODIFICATION_STATUS db_has_modified_class(DB_SESSION *session, int stmt_id)
Definition: db_vdb.c:2874
#define ER_UCI_TOO_FEW_HOST_VARS
Definition: error_code.h:541
PT_NODE * del_stmt_list
Definition: parse_tree.h:2073
DB_QUERY_RESULT * pt_new_query_result_descriptor(PARSER_CONTEXT *parser, PT_NODE *query)
void pt_free_query_etc_area(PARSER_CONTEXT *parser, PT_NODE *query)
struct parser_context::@134 flag
PT_NODE * pt_has_name_oid(PARSER_CONTEXT *parser, PT_NODE *node, void *arg, int *continue_walk)
static int get_dimension_of(PT_NODE **array)
Definition: db_vdb.c:108
DB_QUERY_TYPE * pt_fillin_type_size(PARSER_CONTEXT *parser, PT_NODE *query, DB_QUERY_TYPE *list, const int include_oid, bool want_spec_entity_name, bool fixup_columns_type)
Definition: query_result.c:893
int pt_associate_label_with_value_check_reference(const char *label, DB_VALUE *val)
DB_PARAMETER * db_get_parameters(DB_SESSION *session, int statement_id)
Definition: db_vdb.c:3744
int db_set_client_cache_time(DB_SESSION *session, int stmt_ndx, CACHE_TIME *cache_time)
Definition: db_vdb.c:813
int db_compile_statement_local(DB_SESSION *session)
Definition: db_vdb.c:510
DB_SESSION_ERROR * db_get_next_error(DB_SESSION_ERROR *errors, int *line, int *col)
Definition: db_vdb.c:953
#define MSGCAT_SEMANTIC_CANT_COERCE_TO
int dimension
Definition: api_compat.h:30
SERVER_INSERT_ALLOWED server_allowed
Definition: parse_tree.h:2347
int parse_one_statement(int state)
void parser_free_parser(PARSER_CONTEXT *parser)
Definition: parse_tree.c:1240
static int is_vclass_object(MOBJ class_)
Definition: db_vdb.c:3400
int qp_get_server_info(PARSER_CONTEXT *parser, int server_info_bits)
PT_TYPE_ENUM type_enum
Definition: parse_tree.h:3457
void pt_report_to_ersys(const PARSER_CONTEXT *parser, const PT_ERROR_TYPE error_type)
Definition: query_result.c:287
#define MAX_SERVER_TIME_CACHE
Definition: db_vdb.c:61
TP_DOMAIN_STATUS tp_value_cast_preserve_domain(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion, bool preserve_domain)
#define ER_PT_SEMANTIC
Definition: error_code.h:581
char ** db_get_lock_classes(DB_SESSION *session)
Definition: db_vdb.c:1573
unsigned char bytes[1]
Definition: parse_tree.h:3431
char oids_included
Definition: parse_tree.h:2750
bool is_subsession_for_prepared
Definition: api_compat.h:40
unsigned use_auto_commit
Definition: parse_tree.h:3485
int stmt_ndx
Definition: api_compat.h:31
PT_NODE ** pt_init_one_statement_parser(PARSER_CONTEXT *parser, FILE *file)
void * pt_node_etc(const PT_NODE *col)
DB_MARKER * db_marker_next(DB_MARKER *marker)
Definition: db_vdb.c:1238
unsigned int DB_TIMESTAMP
Definition: dbtype_def.h:759
const char * db_parameter_name(DB_PARAMETER *param)
Definition: db_vdb.c:3791
#define PT_MERGE_INFO_SERVER_OP
Definition: parse_tree.h:2947
void pt_free_statement_xasl_id(PT_NODE *statement)
PT_NODE * arg1
Definition: parse_tree.h:2663
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
DB_SELECT_RESULT s
Definition: db_query.h:124
DB_OBJECT * db_object
Definition: parse_tree.h:2546
#define PT_ERRORmf2(parser, node, setNo, msgNo, arg1, arg2)
Definition: parse_tree.h:65
#define XASL_ID_COPY(X1, X2)
Definition: xasl.h:562
int db_parse_one_statement(DB_SESSION *session)
Definition: db_vdb.c:298
#define assert(x)
#define BUF_SIZE
Definition: db_vdb.c:59
int errors
#define PT_IS_QUERY_NODE_TYPE(x)
Definition: parse_tree.h:115
DB_QUERY_TYPE * query_type
Definition: db_query.h:119
DB_VALUE * db_get_hostvars(DB_SESSION *session)
Definition: db_vdb.c:1562
DB_DOMAIN * db_marker_domain(DB_MARKER *marker)
Definition: db_vdb.c:1276
int prm_get_integer_value(PARAM_ID prm_id)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
static int db_execute_and_keep_statement_local(DB_SESSION *session, int stmt_ndx, DB_QUERY_RESULT **result)
Definition: db_vdb.c:1599
TP_DOMAIN ** host_var_expected_domains
Definition: db_query.h:148
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
PARSER_CONTEXT * parent_parser
DB_TYPE db_value_type(const DB_VALUE *value)
PT_DATA_VALUE data_value
Definition: parse_tree.h:3058
int xasl_flag
Definition: xasl.h:69
PT_NODE * flat_entity_list
Definition: parse_tree.h:2140
PT_NODE * top_node
Definition: parse_tree.h:1707
DB_VALUE_ARRAY host_variables
Definition: db_query.h:147
int db_execute_and_keep_statement(DB_SESSION *session, int stmt_ndx, DB_QUERY_RESULT **result)
Definition: db_vdb.c:2906
const char * original
Definition: parse_tree.h:2544
DB_MARKER * db_get_input_markers(DB_SESSION *session, int stmt)
Definition: db_vdb.c:1179
PT_HINT_ENUM hint
Definition: parse_tree.h:2707
PT_NODE * pt_make_string_value(PARSER_CONTEXT *parser, const char *value_string)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
int db_value_free(DB_VALUE *value)
Definition: db_macro.c:1610
DB_PARAMETER * db_parameter_next(DB_PARAMETER *param)
Definition: db_vdb.c:3772
DB_VALUE local_transaction_id
Definition: parse_tree.h:3583
PT_NODE_TYPE node_type
Definition: parse_tree.h:3439
PT_PREPARE_INFO prepare
Definition: parse_tree.h:3323
void db_drop_statement(DB_SESSION *session, int stmt)
Definition: db_vdb.c:3196
void db_session_set_holdable(DB_SESSION *session, bool holdable)
Definition: db_vdb.c:1040
bool db_get_jdbccachehint(DB_SESSION *session, int stmt_ndx, int *life_time)
Definition: db_vdb.c:844
#define CHECK_1ARG_NULL(obj)
Definition: db.h:171
PT_NODE * pt_semantic_type(PARSER_CONTEXT *parser, PT_NODE *tree, SEMANTIC_CHK_INFO *sc_info)
DB_VALUE sys_epochtime
Definition: parse_tree.h:3581
void db_init_prepare_info(DB_PREPARE_INFO *info)
Definition: db_query.c:411
DB_ATTRIBUTE * db_attribute_next(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1020
const char * db_query_spec_string(DB_QUERY_SPEC *query_spec)
Definition: db_virt.c:651
void db_session_set_return_generated_keys(DB_SESSION *session, bool return_generated_keys)
Definition: db_vdb.c:1075
int db_get_parser_line_col(DB_SESSION *session, int *line, int *col)
Definition: db_vdb.c:355
PT_NODE * pt_get_parameters(PARSER_CONTEXT *parser, PT_NODE *statement)
#define TP_DOMAIN_TYPE(dom)
void db_set_read_fetch_instance_version(LC_FETCH_VERSION_TYPE read_Fetch_Instance_Version)
Definition: db_vdb.c:3904
DB_VALUE * db_value_create(void)
Definition: db_macro.c:1517
DB_SESSION_WARNING * db_get_next_warning(DB_SESSION_WARNING *warnings, int *line, int *col)
Definition: db_vdb.c:1013
static int do_process_deallocate_prepare(DB_SESSION *session, PT_NODE *statement)
Definition: db_vdb.c:2798
struct db_query_type * next
Definition: db_query.h:54
void db_update_row_count_cache(const int row_count)
Definition: db_admin.c:2924
static void cleanup(int signo)
Definition: broker.c:717
PARSER_VARCHAR * str
Definition: parse_tree.h:3036
int db_execute_statement(DB_SESSION *session, int stmt_ndx, DB_QUERY_RESULT **result)
Definition: db_vdb.c:2978
SP_PARSER_CTX * parser
PT_NODE * arg1
Definition: parse_tree.h:2197
#define NULL
Definition: freelistheap.h:34
void db_session_set_xasl_cache_pinned(DB_SESSION *session, bool is_pinned, bool recompile)
Definition: db_vdb.c:1057
struct pr_type * type
Definition: object_domain.h:76
CACHE_TIME cache_time
Definition: parse_tree.h:3458
bool db_is_input_marker(DB_MARKER *marker)
Definition: db_vdb.c:1299
LC_FETCH_VERSION_TYPE tm_Tran_read_fetch_instance_version
unsigned recompile
Definition: parse_tree.h:3461
CUBRID_STMT_TYPE pt_node_to_cmd_type(PT_NODE *node)
Definition: parse_dbi.c:2736
int db_tm_encode(struct tm *c_time_struct, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:536
DB_SESSION * db_open_buffer(const char *buffer)
Definition: db_vdb.c:232
void db_include_oid(DB_SESSION *session, int include_oid)
Definition: db_vdb.c:1508
int db_compile_statement(DB_SESSION *session)
Definition: db_vdb.c:766
void db_drop_all_statements(DB_SESSION *session)
Definition: db_vdb.c:3218
void db_close_session(DB_SESSION *session)
Definition: db_vdb.c:3319
int csession_create_prepared_statement(const char *name, const char *alias_print, char *stmt_info, int info_length)
static void db_calculate_current_time(struct timeb *tb)
Definition: db_vdb.c:402
DB_SESSION * db_open_buffer_local(const char *buffer)
Definition: db_vdb.c:205
void db_free_query(DB_SESSION *session)
Definition: db_vdb.c:3683
DB_SESSION_WARNING * db_get_warnings(DB_SESSION *session)
Definition: db_vdb.c:985
int pt_is_server_insert_with_generated_keys(PARSER_CONTEXT *parser, PT_NODE *statement)
unsigned recompile_xasl_pinned
Definition: parse_tree.h:3620
PT_HOST_VARS * pt_host_info(PARSER_CONTEXT *parser, PT_NODE *stmt)
void pt_end_query(PARSER_CONTEXT *parser, QUERY_ID query_id_self)
PT_CREATE_ENTITY_INFO create_entity
Definition: parse_tree.h:3279
#define err(fd,...)
Definition: porting.h:431
int db_value_clear_array(DB_VALUE_ARRAY *value_array)
Definition: db_macro.c:1633
PT_NODE ** parser_parse_string_with_escapes(PARSER_CONTEXT *parser, const char *buffer, const bool strings_have_no_escapes)
enum db_class_modification_status DB_CLASS_MODIFICATION_STATUS
void pt_null_etc(PT_NODE *node)
PT_NODE * pt_add_row_oid(PARSER_CONTEXT *parser, PT_NODE *statement)
Definition: compile.c:333
int csession_delete_prepared_statement(const char *name)
PT_QUERY_INFO query
Definition: parse_tree.h:3325
struct db_objlist * next
Definition: dbtype_def.h:442
DB_QUERY_TYPE * db_alloc_query_format(int cnt)
Definition: db_query.c:807
unsigned is_holdable
Definition: parse_tree.h:3615
PT_UPDATABILITY mq_updatable(PARSER_CONTEXT *parser, PT_NODE *statement)
static int set_prepare_info_into_list(DB_PREPARE_INFO *prepare_info, PT_NODE *statement)
Definition: db_vdb.c:2168
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
int pr_clear_value(DB_VALUE *value)
void db_free_query_format(DB_QUERY_TYPE *q)
Definition: db_query.c:154
unsigned is_in_and_list
Definition: parse_tree.h:3611
bool db_is_output_marker(DB_MARKER *marker)
Definition: db_vdb.c:1318
DB_TYPE pt_node_to_db_type(PT_NODE *node)
Definition: parse_dbi.c:2453
static char * get_reasonable_predicate(DB_ATTRIBUTE *att)
Definition: db_vdb.c:3497
TP_DOMAIN ** host_var_expected_domains
Definition: parse_tree.h:3561
static DB_CLASS_MODIFICATION_STATUS pt_has_modified_class(PARSER_CONTEXT *parser, PT_NODE *statement)
Definition: db_vdb.c:3917
DB_QUERY_TYPE * db_cp_query_type(DB_QUERY_TYPE *query_type, int copy_only_user)
Definition: db_query.c:1329
void er_stack_pop(void)
char include_oid
Definition: api_compat.h:29
#define ER_PT_EXECUTE
Definition: error_code.h:582
unsigned si_datetime
Definition: parse_tree.h:3464
PT_NODE * parser_append_node(PT_NODE *node, PT_NODE *list)
static int do_get_prepared_statement_info(DB_SESSION *session, int stmt_idx)
Definition: db_vdb.c:2410
struct db_object * op
Definition: dbtype_def.h:443
void util_get_second_and_ms_since_epoch(time_t *secs, int *msec)
Definition: util_func.c:829
unsigned do_not_cache
Definition: parse_tree.h:2764
#define TP_IS_CHAR_TYPE(typeid)
int db_session_is_last_statement(DB_SESSION *session)
Definition: db_vdb.c:799
LIST_MOPS * locator_get_all_class_mops(DB_FETCH_MODE purpose, int(*fun)(MOBJ class_obj))
Definition: locator_cl.c:2861
static void error(const char *msg)
Definition: gencat.c:331
int db_get_statement_type(DB_SESSION *session, int stmt)
Definition: db_vdb.c:1473
int do_execute_statement(PARSER_CONTEXT *parser, PT_NODE *statement)
DB_OBJLIST * db_get_all_vclasses(void)
Definition: db_vdb.c:3423
static int rc
Definition: serial.c:50
unsigned is_system_generated_stmt
Definition: parse_tree.h:3484
DB_OBJLIST * db_get_all_vclasses_on_ldb(void)
Definition: db_vdb.c:3412
int pt_statement_line_number(const PT_NODE *stmt)
DB_QUERY_TYPE ** type_list
Definition: api_compat.h:36
#define CHECK_CONNECT_NULL()
Definition: db.h:91
#define ARG_FILE_LINE
Definition: error_manager.h:44
#define ER_IT_INCORRECT_HOSTVAR_COUNT
Definition: error_code.h:1247
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
void parser_free_tree(PARSER_CONTEXT *parser, PT_NODE *tree)
Definition: dbi.h:57
int db_pack_prepare_info(const DB_PREPARE_INFO *info, char **buffer)
Definition: db_query.c:433
int db_number_of_output_markers(DB_SESSION *session, int stmt)
Definition: db_vdb.c:1152
static PT_NODE * pt_has_modified_class_helper(PARSER_CONTEXT *parser, PT_NODE *tree, void *arg, int *continue_walk)
Definition: db_vdb.c:3936
bool db_get_cacheinfo(DB_SESSION *session, int stmt_ndx, bool *use_plan_cache, bool *use_query_cache)
Definition: db_vdb.c:878
unsigned int DB_TIME
Definition: dbtype_def.h:754
unsigned clt_cache_reusable
Definition: parse_tree.h:3467
PT_NODE * pt_resolve_names(PARSER_CONTEXT *parser, PT_NODE *statement, SEMANTIC_CHK_INFO *sc_info)
#define MSGCAT_SET_PARSER_SEMANTIC
DB_COL_TYPE col_type
Definition: db_query.h:55
CUBRID_STMT_TYPE
Definition: cas_dbms_util.h:40
PT_NODE * name
Definition: parse_tree.h:3154
DB_VALUE sys_datetime
Definition: parse_tree.h:3580
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define strlen(s1)
Definition: intl_support.c:43
int db_datetime_encode(DB_DATETIME *datetime, int month, int day, int year, int hour, int minute, int second, int millisecond)
Definition: db_date.c:4597
static struct timeb base_client_timeb
Definition: db_vdb.c:72
PT_NODE * pt_get_input_host_vars(const PT_HOST_VARS *hv)
unsigned si_tran_id
Definition: parse_tree.h:3465
PARSER_CONTEXT * parser
Definition: api_compat.h:35
int db_value_precision(const DB_VALUE *value)
#define ER_OBJ_INVALID_ARGUMENTS
Definition: error_code.h:275
int db_push_values(DB_SESSION *session, int count, DB_VALUE *in_values)
Definition: db_vdb.c:1527
PT_NODE ** node_stack
Definition: parse_tree.h:3544
PT_MISC_TYPE entity_type
Definition: parse_tree.h:1899
int db_validate(DB_OBJECT *vc)
Definition: db_vdb.c:3573
int db_check_single_query(DB_SESSION *session)
Definition: db_vdb.c:3695
unsigned int date
Definition: dbtype_def.h:776
MOP mops[1]
Definition: locator_cl.h:67
#define ER_HEAP_UNKNOWN_OBJECT
Definition: error_code.h:102
unsigned clt_cache_check
Definition: parse_tree.h:3466
static bool db_check_limit_need_recompile(PARSER_CONTEXT *parser, PT_NODE *statement, int xasl_flag)
Definition: db_vdb.c:2647
char * statement
Definition: db_query.h:144
static bool db_can_execute_statement_with_autocommit(PARSER_CONTEXT *parser, PT_NODE *statement)
Definition: db_vdb.c:4127
void ml_ext_free(DB_OBJLIST *list)
Definition: work_space.c:4806
int db_get_variable(DB_VALUE *name, DB_VALUE *value)
Definition: db_admin.c:1072
int auto_param_count
Definition: db_query.h:149
void er_clear(void)
DB_QUERY_TYPE * db_get_query_type_list(DB_SESSION *session, int stmt_ndx)
Definition: db_vdb.c:1341
int line_offset
Definition: api_compat.h:33
unsigned cannot_prepare
Definition: parse_tree.h:3462
PT_DELETE_INFO delete_
Definition: parse_tree.h:3285
static void copy_execution_values(EXECUTION_STATE_VALUES *source, EXECUTION_STATE_VALUES *destination)
Definition: db_vdb.c:2066
unsigned execute_with_commit_allowed
Definition: parse_tree.h:2884
DB_TYPE db_attribute_type(DB_ATTRIBUTE *attribute)
Definition: db_info.c:1000
int i
Definition: dynamic_load.c:954
PT_VALUE_INFO value
Definition: parse_tree.h:3358
int db_marker_index(DB_MARKER *marker)
Definition: db_vdb.c:1257
int pt_length_of_select_list(PT_NODE *list, int hidden_col)
int db_make_null(DB_VALUE *value)
void pt_free_host_info(PT_HOST_VARS *hv)
unsigned use_plan_cache
Definition: parse_tree.h:3468
int db_compile_and_execute_local(const char *CSQL_query, void *result, DB_QUERY_ERROR *query_error)
Definition: db_vdb.c:3068
DB_TYPE id
PT_NODE * list
Definition: parse_tree.h:2685
#define DB_IS_NULL(value)
Definition: dbtype.h:63
DB_QUERY_TYPE * columns
Definition: db_query.h:145
#define XASL_ID_IS_NULL(X)
Definition: xasl.h:560
DB_QUERY_SPEC * db_get_query_specs(DB_OBJECT *obj)
Definition: db_virt.c:608
XASL_ID * xasl_id
Definition: parse_tree.h:3454
PT_OP_TYPE op
Definition: parse_tree.h:2200
DB_MARKER * db_get_output_markers(DB_SESSION *session, int stmt)
Definition: db_vdb.c:1209
#define ER_IT_MULTIPLE_STATEMENT
Definition: error_code.h:513
DB_DATETIME * db_get_datetime(const DB_VALUE *value)
int db_validate_query_spec(DB_OBJECT *vclass, const char *query_spec)
Definition: db_vdb.c:3441
static struct timeb base_server_timeb
Definition: db_vdb.c:71
int db_execute_statement_local(DB_SESSION *session, int stmt_ndx, DB_QUERY_RESULT **result)
Definition: db_vdb.c:2939
unsigned return_generated_keys
Definition: parse_tree.h:3622
DB_SESSION * db_open_file_name(const char *name)
Definition: db_vdb.c:376
bool do_Trigger_involved
MOP sm_Root_class_mop
#define PT_INTERNAL_ERROR(parser, what)
Definition: parse_tree.h:112
static int do_cast_host_variables_to_expected_domain(DB_SESSION *session)
Definition: db_vdb.c:2545
DB_QUERY_TYPE * db_get_query_type_ptr(DB_QUERY_RESULT *result)
Definition: db_vdb.c:1431
int db_value_clear(DB_VALUE *value)
Definition: db_macro.c:1588
int db_make_timestamp(DB_VALUE *value, const DB_C_TIMESTAMP timeval)
#define pt_has_error(parser)
Definition: parser.h:507
const char * alias_print
Definition: parse_tree.h:3455
#define ER_DO_UNKNOWN_HOSTVAR_TYPE
Definition: error_code.h:1083
char * stage
Definition: api_compat.h:28
PT_NODE * mq_reset_ids_in_statement(PARSER_CONTEXT *parser, PT_NODE *statement)
DB_QUERY_TYPE * pt_get_titles(PARSER_CONTEXT *parser, PT_NODE *query)
Definition: query_result.c:642
#define ER_PT_ERROR
Definition: error_code.h:579
PT_NODE * using_list
Definition: parse_tree.h:3163
static int do_set_user_host_variables(DB_SESSION *session, PT_NODE *using_list)
Definition: db_vdb.c:2602
int db_get_line_of_statement(DB_SESSION *session, int stmt_id)
Definition: db_vdb.c:4236
#define ER_CANNOT_PREPARE_WITH_HOST_VAR
Definition: error_code.h:1372
int db_set_statement_auto_commit(DB_SESSION *session, bool auto_commit)
Definition: db_vdb.c:4030
void db_invalidate_mvcc_snapshot_before_statement(void)
Definition: db_vdb.c:3881
int pt_length_of_list(const PT_NODE *list)
CUBRID_STMT_TYPE stmt_type
Definition: parse_tree.h:3166
struct parser_node::@132 flag
#define ER_IT_IS_DISALLOWED_AS_PREPARED
Definition: error_code.h:1245
PT_NODE * name
Definition: parse_tree.h:3161
PT_NODE * statement
Definition: parse_tree.h:3155
PT_SELECT_INFO select
Definition: parse_tree.h:2781
DB_VALUE * pt_value_to_db(PARSER_CONTEXT *parser, PT_NODE *value)
Definition: parse_dbi.c:1088
int db_number_of_input_markers(DB_SESSION *session, int stmt)
Definition: db_vdb.c:1125
int csession_get_prepared_statement(const char *name, XASL_ID *xasl_id, char **stmt_info, xasl_node_header *xasl_header_p)
#define XASL_ID_SET_NULL(X)
Definition: xasl.h:546
void pt_free_orphans(PARSER_CONTEXT *parser)
int db_query_produce_updatable_result(DB_SESSION *session, int stmt_ndx)
Definition: db_vdb.c:3825
char ** lcks_classes
Definition: parse_tree.h:3573
PT_INSERT_INFO insert
Definition: parse_tree.h:3309
DB_SESSION_ERROR * db_get_errors(DB_SESSION *session)
Definition: db_vdb.c:926
PT_NODE * parser_walk_tree(PARSER_CONTEXT *parser, PT_NODE *node, PT_NODE_WALK_FUNCTION pre_function, void *pre_argument, PT_NODE_WALK_FUNCTION post_function, void *post_argument)
#define CHECK_CONNECT_MINUSONE()
Definition: db.h:100
#define PT_IS_NAME_NODE(n)
Definition: parse_tree.h:320
static DB_OBJLIST * db_get_all_chosen_classes(int(*p)(MOBJ o))
Definition: db_vdb.c:3337
CUBRID_STMT_TYPE stmt_type
Definition: db_query.h:146
PT_NODE * parser_copy_tree_list(PARSER_CONTEXT *parser, PT_NODE *tree)
#define ER_OBJ_NOT_A_CLASS
Definition: error_code.h:288
QUERY_ID query_id
Definition: parse_tree.h:3559
int au_fetch_class_force(MOP op, SM_CLASS **class_, AU_FETCHMODE fetchmode)
const char ** p
Definition: dynamic_load.c:945
DB_SESSION * db_open_file(FILE *file)
Definition: db_vdb.c:251
void tp_domain_free(TP_DOMAIN *dom)
int db_statement_count(DB_SESSION *session)
Definition: db_vdb.c:132
int db_compile_and_execute_queries_internal(const char *CSQL_query, void *result, DB_QUERY_ERROR *query_error, int include_oid, int execute, bool is_new_statement)
Definition: db_vdb.c:3096
static int do_process_prepare_statement(DB_SESSION *session, PT_NODE *statement)
Definition: db_vdb.c:2274
unsigned int time
Definition: dbtype_def.h:777
int db_query_tuple_count(DB_QUERY_RESULT *result)
Definition: db_query.c:3089
#define TM_TRAN_ISOLATION()
#define CHECK_CONNECT_ERROR()
Definition: db.h:88
int pt_validate_query_spec(PARSER_CONTEXT *parser, PT_NODE *s, struct db_object *c)
DB_SESSION * db_make_session_for_one_statement_execution(FILE *file)
Definition: db_vdb.c:276
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
int db_get_line_col_of_1st_error(DB_SESSION *session, DB_QUERY_ERROR *linecol)
Definition: db_vdb.c:1095
union db_query_result::@47 res
int db_bind_parameter_name(const char *name, DB_VALUE *value)
Definition: db_vdb.c:3813
DB_QUERY_SPEC * db_query_spec_next(DB_QUERY_SPEC *query_spec)
Definition: db_virt.c:632
EXECUTION_STATE_VALUES execution_values
Definition: parse_tree.h:3562