File object_printer.cpp¶
File List > cubrid > src > object > object_printer.cpp
Go to the documentation of this file
/*
* Copyright 2008 Search Solution Corporation
* Copyright 2016 CUBRID Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
/*
* object_printer.cpp
*/
#include "object_printer.hpp"
#include "authenticate.h"
#include "class_description.hpp"
#include "class_object.h"
#include "db_json.hpp"
#include "db_value_printer.hpp"
#include "dbi.h"
#include "dbtype.h"
#include "misc_string.h"
#include "object_domain.h"
#include "object_primitive.h"
#include "object_print_util.hpp"
#include "parse_tree.h"
#include "schema_manager.h"
#include "set_object.h"
#include "string_buffer.hpp"
#include "trigger_manager.h"
#include "work_space.h"
#include "tde.h"
#include <assert.h>
//--------------------------------------------------------------------------------
void object_printer::describe_comment_for_session_cmd (const char *comment)
{
db_value comment_value;
assert (comment != NULL);
db_make_null (&comment_value);
db_make_string (&comment_value, comment);
m_buf ("COMMENT ");
if (comment != NULL && comment[0] != '\0')
{
db_value_printer printer (m_buf);
printer.describe_comment_value (&comment_value);
}
else
{
m_buf ("''");
}
pr_clear_value (&comment_value);
}
//--------------------------------------------------------------------------------
void object_printer::describe_comment (const char *comment)
{
db_value comment_value;
assert (comment != NULL);
db_make_null (&comment_value);
db_make_string (&comment_value, comment);
m_buf ("COMMENT ");
if (comment != NULL && comment[0] != '\0')
{
db_value_printer printer (m_buf);
printer.describe_value (&comment_value);
}
else
{
m_buf ("''");
}
pr_clear_value (&comment_value);
}
//--------------------------------------------------------------------------------
void object_printer::describe_partition_parts (const sm_partition &parts, class_description::type prt_type)
{
DB_VALUE ele;
int setsize, i;
db_value_printer obj_print (m_buf);
db_make_null (&ele);
m_buf ("PARTITION ");
describe_identifier (parts.pname, prt_type);
switch (parts.partition_type)
{
case PT_PARTITION_HASH:
break;
case PT_PARTITION_RANGE:
m_buf (" VALUES LESS THAN ");
if (!set_get_element (parts.values, 1, &ele))
{
/* 0:MIN, 1: MAX */
if (DB_IS_NULL (&ele))
{
m_buf ("MAXVALUE");
}
else
{
m_buf ("(");
obj_print.describe_value (&ele);
m_buf (")");
}
}
break;
case PT_PARTITION_LIST:
m_buf (" VALUES IN (");
setsize = set_size (parts.values);
for (i = 0; i < setsize; i++)
{
if (i > 0)
{
m_buf (", ");
}
if (set_get_element (parts.values, i, &ele) == NO_ERROR)
{
obj_print.describe_value (&ele);
}
}
m_buf (")");
break;
}
if (parts.comment != NULL && parts.comment[0] != '\0')
{
m_buf (" ");
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
describe_comment_for_session_cmd (parts.comment);
}
else
{
describe_comment (parts.comment);
}
}
pr_clear_value (&ele);
}
/*
* object_print_identifier() - help function to print identifier string.
* if prt_type is OBJ_PRINT_SHOW_CREATE_TABLE,
* we need wrap it with "[" and "]".
* return: advanced buffer pointer
* parser(in) :
* buffer(in) : current buffer pointer
* identifier(in) : identifier string,.such as: table name.
* prt_type(in): the print type: csql schema or show create table
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_identifier (const char *identifier, class_description::type prt_type)
{
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
m_buf ("%s", identifier);
}
else
{
//prt_type == OBJ_PRINT_SHOW_CREATE_TABLE
m_buf ("[%s]", identifier);
}
}
/* CLASS COMPONENT DESCRIPTION FUNCTIONS */
/*
* obj_print_describe_domain() - Describe the domain of an attribute
* return: advanced buffer pointer
* parser(in) :
* buffer(in) : current buffer pointer
* domain(in) : domain structure to describe
* prt_type(in): the print type: csql schema or show create table
* force_print_collation(in): true if collation is printed no matter system
* collation
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_domain (/*const*/tp_domain &domain, class_description::type prt_type,
bool force_print_collation)
{
TP_DOMAIN *temp_domain;
char temp_buffer[27];
int precision = 0, idx, count;
int has_collation;
/* filter first, usually not necessary but this is visible */
sm_filter_domain (&domain, NULL);
for (temp_domain = &domain; temp_domain != NULL; temp_domain = temp_domain->next)
{
has_collation = 0;
switch (TP_DOMAIN_TYPE (temp_domain))
{
case DB_TYPE_INTEGER:
case DB_TYPE_BIGINT:
case DB_TYPE_FLOAT:
case DB_TYPE_DOUBLE:
case DB_TYPE_BLOB:
case DB_TYPE_CLOB:
case DB_TYPE_TIME:
case DB_TYPE_TIMESTAMP:
case DB_TYPE_TIMESTAMPTZ:
case DB_TYPE_TIMESTAMPLTZ:
case DB_TYPE_DATETIME:
case DB_TYPE_DATETIMETZ:
case DB_TYPE_DATETIMELTZ:
case DB_TYPE_DATE:
case DB_TYPE_MONETARY:
case DB_TYPE_SUB:
case DB_TYPE_POINTER:
case DB_TYPE_ERROR:
case DB_TYPE_SHORT:
case DB_TYPE_VOBJ:
case DB_TYPE_OID:
case DB_TYPE_NULL:
case DB_TYPE_VARIABLE:
case DB_TYPE_DB_VALUE:
strcpy (temp_buffer, temp_domain->type->name);
m_buf ("%s", ustr_upper (temp_buffer));
break;
case DB_TYPE_OBJECT:
if (temp_domain->class_mop != NULL)
{
describe_identifier (sm_get_ch_name (temp_domain->class_mop), prt_type);
}
else
{
m_buf ("%s", temp_domain->type->name);
}
break;
case DB_TYPE_VARCHAR:
has_collation = 1;
if (temp_domain->precision == TP_FLOATING_PRECISION_VALUE)
{
m_buf ("STRING");
break;
}
[[fallthrough]];
case DB_TYPE_CHAR:
has_collation = 1;
[[fallthrough]];
case DB_TYPE_BIT:
case DB_TYPE_VARBIT:
strcpy (temp_buffer, temp_domain->type->name);
if (temp_domain->precision == TP_FLOATING_PRECISION_VALUE)
{
precision = DB_MAX_STRING_LENGTH;
}
else
{
precision = temp_domain->precision;
}
m_buf ("%s(%d)", ustr_upper (temp_buffer), precision);
break;
case DB_TYPE_JSON:
strcpy (temp_buffer, temp_domain->type->name);
ustr_upper (temp_buffer);
if (temp_domain->json_validator != NULL)
{
m_buf ("%s(\'%s\')", temp_buffer, db_json_get_schema_raw_from_validator (temp_domain->json_validator));
}
else
{
m_buf (temp_buffer);
}
break;
case DB_TYPE_NUMERIC:
strcpy (temp_buffer, temp_domain->type->name);
m_buf ("%s(%d,%d)", ustr_upper (temp_buffer), temp_domain->precision, temp_domain->scale);
break;
case DB_TYPE_SET:
case DB_TYPE_MULTISET:
case DB_TYPE_SEQUENCE:
strcpy (temp_buffer, temp_domain->type->name);
ustr_upper (temp_buffer);
m_buf ("%s OF ", temp_buffer);
if (temp_domain->setdomain != NULL)
{
if (temp_domain->setdomain->next != NULL && prt_type == class_description::SHOW_CREATE_TABLE)
{
m_buf ("(");
describe_domain (*temp_domain->setdomain, prt_type, force_print_collation);
m_buf (")");
}
else
{
describe_domain (*temp_domain->setdomain, prt_type, force_print_collation);
}
}
break;
case DB_TYPE_ENUMERATION:
has_collation = 1;
strcpy (temp_buffer, temp_domain->type->name);
m_buf ("%s(", ustr_upper (temp_buffer));
count = DOM_GET_ENUM_ELEMS_COUNT (temp_domain);
for (idx = 1; idx <= count; idx++)
{
if (idx > 1)
{
m_buf (", ");
}
m_buf ("'");
m_buf.add_bytes (DB_GET_ENUM_ELEM_STRING_SIZE (&DOM_GET_ENUM_ELEM (temp_domain, idx)),
DB_GET_ENUM_ELEM_STRING (&DOM_GET_ENUM_ELEM (temp_domain, idx)));
m_buf ("'");
}
m_buf (")");
break;
default:
break;
}
if (has_collation && (force_print_collation || temp_domain->collation_id != LANG_SYS_COLLATION))
{
m_buf (" COLLATE %s", lang_get_collation_name (temp_domain->collation_id));
}
if (temp_domain->next != NULL)
{
m_buf (", ");
}
}
}
/*
* obj_print_describe_argument() - Describes a method argument
* return: advanced buffer pointer
* parser(in) :
* buffer(in) : current buffer pointer
* argument_p(in) : method argument to describe
* prt_type(in): the print type: csql schema or show create table
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_argument (const sm_method_argument &argument, class_description::type prt_type)
{
if (argument.domain != NULL)
{
/* method and its arguments do not inherit collation from class, collation printing is not enforced */
describe_domain (*argument.domain, prt_type, false);
}
else if (argument.type)
{
m_buf ("%s", argument.type->name);
}
else
{
m_buf ("invalid type");
}
}
/*
* describe_method() - Describes the definition of a method in a class
* return: advanced buffer pointer
* parser(in) : current buffer pointer
* op(in) : class with method
* method_p(in) : method to describe
* prt_type(in): the print type: csql schema or show create table
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_method (const struct db_object &op, const sm_method &method,
class_description::type prt_type)
{
SM_METHOD_SIGNATURE *signature_p;
/* assume for the moment that there can only be one signature, simplifies the output */
describe_identifier (method.header.name, prt_type);
signature_p = method.signatures;
if (signature_p == NULL)
{
m_buf ("()");
}
else
{
m_buf ("(");
describe_signature (*signature_p, prt_type);
m_buf (") ");
if (signature_p->value != NULL)
{
/* make this look more like the actual definition instead strcpy(line, "returns "); line += strlen(line); */
describe_argument (*signature_p->value, prt_type);
}
if (signature_p->function_name != NULL)
{
m_buf (" FUNCTION ");
describe_identifier (signature_p->function_name, prt_type);
}
}
/* add the inheritance source */
if (method.class_mop != NULL && method.class_mop != &op)
{
m_buf ("(from ");
describe_identifier (sm_get_ch_name (method.class_mop), prt_type);
m_buf (")");
}
}
/*
* obj_print_describe_signature() - Describes a method signature
* return: advanced buffer pointer
* parser(in) :
* buffer(in) : current buffer pointer
* signature_p(in) : signature to describe
* prt_type(in): the print type: csql schema or show create table
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_signature (const sm_method_signature &signature, class_description::type prt_type)
{
SM_METHOD_ARGUMENT *argument_p;
int i;
for (i = 1; i <= signature.num_args; i++)
{
for (argument_p = signature.args; argument_p != NULL && argument_p->index != i; argument_p=argument_p->next)
;
if (argument_p != NULL)
{
describe_argument (*argument_p, prt_type);
}
else
{
m_buf ("??");
}
if (i < signature.num_args)
{
m_buf (", ");
}
}
}
/* CLASS COMPONENT DESCRIPTION FUNCTIONS */
/*
* obj_print_describe_attribute() - Describes the definition of an attribute
* in a class
* return: advanced bufbuffer pointer
* class_p(in) : class being examined
* parser(in) :
* attribute_p(in) : attribute of the class
* is_inherited(in) : is the attribute inherited
* prt_type(in): the print type: csql schema or show create table
* obj_print_describe_attribute(in):
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_attribute (const struct db_object &cls, const sm_attribute &attribute,
bool is_inherited, class_description::type prt_type, bool force_print_collation)
{
char str_buf[NUMERIC_MAX_STRING_SIZE];
db_value_printer printer (m_buf);
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
m_buf ("%-20s ", attribute.header.name);
}
else
{
/* prt_type == OBJ_PRINT_SHOW_CREATE_TABLE */
describe_identifier (attribute.header.name, prt_type);
m_buf (" ");
}
/* could filter here but do in describe_domain */
describe_domain (*attribute.domain, prt_type, force_print_collation);
if (attribute.header.name_space == ID_SHARED_ATTRIBUTE)
{
m_buf (" SHARED ");
if (!DB_IS_NULL (&attribute.default_value.value))
{
printer.describe_value (&attribute.default_value.value);
}
}
else if (attribute.header.name_space == ID_ATTRIBUTE)
{
if (attribute.flags & SM_ATTFLAG_AUTO_INCREMENT)
{
m_buf (" AUTO_INCREMENT ");
assert (is_inherited || attribute.auto_increment != NULL);
if (prt_type == class_description::SHOW_CREATE_TABLE)
{
DB_VALUE min_val, inc_val;
char buff[DB_MAX_NUMERIC_PRECISION * 2 + 4];
int offset;
assert (attribute.auto_increment != NULL);
db_make_null (&min_val);
db_make_null (&inc_val);
if (db_get (attribute.auto_increment, "min_val", &min_val) != NO_ERROR)
{
return;
}
if (db_get (attribute.auto_increment, "increment_val", &inc_val) != NO_ERROR)
{
pr_clear_value (&min_val);
return;
}
offset = snprintf (buff, DB_MAX_NUMERIC_PRECISION + 3, "(%s, ",
numeric_db_value_print (&min_val, str_buf));
snprintf (buff + offset, DB_MAX_NUMERIC_PRECISION + 1, "%s)", numeric_db_value_print (&inc_val, str_buf));
m_buf (buff);
pr_clear_value (&min_val);
pr_clear_value (&inc_val);
}
}
if (!DB_IS_NULL (&attribute.default_value.value)
|| attribute.default_value.default_expr.default_expr_type != DB_DEFAULT_NONE)
{
const char *default_expr_type_str;
m_buf (" DEFAULT ");
if (attribute.default_value.default_expr.default_expr_op == T_TO_CHAR)
{
m_buf ("TO_CHAR(");
}
default_expr_type_str = db_default_expression_string (attribute.default_value.default_expr.default_expr_type);
if (default_expr_type_str != NULL)
{
m_buf ("%s", default_expr_type_str);
}
else
{
assert (attribute.default_value.default_expr.default_expr_op == NULL_DEFAULT_EXPRESSION_OPERATOR);
printer.describe_value (&attribute.default_value.value);
}
if (attribute.default_value.default_expr.default_expr_op == T_TO_CHAR)
{
if (attribute.default_value.default_expr.default_expr_format)
{
m_buf (", \'%s\'", attribute.default_value.default_expr.default_expr_format);
}
m_buf (")");
}
}
if (attribute.on_update_default_expr != DB_DEFAULT_NONE)
{
const char *default_expr_type_str;
m_buf (" ON UPDATE ");
default_expr_type_str = db_default_expression_string (attribute.on_update_default_expr);
m_buf ("%s", default_expr_type_str);
}
}
else if (attribute.header.name_space == ID_CLASS_ATTRIBUTE)
{
if (!DB_IS_NULL (&attribute.default_value.value))
{
m_buf (" VALUE ");
printer.describe_value (&attribute.default_value.value);
}
}
if (attribute.flags & SM_ATTFLAG_NON_NULL)
{
m_buf (" NOT NULL");
}
if (attribute.class_mop != NULL && attribute.class_mop != &cls)
{
m_buf (" /* from ");
describe_identifier (sm_get_ch_name (attribute.class_mop), prt_type);
m_buf (" */");
}
if (attribute.comment != NULL && attribute.comment[0] != '\0')
{
m_buf (" ");
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
describe_comment_for_session_cmd (attribute.comment);
}
else
{
describe_comment (attribute.comment);
}
}
}
/*
* obj_print_describe_constraint() - Describes the definition of an attribute
* in a class
* return: advanced buffer pointer
* parser(in) :
* class_p(in) : class being examined
* constraint_p(in) :
* prt_type(in): the print type: csql schema or show create table
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_constraint (const sm_class &cls, const sm_class_constraint &constraint,
class_description::type prt_type)
{
SM_ATTRIBUTE **attribute_p;
const int *asc_desc;
const int *prefix_length;
int k, n_attrs = 0;
char reserved_col_buf[RESERVED_INDEX_ATTR_NAME_BUF_SIZE] = { 0x00, };
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
switch (constraint.type)
{
case SM_CONSTRAINT_INDEX:
m_buf ("INDEX ");
break;
case SM_CONSTRAINT_UNIQUE:
m_buf ("UNIQUE ");
break;
case SM_CONSTRAINT_REVERSE_INDEX:
m_buf ("REVERSE INDEX ");
break;
case SM_CONSTRAINT_REVERSE_UNIQUE:
m_buf ("REVERSE UNIQUE ");
break;
case SM_CONSTRAINT_PRIMARY_KEY:
m_buf ("PRIMARY KEY ");
break;
case SM_CONSTRAINT_FOREIGN_KEY:
m_buf ("FOREIGN KEY ");
break;
default:
m_buf ("CONSTRAINT ");
break;
}
m_buf ("%s ON %s (", constraint.name, sm_ch_name ((MOBJ) (&cls)));
asc_desc = NULL; /* init */
if (!SM_IS_CONSTRAINT_REVERSE_INDEX_FAMILY (constraint.type))
{
asc_desc = constraint.asc_desc;
}
}
else
{
/* prt_type == OBJ_PRINT_SHOW_CREATE_TABLE */
switch (constraint.type)
{
case SM_CONSTRAINT_INDEX:
case SM_CONSTRAINT_REVERSE_INDEX:
m_buf (" INDEX ");
describe_identifier (constraint.name, prt_type);
break;
case SM_CONSTRAINT_UNIQUE:
case SM_CONSTRAINT_REVERSE_UNIQUE:
m_buf (" CONSTRAINT ");
describe_identifier (constraint.name, prt_type);
m_buf (" UNIQUE KEY ");
break;
case SM_CONSTRAINT_PRIMARY_KEY:
m_buf (" CONSTRAINT ");
describe_identifier (constraint.name, prt_type);
m_buf (" PRIMARY KEY ");
break;
case SM_CONSTRAINT_FOREIGN_KEY:
m_buf (" CONSTRAINT ");
describe_identifier (constraint.name, prt_type);
m_buf (" FOREIGN KEY ");
break;
default:
assert (false);
break;
}
m_buf (" (");
asc_desc = constraint.asc_desc;
}
prefix_length = constraint.attrs_prefix_length;
/* If the index is a function index, then the corresponding expression is printed at the right position in the
* attribute list. Since the expression is not part of the attribute list, when searching through that list we must
* check if the position of the expression is reached and then print it. */
k = 0;
if (constraint.func_index_info)
{
n_attrs = constraint.func_index_info->attr_index_start + 1;
}
else
{
for (attribute_p = constraint.attributes; *attribute_p; attribute_p++)
{
n_attrs++;
}
}
for (attribute_p = constraint.attributes; k < n_attrs; attribute_p++)
{
if (constraint.func_index_info && k == constraint.func_index_info->col_id)
{
if (k > 0)
{
m_buf (", ");
}
m_buf ("%s", constraint.func_index_info->expr_str);
if (constraint.func_index_info->fi_domain->is_desc)
{
m_buf (" DESC");
}
k++;
}
if (k == n_attrs)
{
break;
}
if (IS_DEDUPLICATE_KEY_ATTR_ID ((*attribute_p)->id))
{
assert (k == (n_attrs - 1));
int level = GET_DEDUPLICATE_KEY_ATTR_LEVEL ((*attribute_p)->id);
dk_print_deduplicate_key_info (reserved_col_buf, sizeof (reserved_col_buf), level);
/* Since there is no hidden column in the contents to be described in the REFERENCE clause. */
n_attrs--;
break;
}
if (k > 0)
{
m_buf (", ");
}
describe_identifier ((*attribute_p)->header.name, prt_type);
if (prefix_length)
{
if (*prefix_length != -1)
{
m_buf ("(%d)", *prefix_length);
}
prefix_length++;
}
if (asc_desc)
{
if (*asc_desc == 1)
{
m_buf (" DESC");
}
asc_desc++;
}
k++;
}
m_buf (")");
if (constraint.filter_predicate && constraint.filter_predicate->pred_string)
{
m_buf (" WHERE %s", constraint.filter_predicate->pred_string);
}
// In case of PK (Unique Key also), reserved_col_buf will be empty.
if (reserved_col_buf[0])
{
m_buf (" WITH %s", reserved_col_buf);
}
if (constraint.type == SM_CONSTRAINT_FOREIGN_KEY && constraint.fk_info)
{
MOP ref_clsop;
SM_CLASS *ref_cls;
SM_CLASS_CONSTRAINT *c;
ref_clsop = ws_mop (& (constraint.fk_info->ref_class_oid), NULL);
if (au_fetch_class_force (ref_clsop, &ref_cls, AU_FETCH_READ) != NO_ERROR)
{
return;
}
m_buf (" REFERENCES ");
describe_identifier (sm_ch_name ((MOBJ) ref_cls), prt_type);
if (prt_type == class_description::SHOW_CREATE_TABLE)
{
for (c = ref_cls->constraints; c; c = c->next)
{
if (c->type == SM_CONSTRAINT_PRIMARY_KEY && c->attributes != NULL)
{
m_buf (" (");
for (k = 0; k < n_attrs; k++)
{
if (c->attributes[k] != NULL)
{
describe_identifier (c->attributes[k]->header.name, prt_type);
if (k != (n_attrs - 1))
{
m_buf (", ");
}
}
}
m_buf (")");
break;
}
}
}
m_buf (" ON DELETE %s", classobj_describe_foreign_key_action (constraint.fk_info->delete_action));
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
m_buf (",");
}
m_buf (" ON UPDATE %s", classobj_describe_foreign_key_action (constraint.fk_info->update_action));
}
if (constraint.index_status == SM_INVISIBLE_INDEX)
{
m_buf (" INVISIBLE");
}
if (constraint.comment != NULL && constraint.comment[0] != '\0')
{
m_buf (" ");
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
describe_comment_for_session_cmd (constraint.comment);
}
else
{
describe_comment (constraint.comment);
}
}
if (prt_type == class_description::CSQL_SCHEMA_COMMAND)
{
if (constraint.index_status == SM_ONLINE_INDEX_BUILDING_IN_PROGRESS)
{
m_buf (" IN PROGRESS");
}
}
}
/*
* obj_print_describe_resolution() - Describes a resolution specifier
* return: advanced buffer pointer
* parser(in) :
* resolution_p(in) : resolution to describe
* prt_type(in): the print type: csql schema or show create table
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_resolution (const sm_resolution &resolution, class_description::type prt_type)
{
if (prt_type != class_description::SHOW_CREATE_TABLE)
{
if (resolution.name_space == ID_CLASS)
{
m_buf ("inherit CLASS ");
}
else
{
m_buf ("inherit ");
}
}
describe_identifier (resolution.name, prt_type);
m_buf (" of ");
describe_identifier (sm_get_ch_name (resolution.class_mop), prt_type);
if (resolution.alias != NULL)
{
m_buf (" as ");
describe_identifier (resolution.alias, prt_type);
}
}
/*
* obj_print_describe_method_file () - Describes a method file.
* return: advanced buffer pointer
* parser(in) :
* class_p(in) :
* file_p(in): method file descriptor
*/
//--------------------------------------------------------------------------------
void object_printer::describe_method_file (const struct db_object &obj, const sm_method_file &file)
{
m_buf ("%s", file.name);
if (file.class_mop != NULL && file.class_mop != &obj)
{
m_buf (" (from %s)", sm_get_ch_name (file.class_mop));
}
}
/*
* describe_class_trigger () - Describes the given trigger object to a buffer.
* return: PARSER_VARCHAR *
* parser(in): buffer for description
* trigger(in): trigger object
* Note :
* This description is for the class help and as such it contains
* a condensed versino of the trigger help.
*/
//--------------------------------------------------------------------------------
void object_printer::describe_class_trigger (const tr_trigger &trigger)
{
m_buf ("%s : %s %s ", trigger.name, describe_trigger_condition_time (trigger), tr_event_as_string (trigger.event));
if (trigger.attribute != NULL)
{
m_buf ("OF %s", trigger.attribute);
}
if (trigger.comment != NULL && trigger.comment[0] != '\0')
{
m_buf (" ");
describe_comment_for_session_cmd (trigger.comment);
}
}
/*
* obj_print_trigger_condition_time() -
* return: char *
* trigger(in) :
*/
//--------------------------------------------------------------------------------
const char *object_printer::describe_trigger_condition_time (const tr_trigger &trigger)
{
DB_TRIGGER_TIME time = TR_TIME_NULL;
if (trigger.condition != NULL)
{
time = trigger.condition->time;
}
else if (trigger.action != NULL)
{
time = trigger.action->time;
}
return (tr_time_as_string (time));
}
/*
* obj_print_trigger_action_time() -
* return: char *
* trigger(in) :
*/
//--------------------------------------------------------------------------------
const char *object_printer::describe_trigger_action_time (const tr_trigger &trigger)
{
DB_TRIGGER_TIME time = TR_TIME_NULL;
if (trigger.action != NULL)
{
time = trigger.action->time;
}
return (tr_time_as_string (time));
}
/*
* obj_print_describe_class() - Describes the definition of a class
* return: create table string
* parser(in):
* class_schema(in):
* class_op(in):
*/
//--------------------------------------------------------------------------------
void object_printer::describe_class (struct db_object *class_op)
{
m_buf.clear ();
class_description class_descr;
TDE_ALGORITHM tde_algo;
const char *tde_algo_str;
if (class_descr.init (class_op, class_description::SHOW_CREATE_TABLE, m_buf) != NO_ERROR)
{
#if 0 //what do we do in case of error???
int error = er_errid();
assert (error != NO_ERROR);
if (error == ER_AU_SELECT_FAILURE)
{
PT_ERRORmf2 (parser, table_name, MSGCAT_SET_PARSER_RUNTIME, MSGCAT_RUNTIME_IS_NOT_AUTHORIZED_ON, "select",
db_get_class_name (class_op));
}
else
{
PT_ERRORc (parser, table_name, er_msg());
}
#endif
return;
}
m_buf.clear ();
char **line_ptr;
/* class name */
m_buf ("CREATE TABLE %s", class_descr.name);
/* under or as subclass of */
if (class_descr.supers != NULL)
{
m_buf (" UNDER ");
for (line_ptr = class_descr.supers; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.supers)
{
m_buf (", ");
}
m_buf ("%s", (*line_ptr));
}
}
/* class attributes */
if (class_descr.class_attributes != NULL)
{
m_buf (" CLASS ATTRIBUTE (");
for (line_ptr = class_descr.class_attributes; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.class_attributes)
{
m_buf (", ");
}
m_buf ("%s", *line_ptr);
}
m_buf (")");
}
/* attributes and constraints */
if (class_descr.attributes != NULL || class_descr.constraints != NULL)
{
m_buf (" (");
if (class_descr.attributes != NULL)
{
for (line_ptr = class_descr.attributes; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.attributes)
{
m_buf (", ");
}
m_buf ("%s", *line_ptr);
}
}
if (class_descr.constraints != NULL)
{
for (line_ptr = class_descr.constraints; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.constraints || class_descr.attributes != NULL)
{
m_buf (", ");
}
m_buf ("%s", *line_ptr);
}
}
m_buf += ')';
}
/* reuse_oid flag */
if (sm_is_reuse_oid_class (class_op))
{
m_buf (" REUSE_OID");
}
else
{
m_buf (" DONT_REUSE_OID");
}
/* collation */
if (class_descr.collation != NULL)
{
m_buf (", COLLATE %s", class_descr.collation);
}
/* tde_algorithm */
if (sm_get_class_tde_algorithm (class_op, &tde_algo) == NO_ERROR)
{
if (tde_algo != TDE_ALGORITHM_NONE)
{
tde_algo_str = tde_get_algorithm_name (tde_algo);
assert (tde_algo_str != NULL);
m_buf (" ENCRYPT=%s", tde_algo_str);
}
}
/* methods and class_methods */
if (class_descr.methods != NULL || class_descr.class_methods != NULL)
{
m_buf (" METHOD ");
if (class_descr.methods != NULL)
{
for (line_ptr = class_descr.methods; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.methods)
{
m_buf (", ");
}
m_buf ("%s", *line_ptr);
}
}
if (class_descr.class_methods != NULL)
{
for (line_ptr = class_descr.class_methods; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.class_methods || class_descr.methods != NULL)
{
m_buf (", ");
}
m_buf (" CLASS %s", *line_ptr);
}
}
}
/* method files */
if (class_descr.method_files != NULL)
{
m_buf (" FILE ");
for (line_ptr = class_descr.method_files; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.method_files)
{
m_buf (", ");
}
m_buf ("'%s'", *line_ptr);
}
}
/* inherit */
if (class_descr.resolutions != NULL)
{
m_buf (" INHERIT ");
for (line_ptr = class_descr.resolutions; *line_ptr != NULL; line_ptr++)
{
if (line_ptr != class_descr.resolutions)
{
m_buf (", ");
}
m_buf ("%s", *line_ptr);
}
}
/* partition */
if (!class_descr.partition.empty ())
{
m_buf (" %s", class_descr.partition[0]);
size_t len = class_descr.partition.size ();
if (len > 1)
{
m_buf (" (%s", class_descr.partition[1]);
for (size_t i=2; i<len; ++i)
{
m_buf (", %s", class_descr.partition[i]);
}
m_buf (")");
}
}
/* comment */
if (class_descr.comment != NULL && class_descr.comment[0] != '\0')
{
DB_VALUE comment_value;
db_make_null (&comment_value);
db_make_string (&comment_value, class_descr.comment);
m_buf (" COMMENT=");
db_value_printer printer (m_buf);
printer.describe_value (&comment_value);
pr_clear_value (&comment_value);
}
}
/*
* obj_print_describe_partition_info() -
* return: char *
* parser(in) :
* partinfo(in) :
*
*/
//--------------------------------------------------------------------------------
void object_printer::describe_partition_info (const sm_partition &partinfo)
{
DB_VALUE ele;
char col_name[DB_MAX_IDENTIFIER_LENGTH + 1];
m_buf ("PARTITION BY ");
switch (partinfo.partition_type)
{
case PT_PARTITION_HASH:
m_buf ("HASH (");
break;
case PT_PARTITION_RANGE:
m_buf ("RANGE (");
break;
case PT_PARTITION_LIST:
m_buf ("LIST (");
break;
}
char *tmp = (char *) partinfo.expr;
assert (tmp != NULL);
char *ptr = tmp ? strstr (tmp, "SELECT ") : NULL;
if (ptr)
{
char *ptr2 = strstr (ptr + 7, " FROM ");
if (ptr2)
{
strncpy (col_name, ptr + 7, CAST_STRLEN (ptr2 - (ptr + 7)));
col_name[CAST_STRLEN (ptr2 - (ptr + 7))] = 0;
m_buf ("%s) ", col_name);
}
}
if (partinfo.partition_type == PT_PARTITION_HASH)
{
if (set_get_element (partinfo.values, 1, &ele) == NO_ERROR)
{
m_buf ("PARTITIONS %d", db_get_int (&ele));
}
}
}