CUBRID Engine  latest
object_printer.cpp
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  * object_printer.cpp
21  */
22 
23 #include "object_printer.hpp"
24 
25 #include "authenticate.h"
26 #include "class_description.hpp"
27 #include "class_object.h"
28 #include "db_json.hpp"
29 #include "db_value_printer.hpp"
30 #include "dbi.h"
31 #include "dbtype.h"
32 #include "misc_string.h"
33 #include "object_domain.h"
34 #include "object_primitive.h"
35 #include "object_print_util.hpp"
36 #include "parse_tree.h"
37 #include "schema_manager.h"
38 #include "set_object.h"
39 #include "string_buffer.hpp"
40 #include "trigger_manager.h"
41 #include "work_space.h"
42 #include "tde.h"
43 
44 #include <assert.h>
45 
46 //--------------------------------------------------------------------------------
47 void object_printer::describe_comment (const char *comment)
48 {
49  db_value comment_value;
50 
51  assert (comment != NULL);
52 
53  db_make_null (&comment_value);
54  db_make_string (&comment_value, comment);
55 
56  m_buf ("COMMENT ");
57  if (comment != NULL && comment[0] != '\0')
58  {
59  db_value_printer printer (m_buf);
60  printer.describe_value (&comment_value);
61  }
62  else
63  {
64  m_buf ("''");
65  }
66 
67  pr_clear_value (&comment_value);
68 }
69 
70 //--------------------------------------------------------------------------------
72 {
73  DB_VALUE ele;
74  int setsize, i;
75  db_value_printer obj_print (m_buf);
76 
77  db_make_null (&ele);
78 
79  m_buf ("PARTITION ");
80  describe_identifier (parts.pname, prt_type);
81 
82  switch (parts.partition_type)
83  {
84  case PT_PARTITION_HASH:
85  break;
86  case PT_PARTITION_RANGE:
87  m_buf (" VALUES LESS THAN ");
88  if (!set_get_element (parts.values, 1, &ele))
89  {
90  /* 0:MIN, 1: MAX */
91  if (DB_IS_NULL (&ele))
92  {
93  m_buf ("MAXVALUE");
94  }
95  else
96  {
97  m_buf ("(");
98  obj_print.describe_value (&ele);
99  m_buf (")");
100  }
101  }
102  break;
103  case PT_PARTITION_LIST:
104  m_buf (" VALUES IN (");
105  setsize = set_size (parts.values);
106  for (i = 0; i < setsize; i++)
107  {
108  if (i > 0)
109  {
110  m_buf (", ");
111  }
112  if (set_get_element (parts.values, i, &ele) == NO_ERROR)
113  {
114  obj_print.describe_value (&ele);
115  }
116  }
117  m_buf (")");
118  break;
119  }
120 
121  if (parts.comment != NULL && parts.comment[0] != '\0')
122  {
123  m_buf (" ");
124  describe_comment (parts.comment);
125  }
126 
127  pr_clear_value (&ele);
128 }
129 
130 /*
131  * object_print_identifier() - help function to print identifier string.
132  * if prt_type is OBJ_PRINT_SHOW_CREATE_TABLE,
133  * we need wrap it with "[" and "]".
134  * return: advanced buffer pointer
135  * parser(in) :
136  * buffer(in) : current buffer pointer
137  * identifier(in) : identifier string,.such as: table name.
138  * prt_type(in): the print type: csql schema or show create table
139  *
140  */
141 //--------------------------------------------------------------------------------
142 void object_printer::describe_identifier (const char *identifier, class_description::type prt_type)
143 {
145  {
146  m_buf ("%s", identifier);
147  }
148  else
149  {
150  //prt_type == OBJ_PRINT_SHOW_CREATE_TABLE
151  m_buf ("[%s]", identifier);
152  }
153 }
154 
155 /* CLASS COMPONENT DESCRIPTION FUNCTIONS */
156 
157 /*
158  * obj_print_describe_domain() - Describe the domain of an attribute
159  * return: advanced buffer pointer
160  * parser(in) :
161  * buffer(in) : current buffer pointer
162  * domain(in) : domain structure to describe
163  * prt_type(in): the print type: csql schema or show create table
164  * force_print_collation(in): true if collation is printed no matter system
165  * collation
166  *
167  */
168 //--------------------------------------------------------------------------------
170  bool force_print_collation)
171 {
172  TP_DOMAIN *temp_domain;
173  char temp_buffer[27];
174  int precision = 0, idx, count;
175  int has_collation;
176 
177  /* filter first, usually not necessary but this is visible */
178  sm_filter_domain (&domain, NULL);
179 
180  for (temp_domain = &domain; temp_domain != NULL; temp_domain = temp_domain->next)
181  {
182  has_collation = 0;
183  switch (TP_DOMAIN_TYPE (temp_domain))
184  {
185  case DB_TYPE_INTEGER:
186  case DB_TYPE_BIGINT:
187  case DB_TYPE_FLOAT:
188  case DB_TYPE_DOUBLE:
189  case DB_TYPE_BLOB:
190  case DB_TYPE_CLOB:
191  case DB_TYPE_TIME:
192  case DB_TYPE_TIMESTAMP:
193  case DB_TYPE_TIMESTAMPTZ:
195  case DB_TYPE_DATETIME:
196  case DB_TYPE_DATETIMETZ:
197  case DB_TYPE_DATETIMELTZ:
198  case DB_TYPE_DATE:
199  case DB_TYPE_MONETARY:
200  case DB_TYPE_SUB:
201  case DB_TYPE_POINTER:
202  case DB_TYPE_ERROR:
203  case DB_TYPE_SHORT:
204  case DB_TYPE_VOBJ:
205  case DB_TYPE_OID:
206  case DB_TYPE_NULL:
207  case DB_TYPE_VARIABLE:
208  case DB_TYPE_DB_VALUE:
209  strcpy (temp_buffer, temp_domain->type->name);
210  m_buf ("%s", ustr_upper (temp_buffer));
211  break;
212 
213  case DB_TYPE_OBJECT:
214  if (temp_domain->class_mop != NULL)
215  {
216  describe_identifier (sm_get_ch_name (temp_domain->class_mop), prt_type);
217  }
218  else
219  {
220  m_buf ("%s", temp_domain->type->name);
221  }
222  break;
223 
224  case DB_TYPE_VARCHAR:
225  has_collation = 1;
226  if (temp_domain->precision == TP_FLOATING_PRECISION_VALUE)
227  {
228  m_buf ("STRING");
229  break;
230  }
231  /* FALLTHRU */
232  case DB_TYPE_CHAR:
233  case DB_TYPE_NCHAR:
234  case DB_TYPE_VARNCHAR:
235  has_collation = 1;
236  /* FALLTHRU */
237  case DB_TYPE_BIT:
238  case DB_TYPE_VARBIT:
239  strcpy (temp_buffer, temp_domain->type->name);
240  if (temp_domain->precision == TP_FLOATING_PRECISION_VALUE)
241  {
242  precision = DB_MAX_STRING_LENGTH;
243  }
244  else
245  {
246  precision = temp_domain->precision;
247  }
248  m_buf ("%s(%d)", ustr_upper (temp_buffer), precision);
249  break;
250 
251  case DB_TYPE_JSON:
252  strcpy (temp_buffer, temp_domain->type->name);
253  ustr_upper (temp_buffer);
254  if (temp_domain->json_validator != NULL)
255  {
256  m_buf ("%s(\'%s\')", temp_buffer, db_json_get_schema_raw_from_validator (temp_domain->json_validator));
257  }
258  else
259  {
260  m_buf (temp_buffer);
261  }
262  break;
263 
264  case DB_TYPE_NUMERIC:
265  strcpy (temp_buffer, temp_domain->type->name);
266  m_buf ("%s(%d,%d)", ustr_upper (temp_buffer), temp_domain->precision, temp_domain->scale);
267  break;
268 
269  case DB_TYPE_SET:
270  case DB_TYPE_MULTISET:
271  case DB_TYPE_SEQUENCE:
272  strcpy (temp_buffer, temp_domain->type->name);
273  ustr_upper (temp_buffer);
274  m_buf ("%s OF ", temp_buffer);
275  if (temp_domain->setdomain != NULL)
276  {
277  if (temp_domain->setdomain->next != NULL && prt_type == class_description::SHOW_CREATE_TABLE)
278  {
279  m_buf ("(");
280  describe_domain (*temp_domain->setdomain, prt_type, force_print_collation);
281  m_buf (")");
282  }
283  else
284  {
285  describe_domain (*temp_domain->setdomain, prt_type, force_print_collation);
286  }
287  }
288  break;
289 
290  case DB_TYPE_ENUMERATION:
291  has_collation = 1;
292  strcpy (temp_buffer, temp_domain->type->name);
293  m_buf ("%s(", ustr_upper (temp_buffer));
294  count = DOM_GET_ENUM_ELEMS_COUNT (temp_domain);
295  for (idx = 1; idx <= count; idx++)
296  {
297  if (idx > 1)
298  {
299  m_buf (", ");
300  }
301  m_buf ("'");
303  DB_GET_ENUM_ELEM_STRING (&DOM_GET_ENUM_ELEM (temp_domain, idx)));
304  m_buf ("'");
305  }
306  m_buf (")");
307  break;
308 
309  default:
310  break;
311  }
312 
313  if (has_collation && (force_print_collation || temp_domain->collation_id != LANG_SYS_COLLATION))
314  {
315  m_buf (" COLLATE %s", lang_get_collation_name (temp_domain->collation_id));
316  }
317  if (temp_domain->next != NULL)
318  {
319  m_buf (", ");
320  }
321  }
322 }
323 
324 /*
325  * obj_print_describe_argument() - Describes a method argument
326  * return: advanced buffer pointer
327  * parser(in) :
328  * buffer(in) : current buffer pointer
329  * argument_p(in) : method argument to describe
330  * prt_type(in): the print type: csql schema or show create table
331  *
332  */
333 //--------------------------------------------------------------------------------
335 {
336  if (argument.domain != NULL)
337  {
338  /* method and its arguments do not inherit collation from class, collation printing is not enforced */
339  describe_domain (*argument.domain, prt_type, false);
340  }
341  else if (argument.type)
342  {
343  m_buf ("%s", argument.type->name);
344  }
345  else
346  {
347  m_buf ("invalid type");
348  }
349 }
350 
351 /*
352  * describe_method() - Describes the definition of a method in a class
353  * return: advanced buffer pointer
354  * parser(in) : current buffer pointer
355  * op(in) : class with method
356  * method_p(in) : method to describe
357  * prt_type(in): the print type: csql schema or show create table
358  *
359  */
360 //--------------------------------------------------------------------------------
361 void object_printer::describe_method (const struct db_object &op, const sm_method &method,
362  class_description::type prt_type)
363 {
364  SM_METHOD_SIGNATURE *signature_p;
365 
366  /* assume for the moment that there can only be one signature, simplifies the output */
367  describe_identifier (method.header.name, prt_type);
368 
369  signature_p = method.signatures;
370  if (signature_p == NULL)
371  {
372  m_buf ("()");
373  }
374  else
375  {
376  m_buf ("(");
377  describe_signature (*signature_p, prt_type);
378  m_buf (") ");
379 
380  if (signature_p->value != NULL)
381  {
382  /* make this look more like the actual definition instead strcpy(line, "returns "); line += strlen(line); */
383  describe_argument (*signature_p->value, prt_type);
384  }
385  if (signature_p->function_name != NULL)
386  {
387  m_buf (" FUNCTION ");
388  describe_identifier (signature_p->function_name, prt_type);
389  }
390  }
391 
392  /* add the inheritance source */
393  if (method.class_mop != NULL && method.class_mop != &op)
394  {
395 
396  m_buf ("(from ");
397  describe_identifier (sm_get_ch_name (method.class_mop), prt_type);
398  m_buf (")");
399  }
400 }
401 
402 /*
403  * obj_print_describe_signature() - Describes a method signature
404  * return: advanced buffer pointer
405  * parser(in) :
406  * buffer(in) : current buffer pointer
407  * signature_p(in) : signature to describe
408  * prt_type(in): the print type: csql schema or show create table
409  *
410  */
411 //--------------------------------------------------------------------------------
413 {
414  SM_METHOD_ARGUMENT *argument_p;
415  int i;
416 
417  for (i = 1; i <= signature.num_args; i++)
418  {
419  for (argument_p = signature.args; argument_p != NULL && argument_p->index != i; argument_p=argument_p->next)
420  ;
421 
422  if (argument_p != NULL)
423  {
424  describe_argument (*argument_p, prt_type);
425  }
426  else
427  {
428  m_buf ("??");
429  }
430 
431  if (i < signature.num_args)
432  {
433  m_buf (", ");
434  }
435  }
436 }
437 
438 /* CLASS COMPONENT DESCRIPTION FUNCTIONS */
439 
440 /*
441  * obj_print_describe_attribute() - Describes the definition of an attribute
442  * in a class
443  * return: advanced bufbuffer pointer
444  * class_p(in) : class being examined
445  * parser(in) :
446  * attribute_p(in) : attribute of the class
447  * is_inherited(in) : is the attribute inherited
448  * prt_type(in): the print type: csql schema or show create table
449  * obj_print_describe_attribute(in):
450  *
451  */
452 //--------------------------------------------------------------------------------
453 void object_printer::describe_attribute (const struct db_object &cls, const sm_attribute &attribute,
454  bool is_inherited, class_description::type prt_type, bool force_print_collation)
455 {
456  char str_buf[NUMERIC_MAX_STRING_SIZE];
457  db_value_printer printer (m_buf);
458 
460  {
461  m_buf ("%-20s ", attribute.header.name);
462  }
463  else
464  {
465  /* prt_type == OBJ_PRINT_SHOW_CREATE_TABLE */
466  describe_identifier (attribute.header.name, prt_type);
467  m_buf (" ");
468  }
469 
470  /* could filter here but do in describe_domain */
471  describe_domain (*attribute.domain, prt_type, force_print_collation);
472 
473  if (attribute.header.name_space == ID_SHARED_ATTRIBUTE)
474  {
475  m_buf (" SHARED ");
476  if (!DB_IS_NULL (&attribute.default_value.value))
477  {
478  printer.describe_value (&attribute.default_value.value);
479  }
480  }
481  else if (attribute.header.name_space == ID_ATTRIBUTE)
482  {
483  if (attribute.flags & SM_ATTFLAG_AUTO_INCREMENT)
484  {
485  m_buf (" AUTO_INCREMENT ");
486 
487  assert (is_inherited || attribute.auto_increment != NULL);
488 
489  if (prt_type == class_description::SHOW_CREATE_TABLE)
490  {
491  DB_VALUE min_val, inc_val;
492  char buff[DB_MAX_NUMERIC_PRECISION * 2 + 4];
493  int offset;
494 
495  assert (attribute.auto_increment != NULL);
496 
497  db_make_null (&min_val);
498  db_make_null (&inc_val);
499 
500  if (db_get (attribute.auto_increment, "min_val", &min_val) != NO_ERROR)
501  {
502  return;
503  }
504 
505  if (db_get (attribute.auto_increment, "increment_val", &inc_val) != NO_ERROR)
506  {
507  pr_clear_value (&min_val);
508  return;
509  }
510 
511  offset = snprintf (buff, DB_MAX_NUMERIC_PRECISION + 3, "(%s, ",
512  numeric_db_value_print (&min_val, str_buf));
513  snprintf (buff + offset, DB_MAX_NUMERIC_PRECISION + 1, "%s)", numeric_db_value_print (&inc_val, str_buf));
514  m_buf (buff);
515 
516  pr_clear_value (&min_val);
517  pr_clear_value (&inc_val);
518  }
519  }
520 
521  if (!DB_IS_NULL (&attribute.default_value.value)
523  {
524  const char *default_expr_type_str;
525 
526  m_buf (" DEFAULT ");
527 
529  {
530  m_buf ("TO_CHAR(");
531  }
532 
533  default_expr_type_str = db_default_expression_string (attribute.default_value.default_expr.default_expr_type);
534  if (default_expr_type_str != NULL)
535  {
536  m_buf ("%s", default_expr_type_str);
537  }
538  else
539  {
541  printer.describe_value (&attribute.default_value.value);
542  }
543 
545  {
547  {
548  m_buf (", \'%s\'", attribute.default_value.default_expr.default_expr_format);
549  }
550  m_buf (")");
551  }
552  }
553 
554  if (attribute.on_update_default_expr != DB_DEFAULT_NONE)
555  {
556  const char *default_expr_type_str;
557 
558  m_buf (" ON UPDATE ");
559  default_expr_type_str = db_default_expression_string (attribute.on_update_default_expr);
560  m_buf ("%s", default_expr_type_str);
561  }
562  }
563  else if (attribute.header.name_space == ID_CLASS_ATTRIBUTE)
564  {
565  if (!DB_IS_NULL (&attribute.default_value.value))
566  {
567  m_buf (" VALUE ");
568  printer.describe_value (&attribute.default_value.value);
569  }
570  }
571 
572  if (attribute.flags & SM_ATTFLAG_NON_NULL)
573  {
574  m_buf (" NOT NULL");
575  }
576 
577  if (attribute.class_mop != NULL && attribute.class_mop != &cls)
578  {
579  m_buf (" /* from ");
580  describe_identifier (sm_get_ch_name (attribute.class_mop), prt_type);
581  m_buf (" */");
582  }
583 
584  if (attribute.comment != NULL && attribute.comment[0] != '\0')
585  {
586  m_buf (" ");
587  describe_comment (attribute.comment);
588  }
589 }
590 
591 /*
592  * obj_print_describe_constraint() - Describes the definition of an attribute
593  * in a class
594  * return: advanced buffer pointer
595  * parser(in) :
596  * class_p(in) : class being examined
597  * constraint_p(in) :
598  * prt_type(in): the print type: csql schema or show create table
599  *
600  */
601 //--------------------------------------------------------------------------------
603  class_description::type prt_type)
604 {
605  SM_ATTRIBUTE **attribute_p;
606  const int *asc_desc;
607  const int *prefix_length;
608  int k, n_attrs = 0;
609 
611  {
612  switch (constraint.type)
613  {
614  case SM_CONSTRAINT_INDEX:
615  m_buf ("INDEX ");
616  break;
618  m_buf ("UNIQUE ");
619  break;
621  m_buf ("REVERSE INDEX ");
622  break;
624  m_buf ("REVERSE UNIQUE ");
625  break;
627  m_buf ("PRIMARY KEY ");
628  break;
630  m_buf ("FOREIGN KEY ");
631  break;
632  default:
633  m_buf ("CONSTRAINT ");
634  break;
635  }
636 
637  m_buf ("%s ON %s (", constraint.name, sm_ch_name ((MOBJ) (&cls)));
638  asc_desc = NULL; /* init */
640  {
641  asc_desc = constraint.asc_desc;
642  }
643  }
644  else
645  {
646  /* prt_type == OBJ_PRINT_SHOW_CREATE_TABLE */
647  switch (constraint.type)
648  {
649  case SM_CONSTRAINT_INDEX:
651  m_buf (" INDEX ");
652  describe_identifier (constraint.name, prt_type);
653  break;
656  m_buf (" CONSTRAINT ");
657  describe_identifier (constraint.name, prt_type);
658  m_buf (" UNIQUE KEY ");
659  break;
661  m_buf (" CONSTRAINT ");
662  describe_identifier (constraint.name, prt_type);
663  m_buf (" PRIMARY KEY ");
664  break;
666  m_buf (" CONSTRAINT ");
667  describe_identifier (constraint.name, prt_type);
668  m_buf (" FOREIGN KEY ");
669  break;
670  default:
671  assert (false);
672  break;
673  }
674 
675  m_buf (" (");
676  asc_desc = constraint.asc_desc;
677  }
678 
679  prefix_length = constraint.attrs_prefix_length;
680 
681  /* If the index is a function index, then the corresponding expression is printed at the right position in the
682  * attribute list. Since the expression is not part of the attribute list, when searching through that list we must
683  * check if the position of the expression is reached and then print it. */
684  k = 0;
685  if (constraint.func_index_info)
686  {
687  n_attrs = constraint.func_index_info->attr_index_start + 1;
688  }
689  else
690  {
691  for (attribute_p = constraint.attributes; *attribute_p; attribute_p++)
692  {
693  n_attrs++;
694  }
695  }
696 
697  for (attribute_p = constraint.attributes; k < n_attrs; attribute_p++)
698  {
699  if (constraint.func_index_info && k == constraint.func_index_info->col_id)
700  {
701  if (k > 0)
702  {
703  m_buf (", ");
704  }
705  m_buf ("%s", constraint.func_index_info->expr_str);
706  if (constraint.func_index_info->fi_domain->is_desc)
707  {
708  m_buf (" DESC");
709  }
710  k++;
711  }
712  if (k == n_attrs)
713  {
714  break;
715  }
716  if (k > 0)
717  {
718  m_buf (", ");
719  }
720  describe_identifier ((*attribute_p)->header.name, prt_type);
721 
722  if (prefix_length)
723  {
724  if (*prefix_length != -1)
725  {
726  m_buf ("(%d)", *prefix_length);
727  }
728 
729  prefix_length++;
730  }
731 
732  if (asc_desc)
733  {
734  if (*asc_desc == 1)
735  {
736  m_buf (" DESC");
737  }
738  asc_desc++;
739  }
740  k++;
741  }
742 
743  m_buf (")");
744 
745  if (constraint.filter_predicate && constraint.filter_predicate->pred_string)
746  {
747  m_buf (" WHERE %s", constraint.filter_predicate->pred_string);
748  }
749 
750  if (constraint.type == SM_CONSTRAINT_FOREIGN_KEY && constraint.fk_info)
751  {
752  MOP ref_clsop;
753  SM_CLASS *ref_cls;
755 
756  ref_clsop = ws_mop (& (constraint.fk_info->ref_class_oid), NULL);
757  if (au_fetch_class_force (ref_clsop, &ref_cls, AU_FETCH_READ) != NO_ERROR)
758  {
759  return;
760  }
761 
762  m_buf (" REFERENCES ");
763  describe_identifier (sm_ch_name ((MOBJ) ref_cls), prt_type);
764 
765  if (prt_type == class_description::SHOW_CREATE_TABLE)
766  {
767  for (c = ref_cls->constraints; c; c = c->next)
768  {
769  if (c->type == SM_CONSTRAINT_PRIMARY_KEY && c->attributes != NULL)
770  {
771  m_buf (" (");
772 
773  for (k = 0; k < n_attrs; k++)
774  {
775  if (c->attributes[k] != NULL)
776  {
777  describe_identifier (c->attributes[k]->header.name, prt_type);
778  if (k != (n_attrs - 1))
779  {
780  m_buf (", ");
781  }
782  }
783  }
784 
785  m_buf (")");
786  break;
787  }
788  }
789  }
790 
791  m_buf (" ON DELETE %s", classobj_describe_foreign_key_action (constraint.fk_info->delete_action));
792 
794  {
795  m_buf (",");
796  }
797 
798  m_buf (" ON UPDATE %s", classobj_describe_foreign_key_action (constraint.fk_info->update_action));
799  }
800 
801  if (constraint.comment != NULL && constraint.comment[0] != '\0')
802  {
803  m_buf (" ");
804  describe_comment (constraint.comment);
805  }
806 
807  if (constraint.index_status == SM_INVISIBLE_INDEX)
808  {
809  m_buf (" INVISIBLE");
810  }
811 
813  {
815  {
816  m_buf (" IN PROGRESS");
817  }
818  }
819 }
820 
821 /*
822  * obj_print_describe_resolution() - Describes a resolution specifier
823  * return: advanced buffer pointer
824  * parser(in) :
825  * resolution_p(in) : resolution to describe
826  * prt_type(in): the print type: csql schema or show create table
827  *
828  */
829 //--------------------------------------------------------------------------------
831 {
832  if (prt_type != class_description::SHOW_CREATE_TABLE)
833  {
834  if (resolution.name_space == ID_CLASS)
835  {
836  m_buf ("inherit CLASS ");
837  }
838  else
839  {
840  m_buf ("inherit ");
841  }
842  }
843 
844  describe_identifier (resolution.name, prt_type);
845 
846  m_buf (" of ");
847 
848  describe_identifier (sm_get_ch_name (resolution.class_mop), prt_type);
849 
850  if (resolution.alias != NULL)
851  {
852  m_buf (" as ");
853  describe_identifier (resolution.alias, prt_type);
854  }
855 }
856 
857 /*
858  * obj_print_describe_method_file () - Describes a method file.
859  * return: advanced buffer pointer
860  * parser(in) :
861  * class_p(in) :
862  * file_p(in): method file descriptor
863  */
864 //--------------------------------------------------------------------------------
865 void object_printer::describe_method_file (const struct db_object &obj, const sm_method_file &file)
866 {
867  m_buf ("%s", file.name);
868 
869  if (file.class_mop != NULL && file.class_mop != &obj)
870  {
871  m_buf (" (from %s)", sm_get_ch_name (file.class_mop));
872  }
873 }
874 
875 /*
876  * describe_class_trigger () - Describes the given trigger object to a buffer.
877  * return: PARSER_VARCHAR *
878  * parser(in): buffer for description
879  * trigger(in): trigger object
880  * Note :
881  * This description is for the class help and as such it contains
882  * a condensed versino of the trigger help.
883  */
884 //--------------------------------------------------------------------------------
886 {
887  m_buf ("%s : %s %s ", trigger.name, describe_trigger_condition_time (trigger), tr_event_as_string (trigger.event));
888 
889  if (trigger.attribute != NULL)
890  {
891  m_buf ("OF %s", trigger.attribute);
892  }
893 
894  if (trigger.comment != NULL && trigger.comment[0] != '\0')
895  {
896  m_buf (" ");
897  describe_comment (trigger.comment);
898  }
899 }
900 
901 /*
902  * obj_print_trigger_condition_time() -
903  * return: char *
904  * trigger(in) :
905  */
906 //--------------------------------------------------------------------------------
908 {
910 
911  if (trigger.condition != NULL)
912  {
913  time = trigger.condition->time;
914  }
915  else if (trigger.action != NULL)
916  {
917  time = trigger.action->time;
918  }
919 
920  return (tr_time_as_string (time));
921 }
922 
923 /*
924  * obj_print_trigger_action_time() -
925  * return: char *
926  * trigger(in) :
927  */
928 //--------------------------------------------------------------------------------
930 {
932 
933  if (trigger.action != NULL)
934  {
935  time = trigger.action->time;
936  }
937 
938  return (tr_time_as_string (time));
939 }
940 
941 /*
942  * obj_print_describe_class() - Describes the definition of a class
943  * return: create table string
944  * parser(in):
945  * class_schema(in):
946  * class_op(in):
947  */
948 //--------------------------------------------------------------------------------
950 {
951  m_buf.clear ();
952 
953  class_description class_descr;
954  TDE_ALGORITHM tde_algo;
955  const char *tde_algo_str;
956 
957  if (class_descr.init (class_op, class_description::SHOW_CREATE_TABLE, m_buf) != NO_ERROR)
958  {
959 #if 0 //what do we do in case of error???
960  int error = er_errid();
961  assert (error != NO_ERROR);
962  if (error == ER_AU_SELECT_FAILURE)
963  {
965  db_get_class_name (class_op));
966  }
967  else
968  {
969  PT_ERRORc (parser, table_name, er_msg());
970  }
971 #endif
972  return;
973  }
974 
975  m_buf.clear ();
976 
977  char **line_ptr;
978 
979  /* class name */
980  m_buf ("CREATE TABLE %s", class_descr.name);
981 
982  /* under or as subclass of */
983  if (class_descr.supers != NULL)
984  {
985  m_buf (" UNDER ");
986 
987  for (line_ptr = class_descr.supers; *line_ptr != NULL; line_ptr++)
988  {
989  if (line_ptr != class_descr.supers)
990  {
991  m_buf (", ");
992  }
993  m_buf ("%s", (*line_ptr));
994  }
995  }
996 
997  /* class attributes */
998  if (class_descr.class_attributes != NULL)
999  {
1000  m_buf (" CLASS ATTRIBUTE (");
1001 
1002  for (line_ptr = class_descr.class_attributes; *line_ptr != NULL; line_ptr++)
1003  {
1004  if (line_ptr != class_descr.class_attributes)
1005  {
1006  m_buf (", ");
1007  }
1008  m_buf ("%s", *line_ptr);
1009  }
1010 
1011  m_buf (")");
1012  }
1013 
1014  /* attributes and constraints */
1015  if (class_descr.attributes != NULL || class_descr.constraints != NULL)
1016  {
1017  m_buf (" (");
1018 
1019  if (class_descr.attributes != NULL)
1020  {
1021  for (line_ptr = class_descr.attributes; *line_ptr != NULL; line_ptr++)
1022  {
1023  if (line_ptr != class_descr.attributes)
1024  {
1025  m_buf (", ");
1026  }
1027  m_buf ("%s", *line_ptr);
1028  }
1029  }
1030 
1031  if (class_descr.constraints != NULL)
1032  {
1033  for (line_ptr = class_descr.constraints; *line_ptr != NULL; line_ptr++)
1034  {
1035  if (line_ptr != class_descr.constraints || class_descr.attributes != NULL)
1036  {
1037  m_buf (", ");
1038  }
1039  m_buf ("%s", *line_ptr);
1040  }
1041  }
1042 
1043  m_buf += ')';
1044  }
1045 
1046  /* reuse_oid flag */
1047  if (sm_is_reuse_oid_class (class_op))
1048  {
1049  m_buf (" REUSE_OID");
1050  }
1051  else
1052  {
1053  m_buf (" DONT_REUSE_OID");
1054  }
1055 
1056  /* collation */
1057  if (class_descr.collation != NULL)
1058  {
1059  m_buf (", COLLATE %s", class_descr.collation);
1060  }
1061 
1062  /* tde_algorithm */
1063  if (sm_get_class_tde_algorithm (class_op, &tde_algo) == NO_ERROR)
1064  {
1065  if (tde_algo != TDE_ALGORITHM_NONE)
1066  {
1067  tde_algo_str = tde_get_algorithm_name (tde_algo);
1068  assert (tde_algo_str != NULL);
1069  m_buf (" ENCRYPT=%s", tde_algo_str);
1070  }
1071  }
1072 
1073  /* methods and class_methods */
1074  if (class_descr.methods != NULL || class_descr.class_methods != NULL)
1075  {
1076  m_buf (" METHOD ");
1077 
1078  if (class_descr.methods != NULL)
1079  {
1080  for (line_ptr = class_descr.methods; *line_ptr != NULL; line_ptr++)
1081  {
1082  if (line_ptr != class_descr.methods)
1083  {
1084  m_buf (", ");
1085  }
1086  m_buf ("%s", *line_ptr);
1087  }
1088  }
1089 
1090  if (class_descr.class_methods != NULL)
1091  {
1092  for (line_ptr = class_descr.class_methods; *line_ptr != NULL; line_ptr++)
1093  {
1094  if (line_ptr != class_descr.class_methods || class_descr.methods != NULL)
1095  {
1096  m_buf (", ");
1097  }
1098  m_buf (" CLASS %s", *line_ptr);
1099  }
1100  }
1101  }
1102 
1103  /* method files */
1104  if (class_descr.method_files != NULL)
1105  {
1106  m_buf (" FILE ");
1107 
1108  for (line_ptr = class_descr.method_files; *line_ptr != NULL; line_ptr++)
1109  {
1110  if (line_ptr != class_descr.method_files)
1111  {
1112  m_buf (", ");
1113  }
1114  m_buf ("'%s'", *line_ptr);
1115  }
1116  }
1117 
1118  /* inherit */
1119  if (class_descr.resolutions != NULL)
1120  {
1121  m_buf (" INHERIT ");
1122 
1123  for (line_ptr = class_descr.resolutions; *line_ptr != NULL; line_ptr++)
1124  {
1125  if (line_ptr != class_descr.resolutions)
1126  {
1127  m_buf (", ");
1128  }
1129  m_buf ("%s", *line_ptr);
1130  }
1131  }
1132 
1133  /* partition */
1134  if (!class_descr.partition.empty ())
1135  {
1136  m_buf (" %s", class_descr.partition[0]);
1137 
1138  size_t len = class_descr.partition.size ();
1139 
1140  if (len > 1)
1141  {
1142  m_buf (" (%s", class_descr.partition[1]);
1143  for (size_t i=2; i<len; ++i)
1144  {
1145  m_buf (", %s", class_descr.partition[i]);
1146  }
1147  m_buf (")");
1148  }
1149  }
1150 
1151  /* comment */
1152  if (class_descr.comment != NULL && class_descr.comment[0] != '\0')
1153  {
1154  DB_VALUE comment_value;
1155  db_make_null (&comment_value);
1156  db_make_string (&comment_value, class_descr.comment);
1157 
1158  m_buf (" COMMENT=");
1159 
1160  db_value_printer printer (m_buf);
1161 
1162  printer.describe_value (&comment_value);
1163  pr_clear_value (&comment_value);
1164  }
1165 }
1166 
1167 /*
1168  * obj_print_describe_partition_info() -
1169  * return: char *
1170  * parser(in) :
1171  * partinfo(in) :
1172  *
1173  */
1174 //--------------------------------------------------------------------------------
1176 {
1177  DB_VALUE ele;
1178  char col_name[DB_MAX_IDENTIFIER_LENGTH + 1];
1179 
1180  m_buf ("PARTITION BY ");
1181 
1182  switch (partinfo.partition_type)
1183  {
1184  case PT_PARTITION_HASH:
1185  m_buf ("HASH (");
1186  break;
1187  case PT_PARTITION_RANGE:
1188  m_buf ("RANGE (");
1189  break;
1190  case PT_PARTITION_LIST:
1191  m_buf ("LIST (");
1192  break;
1193  }
1194 
1195  char *tmp = (char *) partinfo.expr;
1196  assert (tmp != NULL);
1197 
1198  char *ptr = tmp ? strstr (tmp, "SELECT ") : NULL;
1199 
1200  if (ptr)
1201  {
1202  char *ptr2 = strstr (ptr + 7, " FROM ");
1203  if (ptr2)
1204  {
1205  strncpy (col_name, ptr + 7, CAST_STRLEN (ptr2 - (ptr + 7)));
1206  col_name[CAST_STRLEN (ptr2 - (ptr + 7))] = 0;
1207  m_buf ("%s) ", col_name);
1208  }
1209  }
1210 
1211  if (partinfo.partition_type == PT_PARTITION_HASH)
1212  {
1213  if (set_get_element (partinfo.values, 1, &ele) == NO_ERROR)
1214  {
1215  m_buf ("PARTITIONS %d", db_get_int (&ele));
1216  }
1217  }
1218 }
const char * name
Definition: class_object.h:631
DB_TRIGGER_TIME time
const char * expr
Definition: class_object.h:697
void describe_class(struct db_object *class_op)
#define NO_ERROR
Definition: error_code.h:46
#define DB_GET_ENUM_ELEM_STRING(elem)
Definition: dbtype.h:103
char * ustr_upper(char *s)
Definition: misc_string.c:98
#define LANG_SYS_COLLATION
SM_FOREIGN_KEY_INFO * fk_info
Definition: class_object.h:537
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
std::vector< char * > partition
MOP ws_mop(const OID *oid, MOP class_mop)
Definition: work_space.c:614
SM_COMPONENT header
Definition: class_object.h:591
SM_PREDICATE_INFO * filter_predicate
Definition: class_object.h:536
char * MOBJ
Definition: work_space.h:174
#define DB_MAX_STRING_LENGTH
Definition: dbtype_def.h:516
struct tr_activity * condition
int db_get_int(const DB_VALUE *value)
const char * name
Definition: class_object.h:616
struct tp_domain * setdomain
Definition: object_domain.h:82
TP_DOMAIN * domain
Definition: class_object.h:444
const char * tr_time_as_string(DB_TRIGGER_TIME time)
void describe_partition_parts(const sm_partition &parts, class_description::type prt_type)
void describe_method(const struct db_object &op, const sm_method &method_p, class_description::type prt_type)
DB_TRIGGER_EVENT event
SM_DEFAULT_VALUE default_value
Definition: class_object.h:451
void describe_attribute(const struct db_object &class_p, const sm_attribute &attribute_p, bool is_inherited, class_description::type prt_type, bool force_print_collation)
TP_DOMAIN * domain
Definition: class_object.h:559
#define CAST_STRLEN
Definition: porting.h:470
SM_FUNCTION_INFO * func_index_info
Definition: class_object.h:541
const char * db_default_expression_string(DB_DEFAULT_EXPR_TYPE default_expr_type)
Definition: db_macro.c:4947
const char * pname
Definition: class_object.h:694
static const char * describe_trigger_condition_time(const tr_trigger &trigger)
SM_METHOD_ARGUMENT * value
Definition: class_object.h:575
struct sm_class_constraint * next
Definition: class_object.h:530
SM_NAME_SPACE name_space
Definition: class_object.h:386
int er_errid(void)
const char * comment
Definition: class_object.h:698
int set_size(DB_COLLECTION *set)
Definition: set_object.c:3036
const char * name
SM_FOREIGN_KEY_ACTION update_action
Definition: class_object.h:482
void describe_value(const db_value *value)
const char * comment
Definition: class_object.h:542
DB_DEFAULT_EXPR_TYPE default_expr_type
Definition: dbtype_def.h:1204
const char * lang_get_collation_name(const int coll_id)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
void describe_method_file(const struct db_object &obj, const sm_method_file &file)
int init(const char *name)
DB_DEFAULT_EXPR default_expr
Definition: class_object.h:395
const char * tde_get_algorithm_name(TDE_ALGORITHM tde_algo)
Definition: tde.c:1694
void describe_resolution(const sm_resolution &resolution, class_description::type prt_type)
const char * sm_ch_name(const MOBJ clobj)
struct tr_activity * action
#define NULL_DEFAULT_EXPRESSION_OPERATOR
Definition: dbtype_def.h:659
#define DB_MAX_NUMERIC_PRECISION
Definition: dbtype_def.h:522
#define PT_ERRORmf2(parser, node, setNo, msgNo, arg1, arg2)
Definition: parse_tree.h:65
#define assert(x)
TDE_ALGORITHM
Definition: tde.h:71
const char * comment
#define MSGCAT_SET_PARSER_RUNTIME
const char * db_json_get_schema_raw_from_validator(JSON_VALIDATOR *val)
Definition: db_json.cpp:2310
unsigned is_desc
#define DB_MAX_IDENTIFIER_LENGTH
Definition: dbtype_def.h:495
#define DOM_GET_ENUM_ELEM(dom, idx)
Definition: object_domain.h:44
SM_NAME_SPACE name_space
Definition: class_object.h:633
#define DOM_GET_ENUM_ELEMS_COUNT(dom)
Definition: object_domain.h:42
DB_SEQ * values
Definition: class_object.h:696
int sm_filter_domain(TP_DOMAIN *domain, int *changes)
const char * sm_get_ch_name(MOP op)
const char * function_name
Definition: class_object.h:570
#define TP_DOMAIN_TYPE(dom)
TP_DOMAIN * fi_domain
Definition: class_object.h:502
SP_PARSER_CTX * parser
#define NULL
Definition: freelistheap.h:34
#define NUMERIC_MAX_STRING_SIZE
const char * er_msg(void)
struct pr_type * type
Definition: object_domain.h:76
const char * alias
Definition: class_object.h:632
SM_METHOD_SIGNATURE * signatures
Definition: class_object.h:593
void describe_constraint(const sm_class &class_p, const sm_class_constraint &constraint_p, class_description::type prt_type)
void describe_domain(tp_domain &domain, class_description::type prt_type, bool force_print_collation)
#define PT_ERRORc(parser, node, msg)
Definition: parse_tree.h:55
struct pr_type * type
Definition: class_object.h:558
int set_get_element(DB_COLLECTION *set, int index, DB_VALUE *value)
Definition: set_object.c:2575
int count(int &result, const cub_regex_object &reg, const std::string &src, const int position, const INTL_CODESET codeset)
int pr_clear_value(DB_VALUE *value)
DB_TRIGGER_TIME
Definition: dbtype_def.h:388
void describe_class_trigger(const tr_trigger &trigger)
static void error(const char *msg)
Definition: gencat.c:331
void describe_comment(const char *comment)
DB_DEFAULT_EXPR_TYPE on_update_default_expr
Definition: class_object.h:452
unsigned int flags
Definition: class_object.h:459
#define DB_GET_ENUM_ELEM_STRING_SIZE(elem)
Definition: dbtype.h:105
char * numeric_db_value_print(const DB_VALUE *val, char *buf)
const char * default_expr_format
Definition: dbtype_def.h:1206
const char * tr_event_as_string(DB_TRIGGER_EVENT event)
#define ER_AU_SELECT_FAILURE
Definition: error_code.h:221
SM_FOREIGN_KEY_ACTION delete_action
Definition: class_object.h:481
bool sm_is_reuse_oid_class(MOP op)
SM_COMPONENT header
Definition: class_object.h:441
void describe_partition_info(const sm_partition &partinfo)
int db_get(DB_OBJECT *object, const char *attpath, DB_VALUE *value)
Definition: db_obj.c:233
SM_ATTRIBUTE ** attributes
Definition: class_object.h:533
JSON_VALIDATOR * json_validator
SM_METHOD_ARGUMENT * args
Definition: class_object.h:577
#define TP_FLOATING_PRECISION_VALUE
#define SM_IS_CONSTRAINT_REVERSE_INDEX_FAMILY(c)
Definition: class_object.h:124
SM_CONSTRAINT_TYPE type
Definition: class_object.h:540
void describe_identifier(const char *identifier, class_description::type prt_type)
int i
Definition: dynamic_load.c:954
int db_make_null(DB_VALUE *value)
static const char * describe_trigger_action_time(const tr_trigger &trigger)
#define DB_IS_NULL(value)
Definition: dbtype.h:63
struct tp_domain * next
Definition: object_domain.h:74
char * attribute
const char * name
Definition: class_object.h:385
SM_INDEX_STATUS index_status
Definition: class_object.h:544
#define MSGCAT_RUNTIME_IS_NOT_AUTHORIZED_ON
void describe_signature(const sm_method_signature &signature_p, class_description::type prt_type)
struct db_object * class_mop
Definition: object_domain.h:81
void describe_argument(const sm_method_argument &argument, class_description::type prt_type)
int collation_id
Definition: object_domain.h:92
int sm_get_class_tde_algorithm(MOP classop, TDE_ALGORITHM *tde_algo)
char * classobj_describe_foreign_key_action(SM_FOREIGN_KEY_ACTION action)
Definition: class_object.c:748
const char * comment
Definition: class_object.h:467
void add_bytes(size_t len, const char *bytes)
int au_fetch_class_force(MOP op, SM_CLASS **class_, AU_FETCHMODE fetchmode)
struct sm_method_argument * next
Definition: class_object.h:556
string_buffer & m_buf
const char * name
Definition: class_object.h:532