Skip to content

Commit

Permalink
[CBRD-25054] Numeric type column inserted by using rownum does not sh…
Browse files Browse the repository at this point in the history
…ow error even it's outranged. (#4766)

http://jira.cubrid.org/browse/CBRD-25054
  • Loading branch information
beyondykk9 authored Nov 24, 2023
1 parent e052275 commit d9f9ae8
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
71 changes: 71 additions & 0 deletions src/object/object_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -11483,6 +11483,77 @@ tp_domain_references_objects (const TP_DOMAIN * dom)
}
}

/*
* tp_value_auto_cast_with_precsion_check
* Cast a value into one of another domain like tp_value_auto_cast.
* It checks the precision in case of casting discrete number type to numeric type
* return: TP_DOMAIN_STATUS
* src(in): src DB_VALUE
* dest(out): dest DB_VALUE
* desired_domain(in): destion domain
*/
TP_DOMAIN_STATUS
tp_value_auto_cast_with_precision_check (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain)
{
TP_DOMAIN_STATUS dom_status = DOMAIN_COMPATIBLE;

static INT64 max_value[19]; /* max precision of a big integer is 19 */
static bool init_bigint_value = false;

if (!init_bigint_value)
{
int i;

max_value[0] = 1;
for (i = 1; i < 19; i++)
{
max_value[i] = max_value[i - 1] * 10;
}

init_bigint_value = true;
}

if (TP_IS_DISCRETE_NUMBER_TYPE (src->domain.general_info.type))
{
/* if the numeric's precision is 19 or more, then it can get the bigint enough */
if (desired_domain->type->id == DB_TYPE_NUMERIC && desired_domain->precision < 19)
{
INT64 bigint;

assert (desired_domain->precision >= 0);

switch (src->domain.general_info.type)
{
case DB_TYPE_BIGINT:
bigint = db_get_bigint (src);
break;
case DB_TYPE_INTEGER:
bigint = db_get_int (src);
break;
case DB_TYPE_SHORT:
bigint = db_get_short (src);
default:
/* never here */
break;
}

if ((bigint > 0 && (bigint >= max_value[desired_domain->precision]))
|| ((bigint < 0) && ((-bigint) >= max_value[desired_domain->precision])))
{
/* can not coerce for overflow */
dom_status = DOMAIN_OVERFLOW;
}
}
}

if (dom_status != DOMAIN_OVERFLOW)
{
dom_status = tp_value_auto_cast (src, dest, desired_domain);
}

return dom_status;
}

/*
* tp_value_auto_cast - Cast a value into one of another domain, returning an
* error only
Expand Down
2 changes: 2 additions & 0 deletions src/object/object_domain.h
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,8 @@ extern "C"
#endif
extern int tp_domain_attach (TP_DOMAIN ** dlist, TP_DOMAIN * domain);

extern TP_DOMAIN_STATUS tp_value_auto_cast_with_precision_check (const DB_VALUE * src, DB_VALUE * dest,
const TP_DOMAIN * desired_domain);
extern TP_DOMAIN_STATUS tp_value_auto_cast (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain);
extern int tp_value_str_auto_cast_to_number (DB_VALUE * src, DB_VALUE * dest, DB_TYPE * val_type);
extern TP_DOMAIN *tp_infer_common_domain (TP_DOMAIN * arg1, TP_DOMAIN * arg2);
Expand Down
3 changes: 2 additions & 1 deletion src/storage/heap_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -11343,7 +11343,8 @@ heap_attrinfo_set (const OID * inst_oid, ATTR_ID attrid, DB_VALUE * attr_val, HE
else
{
/* the domains don't match, must attempt coercion */
dom_status = tp_value_auto_cast (attr_val, &value->dbvalue, value->last_attrepr->domain);
dom_status = tp_value_auto_cast_with_precision_check (attr_val, &value->dbvalue, value->last_attrepr->domain);

if (dom_status != DOMAIN_COMPATIBLE)
{
ret = tp_domain_status_er_set (dom_status, ARG_FILE_LINE, attr_val, value->last_attrepr->domain);
Expand Down

0 comments on commit d9f9ae8

Please sign in to comment.