Skip to content

Commit

Permalink
Fix CORE-1162
Browse files Browse the repository at this point in the history
  • Loading branch information
robocop committed Mar 28, 2007
1 parent 72154e3 commit 01864d3
Show file tree
Hide file tree
Showing 11 changed files with 300 additions and 186 deletions.
4 changes: 4 additions & 0 deletions lang_helpers/gds_codes.ftn
Expand Up @@ -1324,6 +1324,10 @@ C --
PARAMETER (GDS__dyn_zero_len_id = 336068820)
INTEGER*4 GDS__dyn_wrong_gtt_scope
PARAMETER (GDS__dyn_wrong_gtt_scope = 336068840)
INTEGER*4 GDS__dyn_scale_too_big
PARAMETER (GDS__dyn_scale_too_big = 336068852)
INTEGER*4 GDS__dyn_precision_too_small
PARAMETER (GDS__dyn_precision_too_small = 336068853)
INTEGER*4 GDS__gbak_unknown_switch
PARAMETER (GDS__gbak_unknown_switch = 336330753)
INTEGER*4 GDS__gbak_page_size_missing
Expand Down
2 changes: 2 additions & 0 deletions lang_helpers/gds_codes.pas
Expand Up @@ -669,6 +669,8 @@
gds_dyn_dtype_conv_invalid = 336068818;
gds_dyn_zero_len_id = 336068820;
gds_dyn_wrong_gtt_scope = 336068840;
gds_dyn_scale_too_big = 336068852;
gds_dyn_precision_too_small = 336068853;
gds_gbak_unknown_switch = 336330753;
gds_gbak_page_size_missing = 336330754;
gds_gbak_page_size_toobig = 336330755;
Expand Down
2 changes: 2 additions & 0 deletions src/include/gen/codetext.h
Expand Up @@ -658,6 +658,8 @@ static const struct {
{"dyn_dtype_conv_invalid", 336068818},
{"dyn_zero_len_id", 336068820},
{"dyn_wrong_gtt_scope", 336068840},
{"dyn_scale_too_big", 336068852},
{"dyn_precision_too_small", 336068853},
{"gbak_unknown_switch", 336330753},
{"gbak_page_size_missing", 336330754},
{"gbak_page_size_toobig", 336330755},
Expand Down
8 changes: 6 additions & 2 deletions src/include/gen/iberror.h
Expand Up @@ -691,6 +691,8 @@ const ISC_LONG isc_dyn_invalid_dtype_conversion = 336068817L;
const ISC_LONG isc_dyn_dtype_conv_invalid = 336068818L;
const ISC_LONG isc_dyn_zero_len_id = 336068820L;
const ISC_LONG isc_dyn_wrong_gtt_scope = 336068840L;
const ISC_LONG isc_dyn_scale_too_big = 336068852L;
const ISC_LONG isc_dyn_precision_too_small = 336068853L;
const ISC_LONG isc_gbak_unknown_switch = 336330753L;
const ISC_LONG isc_gbak_page_size_missing = 336330754L;
const ISC_LONG isc_gbak_page_size_toobig = 336330755L;
Expand Down Expand Up @@ -864,7 +866,7 @@ const ISC_LONG isc_gstat_unexpected_eof = 336920580L;
const ISC_LONG isc_gstat_open_err = 336920605L;
const ISC_LONG isc_gstat_read_err = 336920606L;
const ISC_LONG isc_gstat_sysmemex = 336920607L;
const ISC_LONG isc_err_max = 809;
const ISC_LONG isc_err_max = 811;

#else /* c definitions */

Expand Down Expand Up @@ -1525,6 +1527,8 @@ const ISC_LONG isc_err_max = 809;
#define isc_dyn_dtype_conv_invalid 336068818L
#define isc_dyn_zero_len_id 336068820L
#define isc_dyn_wrong_gtt_scope 336068840L
#define isc_dyn_scale_too_big 336068852L
#define isc_dyn_precision_too_small 336068853L
#define isc_gbak_unknown_switch 336330753L
#define isc_gbak_page_size_missing 336330754L
#define isc_gbak_page_size_toobig 336330755L
Expand Down Expand Up @@ -1698,7 +1702,7 @@ const ISC_LONG isc_err_max = 809;
#define isc_gstat_open_err 336920605L
#define isc_gstat_read_err 336920606L
#define isc_gstat_sysmemex 336920607L
#define isc_err_max 809
#define isc_err_max 811

#endif

Expand Down
348 changes: 175 additions & 173 deletions src/include/gen/msgs.h

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/include/gen/rdb_codes.h
Expand Up @@ -828,4 +828,6 @@ static SLONG user_codes[] = {
0,
0,
0,
0,
0,
};
2 changes: 2 additions & 0 deletions src/include/gen/sql_code.h
Expand Up @@ -657,6 +657,8 @@ static const struct {
{336068818, -829}, /* 210 dyn_dtype_conv_invalid */
{336068820, -901}, /* 212 dyn_zero_len_id */
{336068840, -901}, /* 232 dyn_wrong_gtt_scope */
{336068852, -829}, /* 244 dyn_scale_too_big */
{336068853, -829}, /* 245 dyn_precision_too_small */
{336330753, -901}, /* 1 gbak_unknown_switch */
{336330754, -901}, /* 2 gbak_page_size_missing */
{336330755, -901}, /* 3 gbak_page_size_toobig */
Expand Down
80 changes: 70 additions & 10 deletions src/jrd/dyn_mod.epp
Expand Up @@ -103,6 +103,7 @@ static bool field_exists(thread_db*, Database*, Global*,
static bool domain_exists(thread_db*, Database*, Global*, const Firebird::MetaName&);
static void get_domain_type(thread_db*, Database*, Global*, dyn_fld&);
static ULONG check_update_fld_type(const dyn_fld&, const dyn_fld&);
static ULONG check_update_numeric_type(const dyn_fld&, const dyn_fld&);
static void modify_err_punt(thread_db*, ULONG, const dyn_fld&, const dyn_fld&);


Expand Down Expand Up @@ -3364,7 +3365,7 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
// if (new_fld.dyn_dsc.dsc_length < maxflen)
if (new_len < maxflen)
return isc_dyn_char_fld_too_small;
/* New size specified for column %s must be greater than %d characters. */
// msg 208: New size specified for column %s must be at least %d characters.
}
break;

Expand Down Expand Up @@ -3420,7 +3421,7 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
// if (new_fld.dyn_dsc.dsc_length < maxflen)
if (DSC_string_length(&new_fld.dyn_dsc) < maxflen)
return isc_dyn_char_fld_too_small;
/* New size specified for column %s must be greater than %d characters. */
// msg 208: New size specified for column %s must be at least %d characters.
}

break;
Expand Down Expand Up @@ -3458,7 +3459,9 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
case blr_short:
switch (orig_fld.dyn_dtype) {
case blr_short:
return check_update_numeric_type(orig_fld, new_fld);
break;

default:
return isc_dyn_invalid_dtype_conversion;
/* Cannot change datatype for column %s. Conversion from base type %s to base type %s is not supported. */
Expand All @@ -3469,7 +3472,9 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
switch (orig_fld.dyn_dtype) {
case blr_long:
case blr_short:
return check_update_numeric_type(orig_fld, new_fld);
break;

default:
return isc_dyn_invalid_dtype_conversion;
/* Cannot change datatype for column %s. Conversion from base type %s to base type %s is not supported. */
Expand All @@ -3493,6 +3498,7 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
case blr_int64:
case blr_long:
case blr_short:
return check_update_numeric_type(orig_fld, new_fld);
break;

default:
Expand Down Expand Up @@ -3529,7 +3535,7 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
// if (new_fld.dyn_dsc.dsc_length < maxflen)
if (DSC_string_length(&new_fld.dyn_dsc) < maxflen)
return isc_dyn_char_fld_too_small;
/* New size specified for column %s must be greater than %d characters. */
// msg 208: New size specified for column %s must be at least %d characters.
}
break;

Expand All @@ -3547,6 +3553,38 @@ static ULONG check_update_fld_type(const dyn_fld& orig_fld,
}


static ULONG check_update_numeric_type(const dyn_fld& orig_fld,
const dyn_fld& new_fld)
{
/**************************************
*
* c h e c k _ u p d a t e _ n u m e r i c _ t y p e
*
**************************************
*
* Functional description
* Compare the original field type with the new field type to
* determine if the original type can be changed to the new type.
* The types should be integral, since it tests only numeric/decimal subtypes
* to ensure the scale is not being widened at the expense of the precision,
* because the old stored values should fit in the new definition.
*
* This function returns an error code if the conversion can not be
* made. If the conversion can be made, FB_SUCCESS is returned.
**************************************/

// Since dsc_scale is negative, the sum of precision and scale produces
// the width of the integral part.
if (orig_fld.dyn_dsc.dsc_sub_type && new_fld.dyn_dsc.dsc_sub_type &&
orig_fld.dyn_precision + orig_fld.dyn_dsc.dsc_scale >
new_fld.dyn_precision + new_fld.dyn_dsc.dsc_scale)
{
return isc_dyn_scale_too_big;
}
return FB_SUCCESS;
}


static void modify_err_punt(thread_db* tdbb,
ULONG errorcode,
const dyn_fld& orig_fld_def,
Expand All @@ -3566,23 +3604,44 @@ static void modify_err_punt(thread_db* tdbb,
* DYN_modify_sql_field
**************************************/

switch (errorcode) {
switch (errorcode)
{
case isc_dyn_dtype_invalid:
DYN_error_punt(false, 207, orig_fld_def.dyn_fld_name.c_str());
DYN_error_punt(false, errorcode, orig_fld_def.dyn_fld_name.c_str());
/* Cannot change datatype for column %s.The operation cannot be performed on DATE, BLOB, or ARRAY columns. */
break;

case isc_dyn_dtype_conv_invalid:
DYN_error_punt(false, 210, orig_fld_def.dyn_fld_name.c_str());
DYN_error_punt(false, errorcode, orig_fld_def.dyn_fld_name.c_str());
/* Cannot convert column %s from character to non-character data. */
break;

case isc_dyn_char_fld_too_small:
DYN_error_punt(false,
208,
errorcode,
SafeArg() << orig_fld_def.dyn_fld_name.c_str() <<
DSC_string_length(&orig_fld_def.dyn_dsc));
/* msg 208: New size specified for column %s must be greater than %d characters. */
// msg 208: New size specified for column %s must be at least %d characters.
break;

case isc_dyn_scale_too_big:
{
int code = errorcode;
int diff = new_fld_def.dyn_precision -
(orig_fld_def.dyn_precision + orig_fld_def.dyn_dsc.dsc_scale);
if (diff < 0)
{
// If new scale becomes negative externally, the message is useless for the user.
// (The scale is always zero or negative for us but externally is non-negative.)
// Let's ask the user to widen the precision, then. Example: numeric(4, 0) -> numeric(1, 1).
code = isc_dyn_precision_too_small;
diff = new_fld_def.dyn_precision - new_fld_def.dyn_dsc.dsc_scale - diff;
}
DYN_error_punt(false, code,
SafeArg() << orig_fld_def.dyn_fld_name.c_str() << diff);
// scale_too_big: New scale specified for column @1 must be at most @2.
// precision_too_small: New precision specified for column @1 must be at least @2.
}
break;

case isc_dyn_invalid_dtype_conversion:
Expand All @@ -3594,11 +3653,12 @@ static void modify_err_punt(thread_db* tdbb,
DSC_get_dtype_name(&new_fld_def.dyn_dsc, new_type,
sizeof(new_type));

DYN_error_punt(false, 209, SafeArg() << orig_fld_def.dyn_fld_name.c_str() <<
DYN_error_punt(false, errorcode,
SafeArg() << orig_fld_def.dyn_fld_name.c_str() <<
orig_type << new_type);
// Cannot change datatype for @1. Conversion from base type @2 to @3 is not supported.
break;
}
break;

default:
DYN_error_punt(true, 95);
Expand Down
2 changes: 1 addition & 1 deletion src/msgs/facilities2.sql
Expand Up @@ -11,7 +11,7 @@ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUM
--('1996-11-07 13:39:40', 'GRST', 6, 1)
--
('2005-11-05 13:09:00', 'DSQL', 7, 32)
('2006-10-01 19:10:51', 'DYN', 8, 244)
('2007-03-22 06:41:07', 'DYN', 8, 246)
--
--('1996-11-07 13:39:40', 'FRED', 9, 1)
--
Expand Down

0 comments on commit 01864d3

Please sign in to comment.