CUBRID Engine  latest
csql.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  * csql.c : csql main module
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <stdio.h>
28 #include <fcntl.h>
29 #include <limits.h>
30 #include <assert.h>
31 #if defined(WINDOWS)
32 #include <direct.h>
33 #include <io.h>
34 #include <winsock2.h>
35 #include <ws2tcpip.h>
36 #else /* !WINDOWS */
37 #include <sys/time.h>
38 #include <sys/errno.h>
39 #include <signal.h>
40 #include <wctype.h>
41 #include <editline/readline.h>
42 #include <sys/socket.h>
43 #include <arpa/inet.h>
44 #include <netdb.h>
45 #endif /* !WINDOWS */
46 
47 #include "authenticate.h"
48 #include "csql.h"
49 #include "filesys.hpp"
50 #include "filesys_temp.hpp"
51 #include "system_parameter.h"
52 #include "message_catalog.h"
53 #include "porting.h"
54 #include "release_string.h"
55 #include "error_manager.h"
56 #include "language_support.h"
57 #include "network.h"
58 #include "schema_manager.h"
59 #include "optimizer.h"
60 #include "environment_variable.h"
61 #include "tcp.h"
62 #include "db.h"
63 #include "parser.h"
64 #include "network_interface_cl.h"
65 #include "utility.h"
66 #include "tsc_timer.h"
67 #include "dbtype.h"
68 #include "jsp_cl.h"
69 #include "api_compat.h"
70 #include "cas_log.h"
71 #include "ddl_log.h"
72 
73 #if defined(WINDOWS)
74 #include "file_io.h" /* needed for _wyield() */
75 #endif /* WINDOWS */
76 
77 #if defined (SUPPRESS_STRLEN_WARNING)
78 #define strlen(s1) ((int) strlen(s1))
79 #endif /* defined (SUPPRESS_STRLEN_WARNING) */
80 
81 /* input type specification for csql_execute_statements() */
82 enum
83 {
84  FILE_INPUT = 0, /* FILE stream */
85  STRING_INPUT = 1, /* null-terminated string */
86  EDITOR_INPUT = 2 /* command buffer */
87 };
88 
89 /* the return value of csql_do_session_cmd() */
90 enum
91 {
95 };
96 
97 #define CSQL_SESSION_COMMAND_PREFIX(C) (((C) == ';') || ((C) == '!'))
98 
99 /* size of input buffer */
100 #define LINE_BUFFER_SIZE (4000)
101 #define COLUMN_WIDTH_INFO_LIST_INIT_SIZE 24
102 #define NOT_FOUND -1
103 
104 #if defined (ENABLE_UNUSED_FUNCTION)
105 #if !defined(WINDOWS)
106 /* current max keyword is 16 + nul char + 3 for expansion */
107 
108 static int csql_Keyword_num;
109 static KEYWORD_RECORD *csql_Keyword_list;
110 #endif /* !WINDOWS */
111 #endif /* ENABLE_UNUSED_FUNCTION */
112 
113 int (*csql_text_utf8_to_console) (const char *, const int, char **, int *) = NULL;
114 
115 int (*csql_text_console_to_utf8) (const char *, const int, char **, int *) = NULL;
116 
119 
120 /* command editor lines */
121 int csql_Line_lwm = -1;
122 
123 /* default environment command names */
124 char csql_Print_cmd[PATH_MAX] = "lpr";
125 char csql_Pager_cmd[PATH_MAX] = "more"; /* PAGER does not work on WINDOWS */
126 #if defined(WINDOWS)
127 char csql_Editor_cmd[PATH_MAX] = "notepad";
128 #else
129 char csql_Editor_cmd[PATH_MAX] = "vi";
130 #endif
131 
132 #if defined(WINDOWS)
133 char csql_Shell_cmd[PATH_MAX] = "command.com";
134 #else
135 char csql_Shell_cmd[PATH_MAX] = "csh";
136 #endif
137 
138 /* tty file stream which is used for conversation with users.
139  * In batch mode, this will be set to "/dev/null"
140  */
141 static FILE *csql_Tty_fp = NULL;
142 
143 /* scratch area to make a message text to be displayed.
144  * NOTE: Never put chars more than sizeof(csql_Scratch_text).
145  */
147 
149 
150 static char csql_Prompt[100];
151 static char csql_Name[100];
152 
153 /*
154  * Handles for the various files
155  */
159 
160 /*
161  * Global longjmp environment to terminate the csql() interpreter in the
162  * event of fatal error. This should be used rather than calling
163  * exit(), primarily for the Windows version of the interpreter.
164  *
165  * Set csql_Exit_status to the numeric status code to be returned from
166  * the csql() function after the longjmp has been performed.
167  */
168 static jmp_buf csql_Exit_env;
169 static int csql_Exit_status = EXIT_SUCCESS;
170 
171 /* this is non-zero if there is a dangling connection to a database */
172 static bool csql_Database_connected = false;
173 
174 static bool csql_Is_interactive = false;
175 static bool csql_Is_sigint_caught = false;
176 static bool csql_Is_echo_on = false;
177 enum
180 static bool csql_Is_time_on = true;
181 
182 static jmp_buf csql_Jmp_buf;
183 
187 
188 static bool csql_Query_trace = false;
189 
190 #if defined (ENABLE_UNUSED_FUNCTION)
191 #if !defined(WINDOWS)
192 static char *csql_keyword_generator (const char *text, int state);
193 static char **csql_cmd_completion_handler (const char *text, int start, int end);
194 static void init_readline ();
195 #endif /* ! WINDOWS */
196 #endif /* ENABLE_UNUSED_FUNCTION */
197 
198 static void free_csql_column_width_info_list ();
200 static int get_column_name_argument (char **column_name, char **val_str, char *argument);
201 static void csql_pipe_handler (int sig_no);
202 static void display_buffer (void);
203 static void start_csql (CSQL_ARGUMENT * csql_arg);
204 static void csql_read_file (const char *file_name);
205 static void csql_write_file (const char *file_name, int append_flag);
206 static void display_error (DB_SESSION * session, int stmt_start_line_no);
207 static void free_attr_spec (DB_QUERY_TYPE ** attr_spec);
208 static void csql_print_database (void);
209 static void csql_set_sys_param (const char *arg_str);
210 static void csql_get_sys_param (const char *arg_str);
211 static void csql_set_plan_dump (const char *arg_str);
212 static void csql_exit_init (void);
213 static void csql_exit_cleanup (void);
214 static void csql_print_buffer (void);
215 static void csql_change_working_directory (const char *dirname);
216 static void csql_exit_session (int error);
217 
218 static int csql_execute_statements (const CSQL_ARGUMENT * csql_arg, int type, const void *stream, int line_no);
219 
220 static char *csql_get_external_command (SESSION_CMD cmd_no);
221 static int csql_do_session_cmd (char *line_read, CSQL_ARGUMENT * csql_arg);
222 static void csql_set_trace (const char *arg_str);
223 static void csql_display_trace (void);
224 static bool csql_is_auto_commit_requested (const CSQL_ARGUMENT * csql_arg);
225 static int get_host_ip (unsigned char *ip_addr);
226 
227 #if defined (ENABLE_UNUSED_FUNCTION)
228 #if !defined(WINDOWS)
229 /*
230  * for readline keyword completion
231  */
232 /*
233  * csql_keyword_generator()
234  * return: char*
235  * text(in)
236  * state(in)
237  */
238 static char *
239 csql_keyword_generator (const char *text, int state)
240 {
241  static int list_index, len;
242 
243  /* If this is a new word to complete, initialize now. This includes saving the length of TEXT for efficiency, and
244  * initializing the index variable to 0. */
245  if (!state)
246  {
247  list_index = 0;
248  len = strlen (text);
249  }
250  if (len == 0)
251  {
252  return ((char *) NULL);
253  }
254  if (csql_Keyword_list == NULL)
255  {
256  return ((char *) NULL);
257  }
258 
259  /* Return the next name which partially matches from the keyword list. */
260  while (list_index < csql_Keyword_num)
261  {
262  if (strncasecmp ((csql_Keyword_list + list_index)->keyword, text, len) == 0)
263  {
264  char *ret_str = strdup ((csql_Keyword_list + list_index)->keyword);
265  list_index++;
266  return ret_str;
267  }
268 
269  list_index++;
270  }
271 
272  /* If no keyword matched, then return NULL. */
273  return ((char *) NULL);
274 }
275 
276 /*
277  * csql_cmd_completion_handler()
278  * return: char**
279  * text(in)
280  * start(in)
281  * end(in)
282  */
283 static char **
284 csql_cmd_completion_handler (const char *text, int start, int end)
285 {
286  char **matches;
287 
288  matches = (char **) NULL;
289  matches = completion_matches (text, csql_keyword_generator);
290  rl_attempted_completion_over = 1;
291 
292  return (matches);
293 }
294 
295 /*
296  * init_readline() - initialize libedit module
297  * return: none
298  */
299 static void
300 init_readline ()
301 {
302  rl_attempted_completion_function = csql_cmd_completion_handler;
303 }
304 #endif /* !WINDOWS */
305 #endif /* ENABLE_UNUSED_FUNCTION */
306 
307 /*
308  * free_csql_column_width_info_list() - free csql_column_width_info_list
309  * return: void
310  */
311 static void
313 {
314  int i;
315 
316  if (csql_column_width_info_list == NULL)
317  {
320 
321  return;
322  }
323 
324  for (i = 0; i < csql_column_width_info_list_size; i++)
325  {
326  if (csql_column_width_info_list[i].name != NULL)
327  {
328  free_and_init (csql_column_width_info_list[i].name);
329  }
330  }
331 
332  if (csql_column_width_info_list != NULL)
333  {
334  free_and_init (csql_column_width_info_list);
335  }
336 
337  csql_column_width_info_list_size = 0;
339 }
340 
341 /*
342  * initialize_csql_column_width_info_list() - initialize csql_column_width_info_list
343  * return: int
344  */
345 static int
347 {
348  int i;
349 
350  csql_column_width_info_list =
352  if (csql_column_width_info_list == NULL)
353  {
355 
356  return CSQL_FAILURE;
357  }
358 
361  for (i = 0; i < csql_column_width_info_list_size; i++)
362  {
363  csql_column_width_info_list[i].name = NULL;
364  csql_column_width_info_list[i].width = 0;
365  }
366 
367  return CSQL_SUCCESS;
368 }
369 
370 /*
371  * csql_display_msg() - displays the given msg to output device
372  * return: none
373  * string(in)
374  */
375 void
376 csql_display_msg (const char *string)
377 {
378  csql_fputs ("\n", csql_Tty_fp);
380  csql_fputs ("\n", csql_Tty_fp);
381 }
382 
383 /*
384  * csql_pipe_handler() generic longjmp'ing signal handler used
385  * where we need to catch broken pipe.
386  * return: none
387  * sig_no(in)
388  */
389 static void
390 csql_pipe_handler (int sig_no)
391 {
392  longjmp (csql_Jmp_buf, 1);
393 }
394 
395 /*
396  * display_buffer() - display command buffer into stdout
397  * return: none
398  */
399 static void
401 {
402  int l = 1;
403  FILE *pf;
404 #if !defined(WINDOWS)
405  void (*csql_pipe_save) (int);
406 #endif /* !WINDOWS */
407 
408 #if !defined(WINDOWS)
409  /* There is no SIGPIPE on WINDOWS */
411 #endif /* !WINDOWS */
412  if (setjmp (csql_Jmp_buf) == 0)
413  {
414  char *edit_contents, *p;
416 
417  edit_contents = csql_edit_contents_get ();
418 
419  putc ('\n', pf);
420  while (edit_contents != NULL && *edit_contents != '\0')
421  {
422  fprintf (pf, "%4d ", l++);
423  p = strchr (edit_contents, '\n');
424  if (p)
425  {
426  fwrite (edit_contents, 1, p - edit_contents, pf);
427  edit_contents = p + 1;
428  }
429  else
430  {
431  fwrite (edit_contents, 1, strlen (edit_contents), pf);
432  edit_contents = NULL;
433  }
434  fprintf (pf, "\n");
435  }
436  putc ('\n', pf);
437 
439  }
440 #if !defined(WINDOWS)
441  (void) os_set_signal_handler (SIGPIPE, csql_pipe_save);
442 #endif /* !WINDOWS */
443 }
444 
445 
446 
447 /*
448  * start_csql()
449  * return: none
450  * sql_arg(in/out): CSQL_ARGUMENT structure
451  *
452  * Note:
453  * There are four file pointers associated
454  * stdin - input source
455  * stdout - output file stream
456  * stderr - error message file stream
457  * tty_fp - conversation terminal file stream.
458  * either NULL or stderr
459  *
460  * if -o is given, the output file descriptor is duplicated to STDOU_FILENO.
461  * Also, if -i is given, -c is given or stdin is not a tty,
462  * `tty_fp' will be set to NULL. (No conversational messages)
463  * Otherwise, `tty_fp' will be set to stderr
464  *
465  * If `single_line_execution' is true, it attemts to execute as soon as
466  * it get a line. There is command buffer associated. This is effective
467  * only when INTERACTIVE mode (stdin is tty).
468  * If `command' is not NULL, it'll execute the command and exit and
469  * `-i' option, preceding pipe (if any), `-s' option had no effect.
470  */
471 static void
473 {
474  unsigned char line_buf[LINE_BUFFER_SIZE];
475  unsigned char utf8_line_buf[INTL_UTF8_MAX_CHAR_SIZE * LINE_BUFFER_SIZE];
476  char *line_read = NULL;
477  int line_length;
478  int line_no;
479  char *ptr; /* loop pointer */
480  char *line_read_alloced = NULL;
481  bool is_first_read_line = true;
482  bool read_whole_line;
483 
484  /* check in string block or comment block or identifier block */
485  bool is_in_block = false;
486 
488  if (csql_arg->column_output && csql_arg->line_output)
489  {
491  goto fatal_error;
492  }
493 
494  csql_Output_fp = stdout;
495 
496  if (csql_arg->out_file_name != NULL)
497  {
498  csql_Output_fp = fopen (csql_arg->out_file_name, "w");
499  if (csql_Output_fp == NULL)
500  {
502  goto fatal_error;
503  }
504  }
505 
507  {
508  goto fatal_error;
509  }
510 
511  /* For batch file input and csql command argument input */
512  csql_Tty_fp = NULL;
513  if (csql_arg->command)
514  {
515  /* command input */
516  csql_exit_session (csql_execute_statements (csql_arg, STRING_INPUT, csql_arg->command, -1));
517  }
518 
519  if (!csql_Is_interactive && !csql_arg->single_line_execution)
520  {
522  }
523 
524  /* Start interactive conversation or single line execution */
526  {
528 
530  {
532 
533  if (tc != NULL)
534  {
537  }
538  }
539  }
540 
541  /* display product title */
544 
547 
548 #if !defined(WINDOWS)
550  {
551 #if defined (ENABLE_UNUSED_FUNCTION)
552  init_readline ();
553 #endif /* ENABLE_UNUSED_FUNCTION */
555  using_history ();
556 #if defined (ENABLE_UNUSED_FUNCTION)
557  csql_Keyword_list = pt_get_keyword_rec (&csql_Keyword_num);
558 #endif /* ENABLE_UNUSED_FUNCTION */
559  }
560 #endif /* !WINDOWS */
561 
562  for (line_no = 1;; line_no++)
563  {
565  {
566  csql_Database_connected = false;
567  fputs ("!", csql_Output_fp);
568  }
569 
570  read_whole_line = false;
571 
572  memset (line_buf, 0, LINE_BUFFER_SIZE);
573  memset (utf8_line_buf, 0, INTL_UTF8_MAX_CHAR_SIZE * LINE_BUFFER_SIZE);
574 
576  {
577 #if defined(WINDOWS)
578  fputs (csql_Prompt, csql_Output_fp); /* display prompt */
579  line_read = fgets ((char *) line_buf, LINE_BUFFER_SIZE, csql_Input_fp);
580 #else
581  if ((line_read = readline (csql_Prompt)) != NULL)
582  {
583  if (line_read_alloced != NULL)
584  {
585  free (line_read_alloced);
586  line_read_alloced = NULL;
587  }
588 
589  line_read_alloced = line_read;
590 
591  /* readline assure whole line user typed is located in returned buffer (but it doesn't contain '\n' in
592  * it) */
593  read_whole_line = true;
594  }
595 #endif /* WINDOWS */
596  }
597  else
598  {
599  /* If input line exeeds LINE_BUFFER_SIZE, line_buf couldn't contain '\n' character in it. So, read_whole_line
600  * will be remained as false. */
601  line_read = fgets ((char *) line_buf, LINE_BUFFER_SIZE, csql_Input_fp);
602  }
603 
604  fflush (csql_Output_fp);
605 
606  if (line_read == NULL)
607  {
608  if (errno == EINTR && !feof (csql_Input_fp))
609  {
610  fprintf (csql_Output_fp, "\n");
611  continue;
612  }
613 
614  /* Normal end condtion (with -i option) */
615  if (line_read_alloced != NULL)
616  {
617  free (line_read_alloced);
618  line_read_alloced = NULL;
619  }
621  csql_exit_session (0);
622  }
623 
624  line_length = strlen (line_read);
625 
627  {
628  char *utf8_line_read = NULL;
629 
631  {
632  int utf8_line_buf_size = sizeof (utf8_line_buf);
633 
634  utf8_line_read = (char *) utf8_line_buf;
635  if ((*csql_text_console_to_utf8) (line_read, line_length, &utf8_line_read, &utf8_line_buf_size) !=
636  NO_ERROR)
637  {
638  goto error_continue;
639  }
640  if (utf8_line_read != NULL)
641  {
642  line_read = utf8_line_read;
643  line_length = strlen (line_read);
644  }
645  }
646  }
647 
648  /* skip UTF-8 BOM if present */
649  if (is_first_read_line && intl_is_bom_magic (line_read, line_length))
650  {
651  line_read += 3;
652  line_length -= 3;
653  }
654  is_first_read_line = false;
655 
656  for (ptr = line_read + line_length - 1; line_length > 0; ptr--)
657  {
658  if (*ptr == '\n')
659  {
660  read_whole_line = true;
661  }
662 
663  if (*ptr == '\n' || *ptr == '\r')
664  {
665  *ptr = '\0';
666  line_length--;
667  }
668  else
669  {
670  break;
671  }
672  }
673 
674  if (CSQL_SESSION_COMMAND_PREFIX (line_read[0]) && is_in_block == false)
675  {
676  int ret;
677  ret = csql_do_session_cmd (line_read, csql_arg);
678  if (ret == DO_CMD_EXIT)
679  {
680  if (line_read_alloced != NULL)
681  {
682  free (line_read_alloced);
683  line_read_alloced = NULL;
684  }
686  csql_exit_session (0);
687  }
688  else if (ret == DO_CMD_FAILURE)
689  {
690  goto error_continue;
691  }
692 
694  {
695  line_no = 0;
696  }
697  continue;
698  }
699  else
700  {
701  bool csql_execute = false;
702 
703  if (csql_edit_contents_append (line_read, read_whole_line) != CSQL_SUCCESS)
704  {
705  goto error_continue;
706  }
707 
708  if (feof (csql_Input_fp))
709  {
710  /* if eof is reached, execute all */
711  csql_execute = true;
712  is_in_block = false;
713  }
714  else
715  {
716  csql_walk_statement (line_read);
717  /* because we don't want to execute session commands in string block or comment block or identifier block */
718  is_in_block = csql_is_statement_in_block ();
719 
720  if (csql_arg->single_line_execution
721  /* read_whole_line == false means that fgets couldn't read whole line (exceeds buffer size) so we
722  * should concat next line before execute it. */
723  && read_whole_line == true && csql_is_statement_complete ())
724  {
725  /* if eof is not reached, execute it only on single line execution mode with complete statement */
726  csql_execute = true;
727  }
728  }
729 
730  if (csql_execute)
731  {
732  /* single-line-oriented execution */
733  csql_execute_statements (csql_arg, EDITOR_INPUT, NULL, line_no);
736  {
737  line_no = 0;
738  }
739  }
740  }
741 
742  continue;
743 
744  error_continue:
745 
747  {
748  line_no = 0;
749  }
751  }
752 
753 fatal_error:
755  if (histo_is_supported ())
756  {
758  {
760  histo_stop ();
761  }
762  }
763 
764  db_end_session ();
765  db_shutdown ();
766  csql_Database_connected = false;
768  csql_exit (EXIT_FAILURE);
769 }
770 
771 static char *
773 {
774  switch (cmd_no)
775  {
776  case S_CMD_SHELL_CMD:
777  return csql_Shell_cmd;
778  case S_CMD_EDIT_CMD:
779  return csql_Editor_cmd;
780  case S_CMD_PRINT_CMD:
781  return csql_Print_cmd;
782  case S_CMD_PAGER_CMD:
783  return csql_Pager_cmd;
784  default:
785  assert (false);
786  return NULL;
787  }
788 }
789 
790 static int
791 csql_do_session_cmd (char *line_read, CSQL_ARGUMENT * csql_arg)
792 {
793  char *ptr;
794  char *sess_end = NULL; /* end pos of session command */
795  char sess_end_char = '\0'; /* orginal char in end pos of session command */
796  char *sess_cmd; /* session command pointer */
797  char *argument; /* argument str */
798  int cmd_no; /* session command number */
799  char *argument_end = NULL;
800  int argument_len = 0;
801  int error_code;
802 #if !defined(WINDOWS)
803  HIST_ENTRY *hist_entry;
804 #endif /* !WINDOWS */
805 
806  /* get session command and argument */
807  ptr = line_read;
808  if (csql_Is_echo_on)
809  {
810  fprintf (csql_Output_fp, "%s\n", line_read);
811  }
812 
813  /* 'ptr' points to the prefix char. */
814  for (ptr++; *ptr != '\0' && iswspace ((wint_t) (*ptr)); ptr++)
815  {
816  ;
817  }
818  sess_cmd = (char *) ptr;
819  for (; *ptr != '\0' && !iswspace ((wint_t) (*ptr)); ptr++)
820  {
821  ;
822  }
823  if (iswspace ((wint_t) (*ptr)))
824  {
825  sess_end = ptr;
826  sess_end_char = *ptr;
827  *ptr++ = '\0'; /* put null-termination */
828  }
829  else
830  {
831  sess_end_char = '\0';
832  }
833  for (; *ptr != '\0' && iswspace ((wint_t) (*ptr)); ptr++)
834  {
835  ;
836  }
837  argument = (char *) ptr;
838 
839  /* remove the end wide-space of argument */
840  argument_len = strlen (argument);
841  if (argument_len > 0)
842  {
843  argument_end = argument + argument_len - 1;
844  for (; argument_end != argument && iswspace ((wint_t) (*argument_end)); --argument_end)
845  {
846  *argument_end = '\0';
847  }
848  }
849 
850  /* Now, `sess_cmd' points to null-terminated session command name and `argument' points to remaining argument (it may
851  * be '\0' if not given). */
852 
853  if (*sess_cmd == '\0' && csql_arg->single_line_execution == false)
854  {
855  return DO_CMD_SUCCESS;
856  }
857 
858  cmd_no = csql_get_session_cmd_no (sess_cmd);
859  if (cmd_no == -1)
860  {
861  return DO_CMD_FAILURE;
862  }
863 
864  /* restore line_read string */
865  if (sess_end != NULL)
866  {
867  *sess_end = sess_end_char;
868  }
869 
870 #if !defined(WINDOWS)
872  {
873  add_history (line_read);
874  }
875 #endif /* !WINDOWS */
876 
877  er_clear ();
878 
879  switch ((SESSION_CMD) cmd_no)
880  {
881  /* File stuffs */
882 
883  case S_CMD_READ: /* read a file */
884  csql_read_file (argument);
885  break;
886 
887  case S_CMD_WRITE: /* write to a file */
888  case S_CMD_APPEND: /* append to a file */
889  csql_write_file (argument, cmd_no == S_CMD_APPEND);
890  break;
891 
892  case S_CMD_PRINT:
894  break;
895 
896  case S_CMD_SHELL: /* invoke shell */
898  csql_fputs ("\n", csql_Tty_fp);
899  break;
900 
901  case S_CMD_CD:
903  break;
904 
905  case S_CMD_EXIT: /* exit */
906  return DO_CMD_EXIT;
907 
908  /* Edit stuffs */
909 
910  case S_CMD_CLEAR: /* clear editor buffer */
912  break;
913 
914  case S_CMD_EDIT: /* invoke system editor */
916  {
917  return DO_CMD_FAILURE;
918  }
919  break;
920 
921  case S_CMD_LIST: /* display buffer */
922  display_buffer ();
923  break;
924 
925  /* Command stuffs */
926  case S_CMD_RUN:
927  csql_execute_statements (csql_arg, EDITOR_INPUT, NULL, -1);
928  break;
929 
930  case S_CMD_XRUN:
931  csql_execute_statements (csql_arg, EDITOR_INPUT, NULL, -1);
933  break;
934 
935  case S_CMD_COMMIT:
936  if (db_commit_transaction () < 0)
937  {
938  csql_display_csql_err (0, 0);
940  }
941  else
942  {
945  }
946  break;
947 
948  case S_CMD_ROLLBACK:
949  if (db_abort_transaction () < 0)
950  {
951  csql_display_csql_err (0, 0);
953  }
954  else
955  {
958  }
959  break;
960 
961  case S_CMD_AUTOCOMMIT:
962  if (!strcasecmp (argument, "on"))
963  {
964  csql_arg->auto_commit = true;
965  }
966  else if (!strcasecmp (argument, "off"))
967  {
968  csql_arg->auto_commit = false;
969  }
970 
971  fprintf (csql_Output_fp, "AUTOCOMMIT IS %s\n", (csql_is_auto_commit_requested (csql_arg) ? "ON" : "OFF"));
972 
974  break;
975 
976  case S_CMD_CHECKPOINT:
977  if (csql_arg->sysadm && au_is_dba_group_member (Au_user))
978  {
979  error_code = db_checkpoint ();
980  if (error_code != NO_ERROR)
981  {
982  csql_display_csql_err (0, 0);
983  }
984  else
985  {
987  }
988  }
989  else
990  {
991  fprintf (csql_Output_fp, "Checkpointing is only allowed for" " the csql started with --sysadm\n");
992  }
993  break;
994 
995  case S_CMD_KILLTRAN:
996  if (csql_arg->sysadm && au_is_dba_group_member (Au_user))
997  {
998  csql_killtran ((argument[0] == '\0') ? NULL : argument);
999  }
1000  else
1001  {
1002  fprintf (csql_Output_fp, "Killing transaction is only allowed" " for the csql started with --sysadm\n");
1003  }
1004  break;
1005 
1006  case S_CMD_RESTART:
1008  {
1009  csql_Database_connected = false;
1010  db_end_session ();
1011  db_shutdown ();
1012  }
1013  er_init ("./csql.err", ER_NEVER_EXIT);
1014  if (db_restart_ex (UTIL_CSQL_NAME, csql_arg->db_name, csql_arg->user_name, csql_arg->passwd, NULL,
1016  {
1018  csql_display_csql_err (0, 0);
1020  }
1021  else
1022  {
1023  if (csql_arg->sysadm && au_is_dba_group_member (Au_user))
1024  {
1025  au_disable ();
1026  }
1027  csql_Database_connected = true;
1028 
1029  if (csql_arg->trigger_action_flag == false)
1030  {
1031  db_disable_trigger ();
1032  }
1033 
1035  }
1036  break;
1037 
1038  /* Environment stuffs */
1039  case S_CMD_SHELL_CMD:
1040  case S_CMD_EDIT_CMD:
1041  case S_CMD_PRINT_CMD:
1042  case S_CMD_PAGER_CMD:
1043  if (*argument == '\0')
1044  {
1045  fprintf (csql_Output_fp, "\n\t%s\n\n", csql_get_external_command ((SESSION_CMD) cmd_no));
1046  }
1047  else
1048  {
1049  strncpy (csql_get_external_command ((SESSION_CMD) cmd_no), argument, PATH_MAX - 1);
1050  }
1051  break;
1052 
1053  case S_CMD_NOPAGER_CMD:
1054  csql_Pager_cmd[0] = '\0';
1055  break;
1056 
1057  /* Help stuffs */
1058  case S_CMD_HELP:
1059  csql_help_menu ();
1060  break;
1061 
1062  case S_CMD_SCHEMA:
1063  csql_help_schema ((argument[0] == '\0') ? NULL : argument);
1064  if (csql_is_auto_commit_requested (csql_arg))
1065  {
1066  if (db_commit_transaction () < 0)
1067  {
1068  csql_display_csql_err (0, 0);
1070  }
1071  else
1072  {
1074  }
1075  }
1076  break;
1077 
1078  case S_CMD_TRIGGER:
1079  csql_help_trigger ((argument[0] == '\0') ? NULL : argument);
1080  if (csql_is_auto_commit_requested (csql_arg))
1081  {
1082  if (db_commit_transaction () < 0)
1083  {
1084  csql_display_csql_err (0, 0);
1086  }
1087  else
1088  {
1090  }
1091  }
1092  break;
1093 
1094  case S_CMD_INFO:
1095  csql_help_info ((argument[0] == '\0') ? NULL : argument, csql_is_auto_commit_requested (csql_arg));
1096  break;
1097 
1098  case S_CMD_DATABASE:
1100  break;
1101 
1102  case S_CMD_SET_PARAM:
1103  csql_set_sys_param (argument);
1104  break;
1105 
1106  case S_CMD_GET_PARAM:
1107  csql_get_sys_param (argument);
1108  break;
1109 
1110  case S_CMD_PLAN_DUMP:
1111  csql_set_plan_dump ((argument[0] == '\0') ? NULL : argument);
1112  break;
1113 
1114  case S_CMD_ECHO:
1115  if (!strcasecmp (argument, "on"))
1116  {
1117  csql_Is_echo_on = true;
1118  }
1119  else if (!strcasecmp (argument, "off"))
1120  {
1121  csql_Is_echo_on = false;
1122  }
1123  else
1124  {
1125  fprintf (csql_Output_fp, "ECHO IS %s\n", (csql_Is_echo_on ? "ON" : "OFF"));
1126  }
1127  break;
1128 
1129  case S_CMD_DATE:
1130  {
1131  time_t tloc = time (NULL);
1132  struct tm tmloc;
1133  char str[80];
1134  utility_localtime (&tloc, &tmloc);
1135  strftime (str, 80, "%a %B %d %H:%M:%S %Z %Y", &tmloc);
1136  fprintf (csql_Output_fp, "\n\t%s\n", str);
1137  }
1138  break;
1139 
1140  case S_CMD_TIME:
1141  if (!strcasecmp (argument, "on"))
1142  {
1143  csql_Is_time_on = true;
1144  }
1145  else if (!strcasecmp (argument, "off"))
1146  {
1147  csql_Is_time_on = false;
1148  }
1149  else
1150  {
1151  fprintf (csql_Output_fp, "TIME IS %s\n", (csql_Is_time_on ? "ON" : "OFF"));
1152  }
1153  break;
1154 
1155  case S_CMD_LINE_OUTPUT:
1156  if (strcasecmp (argument, "on") == 0)
1157  {
1158  if (csql_arg->column_output)
1159  {
1162  break;
1163  }
1164  csql_arg->line_output = true;
1165  }
1166  else if (strcasecmp (argument, "off") == 0)
1167  {
1168  csql_arg->line_output = false;
1169  }
1170  else
1171  {
1172  fprintf (csql_Output_fp, "LINE_OUTPUT IS %s\n", (csql_arg->line_output ? "ON" : "OFF"));
1173  }
1174  break;
1175 
1176  case S_CMD_COLUMN_WIDTH:
1177  {
1178  char *column_name = NULL;
1179  int width = 0, result;
1180 
1181  if (*argument == '\0')
1182  {
1183  int i;
1184 
1185  for (i = 0; i < csql_column_width_info_list_size; i++)
1186  {
1187  if (csql_column_width_info_list[i].name == NULL)
1188  {
1189  break;
1190  }
1191 
1192  if (csql_column_width_info_list[i].width <= 0)
1193  {
1194  continue;
1195  }
1196 
1197  fprintf (csql_Output_fp, "COLUMN-WIDTH %s : %d\n", csql_column_width_info_list[i].name,
1198  csql_column_width_info_list[i].width);
1199  }
1200  }
1201  else
1202  {
1203  char *val_str = NULL;
1204 
1205  result = get_column_name_argument (&column_name, &val_str, argument);
1206  if (result == CSQL_FAILURE)
1207  {
1208  fprintf (csql_Error_fp, "ERROR: Column name is too long.\n");
1209  break;
1210  }
1211 
1212  if (val_str == NULL)
1213  {
1214  width = csql_get_column_width (column_name);
1215  fprintf (csql_Output_fp, "COLUMN-WIDTH %s : %d\n", column_name, width);
1216  }
1217  else
1218  {
1219  trim (val_str);
1220  result = parse_int (&width, val_str, 10);
1221  if (result != 0 || width < 0)
1222  {
1223  fprintf (csql_Error_fp, "ERROR: Invalid argument(%s).\n", val_str);
1224  break;
1225  }
1226 
1227  if (csql_set_column_width_info (column_name, width) != CSQL_SUCCESS)
1228  {
1229  return DO_CMD_FAILURE;
1230  }
1231  }
1232  }
1233  }
1234  break;
1235 
1236  case S_CMD_STRING_WIDTH:
1237  {
1238  int string_width = 0, result;
1239 
1240  if (*argument != '\0')
1241  {
1242  trim (argument);
1243 
1244  result = parse_int (&string_width, argument, 10);
1245 
1246  if (result != 0 || string_width < 0)
1247  {
1248  fprintf (csql_Error_fp, "ERROR: Invalid string-width(%s).\n", argument);
1249  }
1250 
1251  csql_arg->string_width = string_width;
1252  }
1253  else
1254  {
1255  fprintf (csql_Output_fp, "STRING-WIDTH : %d\n", csql_arg->string_width);
1256  }
1257  }
1258  break;
1259 
1260  case S_CMD_HISTO:
1261  if (histo_is_supported ())
1262  {
1263  if (!strcasecmp (argument, "on"))
1264  {
1265  if (histo_start (false) == NO_ERROR)
1266  {
1268  }
1269  else
1270  {
1271  if (er_errid () == ER_AU_DBA_ONLY)
1272  {
1273  fprintf (csql_Output_fp, "Histogram is allowed only for DBA\n");
1274  }
1275  else
1276  {
1277  fprintf (csql_Output_fp, "Error on .hist command\n");
1278  }
1279  }
1280  }
1281  else if (!strcasecmp (argument, "off"))
1282  {
1283  (void) histo_stop ();
1285  }
1286  else
1287  {
1288  fprintf (csql_Output_fp, ".hist IS %s\n", (csql_Is_histo_on == HISTO_OFF ? "OFF" : "ON"));
1289  }
1290  }
1291  else
1292  {
1293  fprintf (csql_Output_fp,
1294  "Histogram is possible when the csql started with " "`communication_histogram=yes'\n");
1295  }
1296  break;
1297 
1298  case S_CMD_CLR_HISTO:
1299  if (histo_is_supported ())
1300  {
1301  if (csql_Is_histo_on == HISTO_ON)
1302  {
1303  histo_clear ();
1304  }
1305  else
1306  {
1307  fprintf (csql_Output_fp, ".hist IS currently OFF\n");
1308  }
1309  }
1310  else
1311  {
1312  fprintf (csql_Output_fp,
1313  "Histogram on execution statistics " "is only allowed for the csql started "
1314  "with `communication_histogram=yes'\n");
1315  }
1316  break;
1317 
1318  case S_CMD_DUMP_HISTO:
1319  if (histo_is_supported ())
1320  {
1321  if (csql_Is_histo_on == HISTO_ON)
1322  {
1324  {
1325  return DO_CMD_FAILURE;
1326  }
1327  fprintf (csql_Output_fp, "\n");
1328  }
1329  else
1330  {
1331  fprintf (csql_Output_fp, ".hist IS currently OFF\n");
1332  }
1333  }
1334  else
1335  {
1336  fprintf (csql_Output_fp,
1337  "Histogram on execution statistics " "is only allowed for the csql started "
1338  "with `communication_histogram=yes'\n");
1339  }
1340  break;
1341 
1342  case S_CMD_DUMP_CLR_HISTO:
1343  if (histo_is_supported ())
1344  {
1345  if (csql_Is_histo_on == HISTO_ON)
1346  {
1348  {
1349  return DO_CMD_FAILURE;
1350  }
1351  histo_clear ();
1352  fprintf (csql_Output_fp, "\n");
1353  }
1354  else
1355  {
1356  fprintf (csql_Output_fp, ".hist IS currently OFF\n");
1357  }
1358  }
1359  else
1360  {
1361  fprintf (csql_Output_fp,
1362  "Histogram on execution statistics " "is only allowed for the csql started "
1363  "with `communication_histogram=yes'\n");
1364  }
1365  break;
1366 
1367  case S_CMD_HISTORY_READ:
1368 #if !defined(WINDOWS)
1369  if (csql_Is_interactive)
1370  {
1371  if (argument[0] != '\0')
1372  {
1373  int i = atoi (argument);
1374  if (i > 0)
1375  {
1376  HIST_ENTRY *hist;
1377  hist = history_get (history_base + i - 1);
1378  if (hist != NULL)
1379  {
1380  if (csql_edit_contents_append (hist->line, true) != CSQL_SUCCESS)
1381  {
1382  return DO_CMD_FAILURE;
1383  }
1384  }
1385  else
1386  {
1387  fprintf (csql_Error_fp, "ERROR: Invalid history number(%s).\n", argument);
1388  }
1389  }
1390  else
1391  {
1392  fprintf (csql_Error_fp, "ERROR: Invalid history number\n");
1393  }
1394  }
1395  else
1396  {
1397  fprintf (csql_Error_fp, "ERROR: HISTORYRead {history_number}\n");
1398  }
1399  }
1400 #else
1401  if (csql_Is_interactive)
1402  {
1403  fprintf (csql_Error_fp,
1404  "ERROR: Windows do not support HISTORYList" " and HISTORYRead session commands in csql.\n");
1405  }
1406 #endif /* !WINDOWS */
1407  break;
1408 
1409  case S_CMD_HISTORY_LIST:
1410 #if !defined(WINDOWS)
1411  if (csql_Is_interactive)
1412  {
1413  for (int i = 0; i < history_length; i++)
1414  {
1415  hist_entry = history_get (i + 1);
1416  if (hist_entry != NULL && hist_entry->line != NULL)
1417  {
1418  fprintf (csql_Output_fp, "----< %d >----\n", i + 1);
1419  fprintf (csql_Output_fp, "%s\n\n", hist_entry->line);
1420  }
1421  }
1422  }
1423 #else
1424  if (csql_Is_interactive)
1425  {
1426  fprintf (csql_Error_fp,
1427  "ERROR: Windows do not support HISTORYList" " and HISTORYRead session commands in csql.\n");
1428  }
1429 #endif /* !WINDOWS */
1430  break;
1431  case S_CMD_TRACE:
1432  if (csql_arg->sa_mode == false)
1433  {
1434  csql_set_trace ((argument[0] == '\0') ? NULL : argument);
1435  }
1436  else
1437  {
1438  fprintf (csql_Error_fp, "Auto trace isn't allowed in SA mode.\n");
1439  }
1440  break;
1441  }
1442 
1443  return DO_CMD_SUCCESS;
1444 }
1445 
1446 /*
1447  * csql_read_file() - read a file into command editor
1448  * return: none
1449  * file_name(in): input file name
1450  */
1451 static void
1452 csql_read_file (const char *file_name)
1453 {
1454  static char current_file[PATH_MAX] = "";
1455  char *p, *q; /* pointer to string */
1456  FILE *fp = (FILE *) NULL; /* file stream */
1457 
1458  p = csql_get_real_path (file_name); /* get real path name */
1459 
1460  if (p == NULL || p[0] == '\0')
1461  {
1462  /*
1463  * No filename given; use the last one we were given. If we've
1464  * never received one before we have a genuine error.
1465  */
1466  if (current_file[0] != '\0')
1467  {
1468  p = current_file;
1469  }
1470  else
1471  {
1473  goto error;
1474  }
1475  }
1476 
1477  for (q = p; *q != '\0' && !iswspace ((wint_t) (*q)); q++)
1478  ;
1479 
1480  /* trim trailing blanks */
1481  for (; *q != '\0' && iswspace ((wint_t) (*q)); q++)
1482  {
1483  *q = '\0';
1484  }
1485 
1486  if (*q != '\0')
1487  { /* contains more than one file name */
1489  goto error;
1490  }
1491 
1492  fp = fopen (p, "r");
1493  if (fp == NULL)
1494  {
1496  goto error;
1497  }
1498 
1499  /*
1500  * We've successfully read the file, so remember its name for
1501  * subsequent reads.
1502  */
1503  strncpy_bufsize (current_file, p);
1504 
1505  if (csql_edit_read_file (fp) == CSQL_FAILURE)
1506  {
1507  goto error;
1508  }
1509 
1510  fclose (fp);
1511 
1513 
1514  return;
1515 
1516 error:
1517  if (fp != NULL)
1518  {
1519  fclose (fp);
1520  }
1522 }
1523 
1524 /*
1525  * csql_write_file() - write (or append) the current content of editor into
1526  * user specified file
1527  * return: none
1528  * file_name(in): output file name
1529  * append_flag(in): true if append
1530  */
1531 static void
1532 csql_write_file (const char *file_name, int append_flag)
1533 {
1534  static char current_file[PATH_MAX] = "";
1535  /* the name of the last file written */
1536  char *p, *q; /* pointer to string */
1537  FILE *fp = (FILE *) NULL; /* file stream */
1538 
1539  p = csql_get_real_path (file_name); /* get real path name */
1540 
1541  if (p == NULL || p[0] == '\0')
1542  {
1543  /*
1544  * No filename given; use the last one we were given. If we've
1545  * never received one before we have a genuine error.
1546  */
1547  if (current_file[0] != '\0')
1548  p = current_file;
1549  else
1550  {
1552  goto error;
1553  }
1554  }
1555 
1556  for (q = p; *q != '\0' && !iswspace ((wint_t) (*q)); q++)
1557  ;
1558 
1559  /* trim trailing blanks */
1560  for (; *q != '\0' && iswspace ((wint_t) (*q)); q++)
1561  {
1562  *q = '\0';
1563  }
1564 
1565  if (*q != '\0')
1566  { /* contains more than one file name */
1568  goto error;
1569  }
1570 
1571  fp = fopen (p, (append_flag) ? "a" : "w");
1572  if (fp == NULL)
1573  {
1575  goto error;
1576  }
1577 
1578  /*
1579  * We've successfully opened the file, so remember its name for
1580  * subsequent writes.
1581  */
1582  strncpy_bufsize (current_file, p);
1583 
1584  if (csql_edit_write_file (fp) == CSQL_FAILURE)
1585  {
1586  goto error;
1587  }
1588 
1589  fclose (fp);
1590 
1592 
1593  return;
1594 
1595 error:
1596  if (fp != NULL)
1597  {
1598  fclose (fp);
1599  }
1601 }
1602 
1603 /*
1604  * csql_print_buffer()
1605  * return: none
1606  *
1607  * Note:
1608  * copy command editor buffer into temporary file and
1609  * invoke the user preferred print command to print
1610  */
1611 static void
1613 {
1614  /* create an unique file in tmp folder and open it */
1615  auto[filename, fileptr] = filesys::open_temp_file ("csql_");
1616 
1617  if (!fileptr)
1618  {
1621  return;
1622  }
1623  filesys::auto_delete_file file_del (filename.c_str ()); //deletes file at scope end
1624  filesys::auto_close_file file (fileptr); //closes file at scope end (before the above file deleter); forget about fp from now on
1625 
1626  /* write the content of editor to the temp file */
1627  if (csql_edit_write_file (file.get ()) == CSQL_FAILURE)
1628  {
1630  return;
1631  }
1632  fflush (file.get ());
1633 
1634  /* invoke the print command */
1635  char *cmd = csql_get_tmp_buf (1 + strlen (csql_Print_cmd) + 3 + filename.size ());
1636  if (cmd == NULL)
1637  {
1639  return;
1640  }
1641  /*
1642  * Parenthesize the print command and supply its input through stdin,
1643  * just in case it's a pipe or something odd.
1644  */
1645  sprintf (cmd, "(%s) <%s", csql_Print_cmd, filename.c_str ());
1646  csql_invoke_system (cmd);
1647 
1649 }
1650 
1651 /*
1652  * csql_change_working_directory()
1653  * return: none
1654  * dirname(in)
1655  *
1656  * Note:
1657  * cd to the named directory; if dirname is NULL, cd to
1658  * the home directory.
1659  */
1660 static void
1662 {
1663  const char *msg;
1664  char buf[100 + PATH_MAX];
1665 
1667 
1668  dirname = csql_get_real_path (dirname);
1669 
1670  if (dirname == NULL)
1671  {
1672 #if defined (WINDOWS)
1673  static char home_path[PATH_MAX];
1674 
1675  sprintf (home_path, "%s%s", getenv ("HOMEDRIVE"), getenv ("HOMEPATH"));
1676  dirname = home_path;
1677 #else
1678  dirname = getenv ("HOME");
1679 #endif
1680  }
1681 
1682  if (dirname == NULL || chdir (dirname) == -1)
1683  {
1686  }
1687  else
1688  {
1689  snprintf (buf, sizeof (buf) - 1, "\n%s %s.\n\n", msg, dirname);
1691  }
1692 }
1693 
1694 /*
1695  * display_error()
1696  * return: none
1697  * session(in)
1698  * stmt_start_line_no(in)
1699  */
1700 static void
1701 display_error (DB_SESSION * session, int stmt_start_line_no)
1702 {
1704  {
1705  csql_display_session_err (session, stmt_start_line_no);
1707  }
1708  else
1709  {
1711 
1712  /* let users read this message before the next overwrites */
1713  sleep (3);
1714  }
1715 }
1716 
1717 /*
1718  * csql_execute_statements() - execute statements
1719  * return: >0 if some statement failed, zero otherwise
1720  * csql_arg(in)
1721  * type(in)
1722  * stream(in)
1723  *
1724  * Note:
1725  * If `type' is STRING_INPUT, it regards `stream' points to command string.
1726  * If `type' is FILE_INPUT, it regards `stream' points FILE stream of input
1727  * If `type' is EDITOR_INPUT, it attempts to get input string from command
1728  * buffer.
1729  */
1730 static int
1731 csql_execute_statements (const CSQL_ARGUMENT * csql_arg, int type, const void *stream, int line_no)
1732 {
1733  char *stmts = NULL; /* statements string */
1734  int num_stmts = 0; /* # of stmts executed */
1735  int stmt_start_line_no = 0; /* starting line no of each stmt */
1736  DB_SESSION *session = NULL; /* query compilation session id */
1737  DB_QUERY_TYPE *attr_spec = NULL; /* result attribute spec. */
1738  int total; /* number of statements to execute */
1739  bool do_abort_transaction = false; /* flag for transaction abort */
1740  PT_NODE *statement;
1741  char sql_text[DDL_LOG_BUFFER_SIZE] = { 0 };
1742 
1743  csql_Num_failures = 0;
1744  er_clear ();
1745  db_set_interrupt (0);
1746 
1747  if (type == FILE_INPUT)
1748  { /* FILE * input */
1749  if (!(session = db_open_file ((FILE *) stream)))
1750  {
1752  goto error;
1753  }
1756  }
1757  else if (type == STRING_INPUT)
1758  { /* string pointer input */
1759  session = db_open_buffer ((const char *) stream);
1760  if (!session)
1761  {
1763  goto error;
1764  }
1765  if (csql_Is_echo_on)
1766  {
1767  fprintf (csql_Output_fp, "%s\n", (char *) stream);
1768  }
1770  }
1771  else
1772  { /* command buffer input */
1773  stmts = csql_edit_contents_get ();
1774  session = db_open_buffer (stmts);
1775  if (!session)
1776  {
1778  goto error;
1779  }
1780  if (csql_Is_echo_on)
1781  {
1782  fprintf (csql_Output_fp, "%s\n", stmts);
1783  }
1785  }
1786 
1787  /*
1788  * Make sure that there weren't any syntax errors; if there were, the
1789  * entire concept of "compile next statement" doesn't make sense, and
1790  * you run the risk of getting stuck in an infinite loop in the
1791  * following section (especially if the '-e' switch is on).
1792  */
1793  if (db_get_errors (session) || er_errid () != NO_ERROR)
1794  {
1796 #if !defined(WINDOWS)
1797  if ((stmts != NULL) && (csql_Is_interactive))
1798  {
1799  add_history (stmts);
1800  }
1801 #endif /* !WINDOWS */
1802  goto error;
1803  }
1804  else
1805  {
1806  total = db_statement_count (session);
1807 #if !defined(WINDOWS)
1808  if ((total >= 1) && (stmts != NULL) && (csql_Is_interactive))
1809  {
1810  add_history (stmts);
1811  }
1812 #endif /* !WINDOWS */
1813 
1814  /* It is assumed we must always enter the for loop below */
1815  total = MAX (total, 1);
1816  }
1817 
1820 
1821  /* execute the statements one-by-one */
1822  for (num_stmts = 0; num_stmts < total; num_stmts++)
1823  {
1824  TSC_TICKS start_tick, end_tick;
1825  TSCTIMEVAL elapsed_time;
1826 
1827  int stmt_id;
1828  CUBRID_STMT_TYPE stmt_type; /* statement type */
1829  DB_QUERY_RESULT *result = NULL; /* result pointer */
1830  int db_error;
1831  char stmt_msg[LINE_BUFFER_SIZE];
1832 
1833  /* Start the execution of stms */
1834  stmt_msg[0] = '\0';
1835 
1836  if (csql_Is_time_on)
1837  {
1838  tsc_getticks (&start_tick);
1839  }
1841 
1842  stmt_id = db_compile_statement (session);
1843 
1844  if (session->statements)
1845  {
1846  statement = session->statements[num_stmts];
1847  if (statement)
1848  {
1849  logddl_set_stmt_type (statement->node_type);
1850  logddl_set_file_line (statement->line_number);
1851 
1852  if (statement->sql_user_text && strlen (statement->sql_user_text) >= statement->sql_user_text_len)
1853  {
1854  logddl_set_sql_text (statement->sql_user_text, statement->sql_user_text_len);
1855  }
1856  }
1857  }
1858 
1859  if (stmt_id < 0)
1860  {
1861  /*
1862  * Transaction should be aborted if an error occurs during
1863  * compilation on auto commit mode.
1864  */
1865  if (csql_is_auto_commit_requested (csql_arg))
1866  {
1867  do_abort_transaction = true;
1868  }
1869 
1871  if (statement)
1872  {
1873  logddl_set_file_line (statement->line_number);
1874  }
1875 
1876  /* compilation error */
1878  /* Do not continue if there are no statments in the buffer */
1879  if (csql_arg->continue_on_error && (db_error_code () != ER_IT_EMPTY_STATEMENT))
1880  {
1881  display_error (session, 0);
1882  /* do_abort_transaction() should be called after display_error() because in some cases it deallocates the
1883  * parser containing the error message */
1884  if (do_abort_transaction)
1885  {
1887  do_abort_transaction = false;
1889  if (logddl_get_jsp_mode ())
1890  {
1892  }
1893  }
1894  csql_Num_failures += 1;
1895  if (logddl_get_jsp_mode () == false)
1896  {
1897  logddl_write_end ();
1898  }
1899  continue;
1900  }
1901  else
1902  {
1903  goto error;
1904  }
1905  }
1906 
1907  if (stmt_id == 0) /* done */
1908  {
1909  break;
1910  }
1911 
1912  if (line_no == -1)
1913  {
1914  stmt_start_line_no = db_get_start_line (session, stmt_id);
1915  }
1916  else
1917  {
1918  stmt_start_line_no = line_no;
1919  }
1920  attr_spec = db_get_query_type_list (session, stmt_id);
1921  stmt_type = (CUBRID_STMT_TYPE) db_get_statement_type (session, stmt_id);
1922  logddl_set_stmt_type (stmt_type);
1923  logddl_set_file_line (stmt_start_line_no);
1924 
1926  {
1928  goto error;
1929  }
1930 
1931  db_error = db_execute_statement (session, stmt_id, &result);
1932  if (db_error < 0)
1933  {
1936  if (csql_is_auto_commit_requested (csql_arg) && stmt_type != CUBRID_STMT_ROLLBACK_WORK)
1937  {
1938  do_abort_transaction = true;
1939  }
1940  if (csql_arg->continue_on_error)
1941  {
1942  display_error (session, stmt_start_line_no);
1943  if (do_abort_transaction)
1944  {
1946  do_abort_transaction = false;
1948  if (logddl_get_jsp_mode ())
1949  {
1951  }
1952  }
1953  csql_Num_failures += 1;
1954 
1955  free_attr_spec (&attr_spec);
1957  if (logddl_get_jsp_mode () == false)
1958  {
1959  logddl_write_end ();
1960  }
1961  continue;
1962  }
1963  goto error;
1964  }
1965 
1966  snprintf (stmt_msg, LINE_BUFFER_SIZE, "Execute OK.");
1967 
1968  csql_Row_count = 0;
1969  switch (stmt_type)
1970  {
1971  case CUBRID_STMT_SELECT:
1972  {
1973  const char *msg_p;
1974 
1975  csql_results (csql_arg, result, attr_spec, stmt_start_line_no, stmt_type);
1976 
1977  csql_Row_count = db_error;
1978 
1980  snprintf (stmt_msg, LINE_BUFFER_SIZE, msg_p, csql_Row_count, "selected");
1981  break;
1982  }
1983 
1984  case CUBRID_STMT_CALL:
1985  case CUBRID_STMT_EVALUATE:
1986  if (result != NULL)
1987  {
1988  csql_results (csql_arg, result, db_get_query_type_ptr (result), stmt_start_line_no, stmt_type);
1989  }
1990  break;
1991 
1996  case CUBRID_STMT_GET_STATS:
1997  if (result != NULL)
1998  {
1999  csql_results (csql_arg, result, db_get_query_type_ptr (result), stmt_start_line_no, stmt_type);
2000  }
2001  break;
2002 
2003  case CUBRID_STMT_UPDATE:
2004  case CUBRID_STMT_DELETE:
2005  case CUBRID_STMT_INSERT:
2006  case CUBRID_STMT_MERGE:
2007  {
2008  const char *msg_p;
2009 
2010  msg_p = ((db_error > 1) ? csql_get_message (CSQL_ROWS) : csql_get_message (CSQL_ROW));
2011  snprintf (stmt_msg, LINE_BUFFER_SIZE, msg_p, db_error, "affected");
2012  break;
2013  }
2014 
2015  case CUBRID_STMT_KILL:
2016  {
2017  const char *msg_p;
2018 
2019  msg_p = ((db_error > 1) ? csql_get_message (CSQL_TRANSACTIONS) : csql_get_message (CSQL_TRANSACTION));
2020  snprintf (stmt_msg, LINE_BUFFER_SIZE, msg_p, db_error, "killed");
2021  break;
2022  }
2023 
2024  default:
2025  break;
2026  }
2027 
2028  free_attr_spec (&attr_spec);
2029 
2030  if (result != NULL)
2031  {
2032  db_query_end (result);
2033  result = NULL;
2034  }
2035  else
2036  {
2037  /*
2038  * Even though there are no results, a query may have been
2039  * run implicitly by the statement. If so, we need to end the
2040  * query on the server.
2041  */
2042  db_free_query (session);
2043  }
2044 
2045  if (csql_Is_time_on)
2046  {
2047  char time[100];
2048 
2049  tsc_getticks (&end_tick);
2050  tsc_elapsed_time_usec (&elapsed_time, end_tick, start_tick);
2051 
2052  sprintf (time, " (%ld.%06ld sec) ", elapsed_time.tv_sec, elapsed_time.tv_usec);
2053  strncat (stmt_msg, time, sizeof (stmt_msg) - strlen (stmt_msg) - 1);
2054  }
2055 
2056  if (csql_is_auto_commit_requested (csql_arg) && stmt_type != CUBRID_STMT_COMMIT_WORK
2057  && stmt_type != CUBRID_STMT_ROLLBACK_WORK)
2058  {
2059  db_error = db_commit_transaction ();
2060  if (db_error < 0)
2061  {
2064  do_abort_transaction = true;
2065 
2066  if (csql_arg->continue_on_error)
2067  {
2068  display_error (session, stmt_start_line_no);
2069  if (do_abort_transaction)
2070  {
2072  do_abort_transaction = false;
2074  if (logddl_get_jsp_mode ())
2075  {
2077  }
2078  }
2079  csql_Num_failures += 1;
2080  if (logddl_get_jsp_mode () == false)
2081  {
2082  logddl_write_end ();
2083  }
2084  continue;
2085  }
2086  goto error;
2087  }
2088  else
2089  {
2090  strncat (stmt_msg, csql_get_message (CSQL_STAT_COMMITTED_TEXT), LINE_BUFFER_SIZE - 1);
2091  }
2092  }
2093 
2094  if (csql_is_auto_commit_requested (csql_arg) == false && (stmt_type == CUBRID_STMT_COMMIT_WORK
2095  || stmt_type == CUBRID_STMT_ROLLBACK_WORK))
2096  {
2097  if (stmt_type == CUBRID_STMT_COMMIT_WORK)
2098  {
2099  (type !=
2101  logddl_write_tran_str ("Commit transaction at line %d", stmt_start_line_no);
2102  }
2103  else if (stmt_type == CUBRID_STMT_ROLLBACK_WORK)
2104  {
2105  (type !=
2107  logddl_write_tran_str ("Rollback transaction at line %d", stmt_start_line_no);
2108  }
2109  }
2110 
2111  if (csql_arg->plain_output == false && csql_arg->query_output == false && csql_arg->loaddb_output == false)
2112  {
2113  fprintf (csql_Output_fp, "%s\n", stmt_msg);
2114  }
2115 
2116  db_drop_statement (session, stmt_id);
2117 
2118  if (type != FILE_INPUT)
2119  {
2120  if (logddl_get_jsp_mode ())
2121  {
2122  if (csql_is_auto_commit_requested (csql_arg))
2123  {
2124  do_abort_transaction ==
2127  }
2128  }
2129  else
2130  {
2131  if (csql_is_auto_commit_requested (csql_arg))
2132  {
2134  }
2135  logddl_write_end ();
2136  }
2137  }
2138  }
2139 
2141  num_stmts - csql_Num_failures);
2143 
2144  if (type == FILE_INPUT)
2145  {
2146  logddl_write_end_for_csql_fileinput ("Total %8d statements executed. %8d statements failed.", total,
2148  }
2149 
2150  db_close_session (session);
2151 
2152  if (csql_Query_trace == true)
2153  {
2154  csql_display_trace ();
2155  }
2156 
2157  if (csql_is_auto_commit_requested (csql_arg))
2158  {
2159  logddl_free (true);
2160  }
2161  return csql_Num_failures;
2162 
2163 error:
2165  display_error (session, stmt_start_line_no);
2167  if (do_abort_transaction)
2168  {
2170  do_abort_transaction = false;
2172  }
2173  else
2174  {
2175  (void) db_reset_latest_query_status ();
2176  }
2177 
2178  /* Finish... */
2180  num_stmts - csql_Num_failures);
2182  if (logddl_get_jsp_mode ())
2183  {
2185  }
2186  else
2187  {
2189  }
2190 
2191  if (session)
2192  {
2193  db_close_session (session);
2194  }
2195 
2196  free_attr_spec (&attr_spec);
2197  if (csql_is_auto_commit_requested (csql_arg))
2198  {
2199  logddl_free (true);
2200  }
2201  return 1;
2202 }
2203 
2204 /*
2205  * free_attr_spec()
2206  * return: none
2207  * attr_spec(in/out)
2208  *
2209  * Note: Free memory alloced for attr_spec and set pointer to NULL
2210  */
2211 static void
2213 {
2214  if (*attr_spec != NULL)
2215  {
2216  db_query_format_free (*attr_spec);
2217  *attr_spec = NULL;
2218  }
2219 }
2220 
2221 /*
2222  * csql_print_database()
2223  */
2224 static void
2226 {
2227  struct sockaddr_in sin;
2228  const char *db_name, *host_name;
2229  char *pstr;
2230  char converted_host_name[CUB_MAXHOSTNAMELEN + 1];
2231  char ha_state[16];
2232  int res;
2233 
2234  db_name = db_get_database_name ();
2235  host_name = db_get_host_connected ();
2236 
2237  if (db_name == NULL || host_name == NULL)
2238  {
2239  fprintf (csql_Error_fp, "\n\tNOT CONNECTED\n\n");
2240  }
2241  else
2242  {
2243  sin.sin_family = AF_INET;
2244  sin.sin_addr.s_addr = inet_addr (host_name);
2245 
2246  res =
2247  getnameinfo ((struct sockaddr *) &sin, sizeof (sin), converted_host_name, sizeof (converted_host_name), NULL, 0,
2248  NI_NAMEREQD);
2249  /*
2250  * if it fails to resolves hostname,
2251  * it will use db_get_host_connected()'s result.
2252  */
2253  if (res != 0)
2254  {
2255  strncpy (converted_host_name, host_name, CUB_MAXHOSTNAMELEN);
2256  converted_host_name[CUB_MAXHOSTNAMELEN] = '\0';
2257  }
2258 
2259  if (strcasecmp (converted_host_name, "localhost") == 0
2260  || strcasecmp (converted_host_name, "localhost.localdomain") == 0)
2261  {
2262  if (GETHOSTNAME (converted_host_name, CUB_MAXHOSTNAMELEN) != 0)
2263  {
2264  strncpy (converted_host_name, host_name, CUB_MAXHOSTNAMELEN);
2265  }
2266  }
2267  converted_host_name[CUB_MAXHOSTNAMELEN] = '\0';
2268 
2269  /*
2270  * if there is hostname or ip address in db_name,
2271  * it will only use db_name except for hostname or ip address.
2272  */
2273  pstr = (char *) strchr (db_name, '@');
2274  if (pstr != NULL)
2275  {
2276  *pstr = '\0';
2277  }
2278 
2279  if (HA_DISABLED ())
2280  {
2281  fprintf (csql_Output_fp, "\n\t%s@%s\n\n", db_name, converted_host_name);
2282  }
2283  else
2284  {
2285  db_get_ha_server_state (ha_state, 16);
2286  fprintf (csql_Output_fp, "\n\t%s@%s [%s]\n\n", db_name, converted_host_name, ha_state);
2287  }
2288 
2289  db_ws_free ((char *) db_name);
2290  }
2291 }
2292 
2293 /*
2294  * csql_set_sys_param()
2295  * return: none
2296  * arg_str(in)
2297  *
2298  * Note: Parse the arg string to find out what system parameter to
2299  * clobber, then clobber it. Originally introduced to allow us
2300  * to fiddle with optimizer parameters.
2301  */
2302 static void
2303 csql_set_sys_param (const char *arg_str)
2304 {
2305  char plantype[128];
2306  char val[128];
2307  char ans[4096];
2308  int level;
2309  int len = sizeof (ans);
2310 
2311  if (arg_str == NULL)
2312  return;
2313 
2314  if (strncmp (arg_str, "cost", 4) == 0 && sscanf (arg_str, "cost %127s %127s", plantype, val) == 2)
2315  {
2316  if (qo_plan_set_cost_fn (plantype, val[0]))
2317  {
2318  snprintf (ans, len - 1, "cost %s: %s", plantype, val);
2319  }
2320  else
2321  {
2322  snprintf (ans, len - 1, "error: unknown cost parameter %s", plantype);
2323  }
2324  }
2325  else if (strncmp (arg_str, "level", 5) == 0 && sscanf (arg_str, "level %d", &level) == 1)
2326  {
2328  snprintf (ans, len - 1, "level %d", level);
2329  }
2330  else
2331  {
2332  strncpy (ans, arg_str, len - 1);
2333  if (db_set_system_parameters (ans) != NO_ERROR)
2334  {
2335  snprintf (ans, len, "error: set %s", arg_str);
2336  }
2337  }
2338 
2339  csql_append_more_line (0, ans);
2340  csql_display_more_lines ("Set Param Input");
2342 }
2343 
2344 /*
2345  * csql_get_sys_param()
2346  * return:
2347  * arg_str(in)
2348  */
2349 static void
2350 csql_get_sys_param (const char *arg_str)
2351 {
2352  char plantype[128];
2353  int cost;
2354  char ans[4096];
2355  int level;
2356  int len = sizeof (ans);
2357 
2358  if (arg_str == NULL)
2359  return;
2360 
2361  if (strncmp (arg_str, "cost", 4) == 0 && sscanf (arg_str, "cost %127s", plantype) == 1)
2362  {
2363  cost = qo_plan_get_cost_fn (plantype);
2364  if (cost == 'u')
2365  {
2366  snprintf (ans, len, "error: unknown cost parameter %s", arg_str);
2367  }
2368  else
2369  {
2370  snprintf (ans, len, "cost %s: %c", arg_str, (char) cost);
2371  }
2372  }
2373  else if (strcmp (arg_str, "level") == 0)
2374  {
2376  snprintf (ans, len, "level %d", level);
2377  }
2378  else
2379  {
2380  strncpy (ans, arg_str, len - 1);
2381  if (db_get_system_parameters (ans, len - 1) != NO_ERROR)
2382  {
2383  snprintf (ans, len - 1, "error: get %s", arg_str);
2384  }
2385  }
2386 
2387  csql_append_more_line (0, ans);
2388  csql_display_more_lines ("Get Param Input");
2390 }
2391 
2392 /*
2393  * csql_set_plan_dump()
2394  * return:
2395  * arg_str(in)
2396  */
2397 static void
2398 csql_set_plan_dump (const char *arg_str)
2399 {
2400  int level;
2401  char line[128];
2402 
2404 
2405  if (arg_str != NULL)
2406  {
2407  if (!strncmp (arg_str, "simple", 6))
2408  {
2409  level &= ~0x200;
2410  level |= 0x100;
2412  }
2413  else if (!strncmp (arg_str, "detail", 6))
2414  {
2415  level &= ~0x100;
2416  level |= 0x200;
2418  }
2419  else if (!strncmp (arg_str, "off", 3))
2420  {
2421  level &= ~(0x100 | 0x200);
2423  }
2424  }
2425 
2426  if (PLAN_DUMP_ENABLED (level))
2427  {
2428  if (SIMPLE_DUMP (level))
2429  {
2430  snprintf (line, 128, "plan simple (opt level %d)", level);
2431  }
2432  if (DETAILED_DUMP (level))
2433  {
2434  snprintf (line, 128, "plan detail (opt level %d)", level);
2435  }
2436  }
2437  else
2438  {
2439  snprintf (line, 128, "plan off (opt level %d)", level);
2440  }
2441 
2442  csql_append_more_line (0, line);
2443  csql_display_more_lines ("Plan Dump");
2445 }
2446 
2447 /*
2448  * signal_intr() - Interrupt handler for csql
2449  * return: none
2450  * sig_no(in)
2451  */
2452 #if defined(WINDOWS)
2453 static BOOL WINAPI
2454 #else /* !WINDOWS */
2455 static void
2456 #endif /* WINDOWS */
2457 signal_intr (int sig_no)
2458 {
2459  if (csql_Is_interactive)
2460  {
2461  db_set_interrupt (1);
2462  }
2463  csql_Is_sigint_caught = true;
2464 
2465 #if defined(WINDOWS)
2466  if (sig_no == CTRL_C_EVENT)
2467  {
2468  return TRUE;
2469  }
2470 
2471  return FALSE;
2472 #endif /* WINDOWS */
2473 }
2474 
2475 /*
2476  * signal_stop()
2477  * return: none
2478  * sig_no(in)
2479  *
2480  * Note: Interrupt handler for ^Z. This is needed since the terminal
2481  * must be changed from raw to cooked. After we return, it must
2482  * be set back.
2483  */
2484 static void
2485 signal_stop (int sig_no)
2486 {
2487  static int cont = 0;
2488 
2489 #if defined(WINDOWS)
2490  /* there is no SIGSTP on NT */
2491  cont = 1;
2492 #else /* !WINDOWS */
2493  if (sig_no == SIGTSTP)
2494  {
2495  cont = 0;
2496  (void) os_set_signal_handler (SIGTSTP, SIG_DFL);
2497 
2498  /* send the signal to ourselves */
2499  os_send_signal (SIGTSTP);
2500 
2501  /* Wait for SIGCONT */
2502  while (cont == 0)
2503  {
2504  pause ();
2505  }
2506  (void) os_set_signal_handler (SIGTSTP, signal_stop);
2507  }
2508  else
2509  {
2510  /* Continue */
2511  cont = 1;
2512  }
2513 #endif /* !WINDOWS */
2514 }
2515 
2516 /*
2517  * csql_exit_session() - handling the default action of the last outstanding
2518  * transaction (i.e., commit or abort)
2519  * return: none
2520  * error(in)
2521  *
2522  * Note: this function never return.
2523  */
2524 static void
2526 {
2527  char line_buf[LINE_BUFFER_SIZE];
2528  bool commit_on_shutdown = false;
2529  bool prm_commit_on_shutdown = prm_get_commit_on_shutdown ();
2530 
2532 
2533  if (!db_commit_is_needed ())
2534  {
2535  /* when select statements exist only in session, marks end of transaction to flush audit records for those
2536  * statements */
2538  }
2539 
2540  if (csql_Is_interactive && !prm_commit_on_shutdown && db_commit_is_needed () && !feof (csql_Input_fp))
2541  {
2542  FILE *tf;
2543 
2544  tf = csql_Error_fp;
2545 
2546  /* interactive, default action is abort but there was update */
2548  fflush (tf);
2549  for (; fgets (line_buf, LINE_BUFFER_SIZE, csql_Input_fp) != NULL;)
2550  {
2551  if (line_buf[0] == 'y' || line_buf[0] == 'Y')
2552  {
2553  commit_on_shutdown = true;
2555  break;
2556  }
2557  if (line_buf[0] == 'n' || line_buf[0] == 'N')
2558  {
2559  commit_on_shutdown = false;
2561  break;
2562  }
2563 
2565  fflush (tf);
2566  }
2567 
2568  if (commit_on_shutdown && db_commit_transaction () < 0)
2569  {
2571  error = 1;
2572  }
2573  }
2574 
2575  if (histo_is_supported ())
2576  {
2577  if (csql_Is_histo_on != HISTO_OFF)
2578  {
2580  histo_stop ();
2581  }
2582  }
2583  db_end_session ();
2584 
2585  if (db_shutdown () < 0)
2586  {
2587  csql_Database_connected = false;
2589  csql_exit (EXIT_FAILURE);
2590  }
2591  else
2592  {
2593  csql_Database_connected = false;
2594  csql_exit (error ? EXIT_FAILURE : EXIT_SUCCESS);
2595  }
2596 }
2597 
2598 /*
2599  * csql_exit_init()
2600  * return: none
2601  *
2602  * Note:
2603  * Initialize various state variables we keep to let us know what
2604  * cleanup operations need to be performed when the csql() function
2605  * exits. This should properly initialize everything that is tested
2606  * by the csql_exit_cleanup function.
2607  */
2608 static void
2610 {
2611  csql_Exit_status = EXIT_SUCCESS;
2612  csql_Database_connected = false;
2613 
2614  csql_Input_fp = stdin;
2615  csql_Output_fp = stdout;
2616  csql_Error_fp = stderr;
2617 }
2618 
2619 /*
2620  * csql_exit_cleanup()
2621  * return: none
2622  *
2623  * Note:
2624  * Called by csql() when the exit longjmp has been taken.
2625  * Examine the various state variables we keep and perform any
2626  * termination cleanup operations that need to be performed.
2627  * For the Windows implementation, it is especially important that the
2628  * csql() function return cleanly.
2629  */
2630 static void
2632 {
2633  FILE *oldout;
2634 
2635  if (csql_Input_fp != NULL && csql_Input_fp != stdin)
2636  {
2637  (void) fclose (csql_Input_fp);
2638  csql_Input_fp = NULL;
2639  }
2640 
2641  oldout = csql_Output_fp;
2642  if (csql_Output_fp != NULL && csql_Output_fp != stdout)
2643  {
2644  (void) fclose (csql_Output_fp);
2645  csql_Output_fp = NULL;
2646  }
2647 
2648  if (csql_Error_fp != NULL && csql_Error_fp != oldout && csql_Error_fp != stdout && csql_Error_fp != stderr)
2649  {
2650  (void) fclose (csql_Error_fp);
2651  csql_Error_fp = NULL;
2652  }
2653 
2655  {
2656  if (histo_is_supported ())
2657  {
2658  if (csql_Is_histo_on != HISTO_OFF)
2659  {
2661  histo_stop ();
2662  }
2663  }
2664 
2665  csql_Database_connected = false;
2666  db_end_session ();
2667  db_shutdown ();
2668  }
2669 
2670  /* Note that this closes a global resource, the "kernel" message catalog. This is ok for the Unix implementation as
2671  * the entire process is about to exit. For the Windows implementation, it happens to be ok since the test driver
2672  * application that calls csql() won't use this catalog. If this ever changes however, we'll probably have to
2673  * maintain some sort of internal reference counter on this catalog so that it won't be freed until all the nested
2674  * users close it. */
2675  lang_final ();
2676 }
2677 
2678 /*
2679  * csql_exit()
2680  * return: none
2681  * exit_status(in)
2682  * Note:
2683  * This should be called rather than exit() any place that the code wants
2684  * to terminate the csql interpreter program. Rather than exit(), it
2685  * will longjmp back to the csql() function which will clean up and
2686  * return the status code to the calling function. Usually the calling
2687  * function is main() but under Windows, the caller may be a more complex
2688  * application.
2689  */
2690 void
2691 csql_exit (int exit_status)
2692 {
2693  csql_Exit_status = exit_status;
2694  longjmp (csql_Exit_env, 1);
2695 }
2696 
2697 /*
2698  * csql() - "main" interface function for the csql interpreter
2699  * return: EXIT_SUCCESS, EXIT_FAILURE
2700  * csql_arg(in)
2701  */
2702 int
2703 csql (const char *argv0, CSQL_ARGUMENT * csql_arg)
2704 {
2705  char *env;
2706  int client_type;
2707  int avail_size;
2708  char *p = NULL;
2709  unsigned char ip_addr[16] = { "0" };
2710 
2711  /* Establish a globaly accessible longjmp environment so we can terminate on severe errors without calling exit(). */
2712  csql_exit_init ();
2713 
2714  if (setjmp (csql_Exit_env))
2715  {
2716  /* perform any dangling cleanup operations */
2717  csql_exit_cleanup ();
2718  logddl_destroy ();
2719  return csql_Exit_status;
2720  }
2721 
2722  /* initialize message catalog for argument parsing and usage() */
2723  if (utility_initialize () != NO_ERROR)
2724  {
2725  csql_exit (EXIT_FAILURE);
2726  }
2727 
2728  /* set up prompt and message fields. */
2729  if (csql_arg->sysadm)
2730  {
2732  }
2733  else
2734  {
2736  }
2737  avail_size = sizeof (csql_Prompt) - strlen (csql_Prompt) - 1;
2738  if (avail_size > 0)
2739  {
2740  strncat (csql_Prompt, " ", avail_size);
2741  }
2743 
2744  /* as we must use db_open_file_name() to open the input file, it is necessary to be opening csql_Input_fp at this
2745  * point */
2746  if (csql_arg->in_file_name != NULL)
2747  {
2748 #if defined(WINDOWS)
2749  csql_Input_fp = fopen (csql_arg->in_file_name, "rb");
2750 #else /* !WINDOWS */
2751  csql_Input_fp = fopen (csql_arg->in_file_name, "r");
2752 #endif /* WINDOWS */
2753  if (csql_Input_fp == NULL)
2754  {
2756  goto error;
2757  }
2758 
2759 #if defined(WINDOWS)
2760  {
2761  char tmpchar; /* open breaks in DLL'S */
2762  /*
2763  * Unless an operation is done on this stream before the DLL
2764  * is entered the file descriptor will be invalid. This is a bug in
2765  * MSVC compiler and/or libc.
2766  */
2767  tmpchar = fgetc (csql_Input_fp);
2768  ungetc (tmpchar, csql_Input_fp);
2769  }
2770 #endif /* WINDOWS */
2771  }
2772 
2773  if ((csql_arg->in_file_name == NULL) && isatty (fileno (stdin)))
2774  {
2775  csql_Is_interactive = true;
2776  }
2777 
2778  /* initialize error log file */
2779  if (er_init ("./csql.err", ER_NEVER_EXIT) != NO_ERROR)
2780  {
2781  printf ("Failed to initialize error manager.\n");
2783  goto error;
2784  }
2786 
2787  /*
2788  * login and restart database
2789  */
2790  if (csql_arg->sysadm)
2791  {
2792  client_type = DB_CLIENT_TYPE_ADMIN_CSQL;
2793 
2794  if (csql_arg->write_on_standby)
2795  {
2796  client_type = DB_CLIENT_TYPE_ADMIN_CSQL_WOS;
2797  }
2798  else if (csql_arg->skip_vacuum)
2799  {
2801  }
2802  }
2803  else if (csql_arg->read_only)
2804  {
2805  client_type = DB_CLIENT_TYPE_READ_ONLY_CSQL;
2806  }
2807  else if (csql_arg->skip_vacuum)
2808  {
2809  client_type = DB_CLIENT_TYPE_SKIP_VACUUM_CSQL;
2810  }
2811  else
2812  {
2813  client_type = DB_CLIENT_TYPE_CSQL;
2814  }
2815 
2816  if (db_restart_ex (argv0, csql_arg->db_name, csql_arg->user_name, csql_arg->passwd, NULL, client_type) != NO_ERROR)
2817  {
2818  if (!csql_Is_interactive || csql_arg->passwd != NULL || db_error_code () != ER_AU_INVALID_PASSWORD)
2819  {
2820  /* not INTERACTIVE mode, or password is given already, or the error code is not password related */
2822  goto error;
2823  }
2824 
2825  /* get password interactively if interactive mode */
2826  p = getpass ((char *) csql_get_message (CSQL_PASSWD_PROMPT_TEXT));
2827  if (p[0] == '\0')
2828  {
2829  csql_arg->passwd = (char *) NULL; /* to fit into db_login protocol */
2830  }
2831  else
2832  {
2833  csql_arg->passwd = strdup (p);
2834  }
2835 
2836  /* try again */
2837  if (db_restart_ex (argv0, csql_arg->db_name, csql_arg->user_name, csql_arg->passwd, NULL, client_type) !=
2838  NO_ERROR)
2839  {
2841  goto error;
2842  }
2843  }
2844 
2845  logddl_init ();
2848  if (csql_arg->db_name != NULL)
2849  {
2850  logddl_set_db_name (csql_arg->db_name);
2851  }
2852  if (csql_arg->user_name != NULL)
2853  {
2854  logddl_set_user_name (csql_arg->user_name);
2855  }
2856  if (get_host_ip (ip_addr) == 0)
2857  {
2858  logddl_set_ip ((char *) ip_addr);
2859  }
2860  logddl_set_pid (getpid ());
2861 
2862  if (csql_arg->trigger_action_flag == false)
2863  {
2864  db_disable_trigger ();
2865  }
2866 
2867  if (csql_arg->sysadm && au_is_dba_group_member (Au_user))
2868  {
2869  au_disable ();
2870  }
2871 
2872  /* allow environmental setting of the "-s" command line flag to enable automated testing */
2874  {
2875  csql_arg->single_line_execution = true;
2876  }
2877 
2878  /* record the connection so we know how to clean up on exit */
2879  csql_Database_connected = true;
2880 
2881 #if defined(CSQL_NO_LOGGING)
2882  if (csql_arg->no_logging && locator_log_force_nologging () != NO_ERROR)
2883  {
2885  goto error;
2886  }
2887 #endif /* CSQL_NO_LOGGING */
2888 
2889  csql_Editor_cmd[PATH_MAX - 1] = '\0';
2890  csql_Shell_cmd[PATH_MAX - 1] = '\0';
2891  csql_Print_cmd[PATH_MAX - 1] = '\0';
2892  csql_Pager_cmd[PATH_MAX - 1] = '\0';
2893 
2894  env = getenv ("EDITOR");
2895  if (env)
2896  {
2897  strncpy (csql_Editor_cmd, env, PATH_MAX - 1);
2898  }
2899 
2900  env = getenv ("SHELL");
2901  if (env)
2902  {
2903  strncpy (csql_Shell_cmd, env, PATH_MAX - 1);
2904  }
2905 
2906  if (csql_arg->nopager)
2907  {
2908  csql_Pager_cmd[0] = '\0';
2909  }
2910 
2912 
2913  if (csql_Is_interactive)
2914  {
2915  /* handling Ctrl-C */
2916 #if defined(WINDOWS)
2917  SetConsoleCtrlHandler ((PHANDLER_ROUTINE) signal_intr, TRUE);
2918 #else
2919  if (os_set_signal_handler (SIGINT, signal_intr) == SIG_ERR)
2920  {
2922  goto error;
2923  }
2924 #endif
2925 
2926 #if !defined(WINDOWS)
2927  if (os_set_signal_handler (SIGQUIT, signal_intr) == SIG_ERR)
2928  {
2930  goto error;
2931  }
2932 #endif /* !WINDOWS */
2933  }
2934 
2936 
2937  start_csql (csql_arg);
2938 
2939  csql_exit (EXIT_SUCCESS); /* not reachable code, actually */
2940 
2941 error:
2944  csql_exit (EXIT_FAILURE);
2945  return EXIT_FAILURE; /* won't get here really */
2946 }
2947 
2948 /*
2949  * csql_get_message() - get a string of the csql-utility from the catalog
2950  * return: message string
2951  * message_index(in): an index of the message string
2952  */
2953 const char *
2954 csql_get_message (int message_index)
2955 {
2956  return (msgcat_message (MSGCAT_CATALOG_CSQL, MSGCAT_CSQL_SET_CSQL, message_index));
2957 }
2958 
2959 /*
2960  * csql_set_column_width_info() - insert column_name and column_width
2961  * in csql_column_width_info_list
2962  * return: int
2963  * column_name(in): column_name
2964  * column_width(in): column_width
2965  */
2966 int
2967 csql_set_column_width_info (const char *column_name, int column_width)
2968 {
2969  CSQL_COLUMN_WIDTH_INFO *temp_list;
2970  char *temp_name;
2971  int i, index;
2972 
2973  if (column_name == NULL || column_width < 0)
2974  {
2976 
2977  return CSQL_FAILURE;
2978  }
2979 
2980  if (csql_column_width_info_list == NULL)
2981  {
2983  {
2984  return CSQL_FAILURE;
2985  }
2986  }
2987 
2989  {
2990  temp_list =
2991  (CSQL_COLUMN_WIDTH_INFO *) realloc (csql_column_width_info_list,
2993  if (temp_list == NULL)
2994  {
2996 
2997  return CSQL_FAILURE;
2998  }
2999 
3001  csql_column_width_info_list = temp_list;
3003  {
3004  csql_column_width_info_list[i].name = NULL;
3005  csql_column_width_info_list[i].width = 0;
3006  }
3007  }
3008 
3009  index = NOT_FOUND;
3010  for (i = 0; i < csql_column_width_info_list_index; i++)
3011  {
3012  if (strcasecmp (column_name, csql_column_width_info_list[i].name) == 0)
3013  {
3014  index = i;
3015  break;
3016  }
3017  }
3018 
3019  if (index == NOT_FOUND)
3020  {
3022  csql_column_width_info_list_index++;
3023  }
3024 
3025  if (csql_column_width_info_list[index].name == NULL)
3026  {
3027  temp_name = strdup (column_name);
3028  if (temp_name == NULL)
3029  {
3031 
3032  return CSQL_FAILURE;
3033  }
3034 
3035  csql_column_width_info_list[index].name = temp_name;
3036  csql_column_width_info_list[index].width = column_width;
3037  }
3038  else
3039  {
3040  csql_column_width_info_list[index].width = column_width;
3041  }
3042 
3043  return CSQL_SUCCESS;
3044 }
3045 
3046 /*
3047  * csql_get_column_width() - get column_width related column_name
3048  * return: column_width
3049  * column_name(in): column_name
3050  */
3051 int
3052 csql_get_column_width (const char *column_name)
3053 {
3054  char name_without_space[1024];
3055  char *result;
3056  int i;
3057 
3058  if (column_name == NULL)
3059  {
3060  return 0;
3061  }
3062 
3063  if (csql_column_width_info_list == NULL)
3064  {
3065  return 0;
3066  }
3067 
3068  strncpy (name_without_space, column_name, sizeof (name_without_space) - 1);
3069  name_without_space[sizeof (name_without_space) - 1] = '\0';
3070  result = trim (name_without_space);
3071  if (result == NULL)
3072  {
3073  return 0;
3074  }
3075 
3076  for (i = 0; i < csql_column_width_info_list_index; i++)
3077  {
3078  if (strcasecmp (result, csql_column_width_info_list[i].name) == 0)
3079  {
3080  return csql_column_width_info_list[i].width;
3081  }
3082  }
3083 
3084  return 0;
3085 }
3086 
3087 /*
3088  * get_column_name_argument() - get column_name and value pointer from argument
3089  * return: int
3090  * column_name(out): column name
3091  * val_str(out): value string in argument
3092  * argument(in): argument
3093  */
3094 static int
3095 get_column_name_argument (char **column_name, char **val_str, char *argument)
3096 {
3097  char *p;
3098 
3099  assert (column_name != NULL && val_str != NULL && argument != NULL);
3100 
3101  *column_name = NULL;
3102  *val_str = NULL;
3103 
3104  /* argument : "column_name=value" */
3105  *column_name = argument;
3106 
3107  p = strrchr (*column_name, '=');
3108  if (p != NULL)
3109  {
3110  *p = '\0';
3111  *val_str = (p + 1);
3112  }
3113 
3114  trim (*column_name);
3115 
3116  /* max column_name size is 254 */
3117  if (strlen (*column_name) > 254)
3118  {
3119  return CSQL_FAILURE;
3120  }
3121 
3122  return CSQL_SUCCESS;
3123 }
3124 
3125 /*
3126  * csql_set_trace() - set auto trace on or off
3127  * return:
3128  * arg_str(in):
3129  */
3130 static void
3131 csql_set_trace (const char *arg_str)
3132 {
3133  char line[128];
3134  char format[128], *p;
3135 
3136  if (arg_str != NULL)
3137  {
3138  if (strncmp (arg_str, "on", 2) == 0)
3139  {
3141  csql_Query_trace = true;
3142 
3143  if (sscanf (arg_str, "on %127s", format) == 1)
3144  {
3145  p = trim (format);
3146 
3147  if (strncmp (p, "text", 4) == 0)
3148  {
3150  }
3151  else if (strncmp (p, "json", 4) == 0)
3152  {
3154  }
3155  }
3156  }
3157  else if (!strncmp (arg_str, "off", 3))
3158  {
3160  csql_Query_trace = false;
3161  }
3162  }
3163 
3164  if (prm_get_bool_value (PRM_ID_QUERY_TRACE) == true)
3165  {
3167  {
3168  snprintf (line, 128, "trace on json");
3169  }
3170  else
3171  {
3172  snprintf (line, 128, "trace on text");
3173  }
3174  }
3175  else
3176  {
3177  snprintf (line, 128, "trace off");
3178  }
3179 
3180  csql_append_more_line (0, line);
3181  csql_display_more_lines ("Query Trace");
3183 }
3184 
3185 /*
3186  * csql_display_trace() -
3187  * return:
3188  */
3189 static void
3191 {
3192  const char *stmts = NULL;
3193  DB_SESSION *session = NULL;
3194  int stmt_id, dummy, db_error;
3195  DB_QUERY_RESULT *result = NULL;
3196  DB_VALUE trace;
3197  FILE *pf;
3198  int save_row_count;
3199 
3200  er_clear ();
3201  db_set_interrupt (0);
3202  db_make_null (&trace);
3203  save_row_count = db_get_row_count_cache ();
3204 
3205  stmts = "SHOW TRACE";
3206 
3207  session = db_open_buffer (stmts);
3208  if (session == NULL)
3209  {
3210  return;
3211  }
3212 
3213  stmt_id = db_compile_statement (session);
3214 
3215  if (stmt_id < 0)
3216  {
3217  goto end;
3218  }
3219 
3220  db_error = db_execute_statement (session, stmt_id, &result);
3221 
3222  if (db_error < 0)
3223  {
3224  goto end;
3225  }
3226 
3227  (void) db_query_set_copy_tplvalue (result, 0 /* peek */ );
3228 
3229  if (db_query_first_tuple (result) < 0)
3230  {
3231  goto end;
3232  }
3233 
3234  if (db_query_get_tuple_value (result, 0, &trace) < 0)
3235  {
3236  goto end;
3237  }
3238 
3239  if (DB_VALUE_TYPE (&trace) == DB_TYPE_STRING)
3240  {
3242  fprintf (pf, "\n=== Auto Trace ===\n");
3243  fprintf (pf, "%s\n", db_get_char (&trace, &dummy));
3245  }
3246 
3247 end:
3248 
3249  if (result != NULL)
3250  {
3251  db_query_end (result);
3252  }
3253 
3254  if (session != NULL)
3255  {
3256  db_close_session (session);
3257  }
3258 
3259  db_update_row_count_cache (save_row_count);
3260 
3261  return;
3262 }
3263 
3264 static bool
3266 {
3267  assert (csql_arg != NULL);
3269 }
3270 
3271 static int
3272 get_host_ip (unsigned char *ip_addr)
3273 {
3274  char hostname[CUB_MAXHOSTNAMELEN];
3275  struct hostent *hp;
3276  char *ip;
3277 
3278  if (gethostname (hostname, sizeof (hostname)) < 0)
3279  {
3280  return -1;
3281  }
3282  if ((hp = gethostbyname (hostname)) == NULL)
3283  {
3284  return -1;
3285  }
3286 
3287  ip = inet_ntoa (*(struct in_addr *) *hp->h_addr_list);
3288  memcpy (ip_addr, ip, strlen (ip));
3289 
3290  return 0;
3291 }
static bool csql_Is_echo_on
Definition: csql.c:176
static void csql_pipe_handler(int sig_no)
Definition: csql.c:390
void csql_edit_contents_finalize(void)
const char * csql_get_message(int message_index)
Definition: csql.c:2954
static int csql_column_width_info_list_size
Definition: csql.c:185
void logddl_set_msg(const char *fmt,...)
Definition: ddl_log.c:392
bool auto_commit
Definition: csql.h:268
void db_set_interrupt(int set)
Definition: db_admin.c:1445
#define LOGDDL_MSG_AUTO_ROLLBACK
Definition: ddl_log.h:33
char * trim(char *str)
Definition: porting.c:2260
#define NOT_FOUND
Definition: csql.c:102
void csql_invoke_system(const char *command)
Definition: csql_support.c:226
#define NO_ERROR
Definition: error_code.h:46
FILE * csql_Error_fp
Definition: csql.c:158
bool line_output
Definition: csql.h:266
#define TRUE
Definition: broker_admin.c:49
char * dirname(const char *path)
Definition: porting.c:1066
int string_width
Definition: csql.h:277
char * sql_user_text
Definition: parse_tree.h:3444
void csql_help_trigger(const char *class_name)
Definition: csql_session.c:461
void qo_get_optimization_param(void *, QO_PARAM,...)
Definition: query_graph.c:269
void logddl_write_end_for_csql_fileinput(const char *fmt,...)
Definition: ddl_log.c:917
bool csql_is_statement_in_block(void)
void csql_display_session_err(DB_SESSION *session, int line_no)
Definition: csql_support.c:512
void logddl_set_db_name(const char *db_name)
Definition: ddl_log.c:205
#define MSGCAT_CATALOG_CSQL
void csql_help_schema(const char *class_name)
Definition: csql_session.c:221
static bool csql_Query_trace
Definition: csql.c:188
void histo_print(FILE *stream)
#define DETAILED_DUMP(level)
Definition: optimizer.h:86
int db_Connect_status
Definition: db_macro.c:88
void csql_walk_statement(const char *str)
Definition: csql_support.c:967
int parse_int(int *ret_p, const char *str_p, int base)
Definition: porting.c:2290
void qo_set_optimization_param(void *, QO_PARAM,...)
Definition: query_graph.c:316
void csql_fputs_console_conv(const char *str, FILE *fp)
Definition: csql_support.c:357
int histo_stop(void)
static int get_host_ip(unsigned char *ip_addr)
Definition: csql.c:3272
void histo_clear(void)
int csql_set_column_width_info(const char *column_name, int column_width)
Definition: csql.c:2967
Definition: csql.h:184
int db_set_system_parameters(const char *data)
Definition: db_admin.c:2682
int db_query_end(DB_QUERY_RESULT *result)
Definition: db_query.c:3362
int(* text_to_utf8_func)(const char *, const int, char **, int *)
static void signal_stop(int sig_no)
Definition: csql.c:2485
int db_shutdown(void)
Definition: db_admin.c:964
#define ER_IT_EMPTY_STATEMENT
Definition: error_code.h:502
PT_NODE ** statements
Definition: api_compat.h:38
bool read_only
Definition: csql.h:267
int db_reset_latest_query_status(void)
Definition: db_admin.c:1132
void csql_results(const CSQL_ARGUMENT *csql_arg, DB_QUERY_RESULT *result, DB_QUERY_TYPE *attr_spec, int line_no, CUBRID_STMT_TYPE stmt_type)
Definition: csql_result.c:185
bool au_is_dba_group_member(MOP user)
void csql_display_msg(const char *string)
Definition: csql.c:376
int db_get_start_line(DB_SESSION *session, int stmt)
Definition: db_vdb.c:1444
static jmp_buf csql_Jmp_buf
Definition: csql.c:182
void db_query_format_free(DB_QUERY_TYPE *query_type)
Definition: db_query.c:1723
static void start_csql(CSQL_ARGUMENT *csql_arg)
Definition: csql.c:472
struct timeval TSCTIMEVAL
Definition: tsc_timer.h:40
DB_CONST_C_CHAR db_get_char(const DB_VALUE *value, int *length)
#define LOGDDL_MSG_AUTO_COMMIT
Definition: ddl_log.h:32
void tsc_elapsed_time_usec(TSCTIMEVAL *tv, TSC_TICKS end_tick, TSC_TICKS start_tick)
Definition: tsc_timer.c:101
static void display_error(DB_SESSION *session, int stmt_start_line_no)
Definition: csql.c:1701
#define LOGDDL_TRAN_TYPE_COMMIT
Definition: ddl_log.h:35
int au_disable(void)
int er_errid(void)
const char * qo_plan_set_cost_fn(const char *, int)
void os_send_signal(const int sig_no)
Definition: porting.c:1378
int csql_edit_contents_append(const char *str, bool flag_append_new_line)
Definition: csql_support.c:938
void prm_set_integer_value(PARAM_ID prm_id, int value)
void db_ws_free(void *ptr)
Definition: quick_fit.c:194
void logddl_set_logging_enabled(bool enable)
Definition: ddl_log.c:995
void logddl_set_sql_text(char *sql_text, int len)
Definition: ddl_log.c:268
bool db_disable_trigger(void)
Definition: db_admin.c:570
#define SIMPLE_DUMP(level)
Definition: optimizer.h:85
int er_init(const char *msglog_filename, int exit_ask)
void er_set_print_property(int print_console)
void csql_help_info(const char *command, int aucommit_flag)
Definition: csql_session.c:647
void logddl_write_end()
Definition: ddl_log.c:668
static void free_csql_column_width_info_list()
Definition: csql.c:312
char * db_get_host_connected(void)
Definition: db_admin.c:2806
const char * db_name
Definition: csql.h:256
void csql_fputs(const char *str, FILE *fp)
Definition: csql_support.c:322
static int csql_do_session_cmd(char *line_read, CSQL_ARGUMENT *csql_arg)
Definition: csql.c:791
int db_get_system_parameters(char *data, int len)
Definition: db_admin.c:2770
int csql_append_more_line(int indent, const char *line)
Definition: csql_support.c:550
bool trigger_action_flag
Definition: csql.h:273
#define SCRATCH_TEXT_LEN
Definition: csql.h:152
int csql_get_session_cmd_no(const char *input)
Definition: csql_session.c:141
int(* csql_text_console_to_utf8)(const char *, const int, char **, int *)
Definition: csql.c:115
static jmp_buf csql_Exit_env
Definition: csql.c:168
#define DB_CONNECTION_STATUS_CONNECTED
Definition: db.h:47
INTL_CODESET lang_charset(void)
static void csql_set_plan_dump(const char *arg_str)
Definition: csql.c:2398
#define UTIL_CSQL_NAME
Definition: utility.h:834
char * csql_edit_contents_get(void)
Definition: csql_support.c:896
int db_restart_ex(const char *program, const char *db_name, const char *db_user, const char *db_password, const char *preferred_hosts, int client_type)
Definition: db_admin.c:934
std::unique_ptr< FILE, file_closer > auto_close_file
Definition: filesys.hpp:43
static int get_column_name_argument(char **column_name, char **val_str, char *argument)
Definition: csql.c:3095
void logddl_set_csql_input_type(T_CSQL_INPUT_TYPE input_type)
Definition: ddl_log.c:317
#define assert(x)
void er_final(ER_FINAL_CODE do_global_final)
void csql_check_server_down(void)
Definition: csql_support.c:753
static void csql_set_trace(const char *arg_str)
Definition: csql.c:3131
static void csql_get_sys_param(const char *arg_str)
Definition: csql.c:2350
static bool csql_is_auto_commit_requested(const CSQL_ARGUMENT *csql_arg)
Definition: csql.c:3265
int prm_get_integer_value(PARAM_ID prm_id)
bool plain_output
Definition: csql.h:274
char * db_get_database_name(void)
Definition: db_admin.c:432
int db_end_session(void)
Definition: db_admin.c:1029
void csql_help_menu(void)
Definition: csql_session.c:197
char * csql_get_real_path(const char *pathname)
Definition: csql_support.c:160
const char * passwd
Definition: csql.h:258
int db_query_first_tuple(DB_QUERY_RESULT *result)
Definition: db_query.c:2309
int db_error_code(void)
Definition: db_admin.c:2143
Definition: csql.h:91
bool write_on_standby
Definition: csql.h:272
static FILE * csql_Tty_fp
Definition: csql.c:141
static int csql_execute_statements(const CSQL_ARGUMENT *csql_arg, int type, const void *stream, int line_no)
Definition: csql.c:1731
SESSION_CMD
Definition: csql.h:176
void csql_killtran(const char *argument)
Definition: csql_session.c:755
int db_get_ha_server_state(char *buffer, int maxlen)
Definition: db_admin.c:2824
int utility_localtime(const time_t *ts, struct tm *result)
Definition: util_common.c:390
PT_NODE_TYPE node_type
Definition: parse_tree.h:3439
const char * command
Definition: csql.h:261
void db_drop_statement(DB_SESSION *session, int stmt)
Definition: db_vdb.c:3196
bool sa_mode
Definition: csql.h:262
void logddl_set_load_filename(const char *load_filename)
Definition: ddl_log.c:326
void logddl_destroy()
Definition: ddl_log.c:185
#define CSQL_SESSION_COMMAND_PREFIX(C)
Definition: csql.c:97
const char * out_file_name
Definition: csql.h:260
static void csql_exit_cleanup(void)
Definition: csql.c:2631
bool intl_is_bom_magic(const char *buf, const int size)
int db_abort_transaction(void)
Definition: db_admin.c:1114
void lang_final(void)
void db_update_row_count_cache(const int row_count)
Definition: db_admin.c:2924
const char * name
Definition: cubrid_getopt.h:56
void csql_display_csql_err(int line_no, int col_no)
Definition: csql_support.c:490
int db_execute_statement(DB_SESSION *session, int stmt_ndx, DB_QUERY_RESULT **result)
Definition: db_vdb.c:2978
static bool csql_Is_sigint_caught
Definition: csql.c:175
int utility_initialize()
Definition: util_common.c:69
#define NULL
Definition: freelistheap.h:34
#define strncpy_bufsize(buf, str)
Definition: porting.h:340
void lang_init_console_txt_conv(void)
#define DDL_LOG_BUFFER_SIZE
Definition: ddl_log.h:38
void tsc_getticks(TSC_TICKS *tck)
Definition: tsc_timer.c:81
bool prm_get_commit_on_shutdown(void)
DB_SESSION * db_open_buffer(const char *buffer)
Definition: db_vdb.c:232
static void csql_display_trace(void)
Definition: csql.c:3190
int db_compile_statement(DB_SESSION *session)
Definition: db_vdb.c:766
bool query_output
Definition: csql.h:278
void db_close_session(DB_SESSION *session)
Definition: db_vdb.c:3319
void db_free_query(DB_SESSION *session)
Definition: db_vdb.c:3683
bool loaddb_output
Definition: csql.h:281
#define MSGCAT_CSQL_SET_CSQL
Definition: csql.h:49
static char csql_Name[100]
Definition: csql.c:151
bool continue_on_error
Definition: csql.h:270
bool single_line_execution
Definition: csql.h:264
char csql_Scratch_text[SCRATCH_TEXT_LEN]
Definition: csql.c:146
int csql_Line_lwm
Definition: csql.c:121
int csql_Num_failures
Definition: csql.c:118
int csql(const char *argv0, CSQL_ARGUMENT *csql_arg)
Definition: csql.c:2703
char * db_name
FILE * csql_popen(const char *cmd, FILE *fd)
Definition: csql_support.c:396
static CSQL_COLUMN_WIDTH_INFO * csql_column_width_info_list
Definition: csql.c:184
void csql_pclose(FILE *pf, FILE *fd)
Definition: csql_support.c:444
#define LINE_BUFFER_SIZE
Definition: csql.c:100
void csql_free_more_lines(void)
Definition: csql_support.c:714
void csql_edit_contents_clear(void)
bool histo_is_supported(void)
void csql_display_more_lines(const char *title)
Definition: csql_support.c:675
bool csql_is_statement_complete(void)
int csql_edit_write_file(FILE *fp)
int jsp_send_destroy_request_all()
Definition: jsp_cl.c:1963
static void(* csql_pipe_save)(int sig)
Definition: csql_result.c:710
MOP Au_user
Definition: authenticate.c:343
#define INTL_UTF8_MAX_CHAR_SIZE
static char csql_Prompt[100]
Definition: csql.c:150
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
static void free_attr_spec(DB_QUERY_TYPE **attr_spec)
Definition: csql.c:2212
char csql_Print_cmd[PATH_MAX]
Definition: csql.c:124
static bool csql_Is_time_on
Definition: csql.c:180
#define ER_AU_INVALID_PASSWORD
Definition: error_code.h:235
void logddl_init()
Definition: ddl_log.c:119
int histo_start(bool for_all_trans)
static void csql_read_file(const char *file_name)
Definition: csql.c:1452
char csql_Pager_cmd[PATH_MAX]
Definition: csql.c:125
std::pair< std::string, FILE * > open_temp_file(const char *prefix, const char *mode="w", int flags=0)
#define ER_AU_DBA_ONLY
Definition: error_code.h:204
static void signal_intr(int sig_no)
Definition: csql.c:2457
static char * csql_get_external_command(SESSION_CMD cmd_no)
Definition: csql.c:772
std::unique_ptr< const char, file_deleter > auto_delete_file
Definition: filesys.hpp:58
void logddl_set_pid(const int pid)
Definition: ddl_log.c:241
int(* csql_text_utf8_to_console)(const char *, const int, char **, int *)
Definition: csql.c:113
int csql_get_column_width(const char *column_name)
Definition: csql.c:3052
int db_get_client_type(void)
Definition: db_admin.c:489
CUBRID_STMT_TYPE
Definition: cas_dbms_util.h:40
#define free_and_init(ptr)
Definition: memory_alloc.h:147
bool sysadm
Definition: csql.h:271
#define strlen(s1)
Definition: intl_support.c:43
static void csql_exit_session(int error)
Definition: csql.c:2525
static int csql_column_width_info_list_index
Definition: csql.c:186
static void csql_exit_init(void)
Definition: csql.c:2609
static bool csql_Database_connected
Definition: csql.c:172
void logddl_set_app_name(T_APP_NAME app_name)
Definition: ddl_log.c:196
void csql_exit(int exit_status)
Definition: csql.c:2691
int db_get_row_count_cache(void)
Definition: db_admin.c:2914
void logddl_set_commit_mode(bool mode)
Definition: ddl_log.c:422
bool prm_get_bool_value(PARAM_ID prm_id)
#define FALSE
Definition: broker_admin.c:50
void er_clear(void)
DB_QUERY_TYPE * db_get_query_type_list(DB_SESSION *session, int stmt_ndx)
Definition: db_vdb.c:1341
int db_query_set_copy_tplvalue(DB_QUERY_RESULT *result, int copy)
Definition: db_query.c:3386
int qo_plan_get_cost_fn(const char *)
KEYWORD_RECORD * pt_get_keyword_rec(int *rec_count)
Definition: keyword.c:757
static void csql_print_buffer(void)
Definition: csql.c:1612
static bool csql_Is_interactive
Definition: csql.c:174
static void csql_print_database(void)
Definition: csql.c:2225
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
void nonscr_display_error(char *buffer, int buf_length)
Definition: csql_support.c:830
int i
Definition: dynamic_load.c:954
FILE * csql_Output_fp
Definition: csql.c:157
int db_make_null(DB_VALUE *value)
char * msgcat_message(int cat_id, int set_id, int msg_id)
int csql_invoke_system_editor(void)
Definition: csql_support.c:252
char * strdup(const char *str)
Definition: porting.c:901
#define HA_DISABLED()
bool logddl_get_jsp_mode()
Definition: ddl_log.c:440
int csql_Row_count
Definition: csql.c:117
int sql_user_text_len
Definition: parse_tree.h:3445
int(* utf8_to_text_func)(const char *, const int, char **, int *)
void logddl_set_user_name(const char *user_name)
Definition: ddl_log.c:223
Definition: csql.c:178
DB_QUERY_TYPE * db_get_query_type_ptr(DB_QUERY_RESULT *result)
Definition: db_vdb.c:1431
int db_query_get_tuple_value(DB_QUERY_RESULT *result, int index, DB_VALUE *value)
Definition: db_query.c:2873
#define LOGDDL_TRAN_TYPE_ROLLBACK
Definition: ddl_log.h:36
Definition: csql.h:96
char * csql_get_tmp_buf(size_t size)
Definition: csql_support.c:779
void logddl_write_tran_str(const char *fmt,...)
Definition: ddl_log.c:807
static void csql_change_working_directory(const char *dirname)
Definition: csql.c:1661
void logddl_free(bool all_free)
Definition: ddl_log.c:143
bool skip_vacuum
Definition: csql.h:276
FILE * csql_Input_fp
Definition: csql.c:156
TEXT_CONVERSION * lang_get_txt_conv(void)
static int csql_Exit_status
Definition: csql.c:169
int csql_Error_code
Definition: csql.c:148
#define COLUMN_WIDTH_INFO_LIST_INIT_SIZE
Definition: csql.c:101
void prm_set_bool_value(PARAM_ID prm_id, bool value)
int db_commit_is_needed(void)
Definition: db_admin.c:1154
int db_set_statement_auto_commit(DB_SESSION *session, bool auto_commit)
Definition: db_vdb.c:4030
void logddl_set_err_code(int err_code)
Definition: ddl_log.c:361
#define CUB_MAXHOSTNAMELEN
Definition: porting.h:379
static void display_buffer(void)
Definition: csql.c:400
bool nopager
Definition: csql.h:269
static int initialize_csql_column_width_info_list()
Definition: csql.c:346
char csql_Editor_cmd[PATH_MAX]
Definition: csql.c:129
#define PLAN_DUMP_ENABLED(level)
Definition: optimizer.h:84
void logddl_set_ip(const char *ip_addr)
Definition: ddl_log.c:232
const char * user_name
Definition: csql.h:257
int db_checkpoint(void)
Definition: db_admin.c:1473
void logddl_set_stmt_type(int stmt_type)
Definition: ddl_log.c:291
const char * in_file_name
Definition: csql.h:259
static int csql_Is_histo_on
Definition: csql.c:179
DB_SESSION_ERROR * db_get_errors(DB_SESSION *session)
Definition: db_vdb.c:926
static void csql_set_sys_param(const char *arg_str)
Definition: csql.c:2303
bool column_output
Definition: csql.h:265
SIGNAL_HANDLER_FUNCTION os_set_signal_handler(const int sig_no, SIGNAL_HANDLER_FUNCTION sig_handler)
Definition: porting.c:1333
#define GETHOSTNAME(p, l)
Definition: porting.h:381
const char ** p
Definition: dynamic_load.c:945
DB_SESSION * db_open_file(FILE *file)
Definition: db_vdb.c:251
int db_statement_count(DB_SESSION *session)
Definition: db_vdb.c:132
static void csql_write_file(const char *file_name, int append_flag)
Definition: csql.c:1532
Definition: csql.h:92
void logddl_set_file_line(int file_line)
Definition: ddl_log.c:335
int db_commit_transaction(void)
Definition: db_admin.c:1091
int locator_log_force_nologging(void)
int csql_edit_read_file(FILE *fp)
void logddl_set_start_time(struct timeval *time_val)
Definition: ddl_log.c:370
char csql_Shell_cmd[PATH_MAX]
Definition: csql.c:135