8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 02:03:04 +01:00

Fixed a number of issues for Dialect 1 and Dialect 3 (string arithmetics) + some cleanup.

The issues are:
1) '1.5' / '0.5' doesn't work in Dialect 1
2) avg ('1.5') doesn't work in Dialect 1
3) 5 * '1.5' produces INT result instead of DOUBLE PRECISION in Dialect 1
4) sum ('1.5') produces NUMERIC(15, 2) result instead of DOUBLE PRECISION in Dialect 1
5) - '1.5' doesn't work in Dialect 1
6) '1.5' * '0.5' and '1.5' / '0.5' are not forbidden in Dialect 3
This commit is contained in:
dimitr 2005-08-06 05:29:31 +00:00
parent b57b7b1e34
commit 6494351243
4 changed files with 88 additions and 57 deletions

View File

@ -350,18 +350,25 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
case nod_agg_average:
MAKE_desc(request, desc, node->nod_arg[0], null_replacement);
desc->dsc_flags = DSC_nullable;
dtype = desc->dsc_dtype;
if (!DTYPE_CAN_AVERAGE(dtype))
if (!DTYPE_IS_NUMERIC(desc->dsc_dtype) &&
!DTYPE_IS_TEXT(desc->dsc_dtype))
{
ERRD_post(isc_expression_eval_err, 0);
}
else if (DTYPE_IS_TEXT(desc->dsc_dtype)) {
desc->dsc_dtype = dtype_double;
desc->dsc_length = sizeof(double);
}
return;
case nod_agg_average2:
MAKE_desc(request, desc, node->nod_arg[0], null_replacement);
desc->dsc_flags = DSC_nullable;
dtype = desc->dsc_dtype;
if (!DTYPE_CAN_AVERAGE(dtype))
if (!DTYPE_IS_NUMERIC(dtype)) {
ERRD_post(isc_expression_eval_err, 0);
if (DTYPE_IS_EXACT(dtype)) {
}
else if (DTYPE_IS_EXACT(dtype)) {
desc->dsc_dtype = dtype_int64;
desc->dsc_length = sizeof(SINT64);
node->nod_flags |= NOD_COMP_DIALECT;
@ -374,7 +381,12 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
case nod_agg_total:
MAKE_desc(request, desc, node->nod_arg[0], null_replacement);
if (desc->dsc_dtype == dtype_short) {
if (!DTYPE_IS_NUMERIC(desc->dsc_dtype) &&
!DTYPE_IS_TEXT(desc->dsc_dtype))
{
ERRD_post(isc_expression_eval_err, 0);
}
else if (desc->dsc_dtype == dtype_short) {
desc->dsc_dtype = dtype_long;
desc->dsc_length = sizeof(SLONG);
}
@ -382,13 +394,20 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
desc->dsc_dtype = dtype_double;
desc->dsc_length = sizeof(double);
}
else if (DTYPE_IS_TEXT(desc->dsc_dtype)) {
desc->dsc_dtype = dtype_double;
desc->dsc_length = sizeof(double);
}
desc->dsc_flags = DSC_nullable;
return;
case nod_agg_total2:
MAKE_desc(request, desc, node->nod_arg[0], null_replacement);
dtype = desc->dsc_dtype;
if (DTYPE_IS_EXACT(dtype)) {
if (!DTYPE_IS_NUMERIC(dtype)) {
ERRD_post(isc_expression_eval_err, 0);
}
else if (DTYPE_IS_EXACT(dtype)) {
desc->dsc_dtype = dtype_int64;
desc->dsc_length = sizeof(SINT64);
node->nod_flags |= NOD_COMP_DIALECT;
@ -552,11 +571,11 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
}
dtype1 = desc1.dsc_dtype;
dtype2 = desc2.dsc_dtype;
if (dtype_int64 == dtype1)
if (DTYPE_IS_EXACT(dtype1) || DTYPE_IS_TEXT(dtype1))
dtype1 = dtype_double;
if (dtype_int64 == dtype2)
dtype2 = desc2.dsc_dtype;
if (DTYPE_IS_EXACT(dtype2) || DTYPE_IS_TEXT(dtype2))
dtype2 = dtype_double;
dtype = MAX(dtype1, dtype2);
@ -567,6 +586,7 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
}
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
switch (dtype) {
case dtype_sql_time:
case dtype_sql_date:
@ -704,10 +724,9 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
isc_arg_gds, isc_dsql_no_blob_array, 0);
}
/* In Dialect 2 or 3, strings can never partipate in addition / sub
(Use a specific cast instead) */
if (DTYPE_IS_TEXT(desc1.dsc_dtype) ||
DTYPE_IS_TEXT(desc2.dsc_dtype))
// In Dialect 2 or 3, strings can never partipate in addition / sub
// (use a specific cast instead)
if (DTYPE_IS_TEXT(desc1.dsc_dtype) || DTYPE_IS_TEXT(desc2.dsc_dtype))
{
ERRD_post(isc_expression_eval_err, 0);
}
@ -717,7 +736,10 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
the operation, as <timestamp>-<timestamp> uses
<timestamp> arithmetic, but returns a <double> */
if (DTYPE_IS_EXACT(desc1.dsc_dtype)
&& DTYPE_IS_EXACT(desc2.dsc_dtype)) dtype = dtype_int64;
&& DTYPE_IS_EXACT(desc2.dsc_dtype))
{
dtype = dtype_int64;
}
else if (DTYPE_IS_NUMERIC(desc1.dsc_dtype)
&& DTYPE_IS_NUMERIC(desc2.dsc_dtype))
{
@ -741,6 +763,7 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
}
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
switch (dtype) {
case dtype_sql_time:
case dtype_sql_date:
@ -869,13 +892,8 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
}
dtype = DSC_multiply_blr4_result[desc1.dsc_dtype][desc2.dsc_dtype];
if (dtype_unknown == dtype) {
ERRD_post(isc_sqlerr, isc_arg_number, (SLONG) - 607,
isc_arg_gds, isc_dsql_no_blob_array, 0);
}
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
switch (dtype) {
case dtype_double:
desc->dsc_dtype = dtype_double;
@ -892,7 +910,8 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
break;
default:
ERRD_post(isc_expression_eval_err, 0);
ERRD_post(isc_sqlerr, isc_arg_number, (SLONG) - 607,
isc_arg_gds, isc_dsql_no_blob_array, 0);
}
return;
@ -908,9 +927,16 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
return;
}
dtype = DSC_multiply_result[desc1.dsc_dtype][desc2.dsc_dtype];
// In Dialect 2 or 3, strings can never partipate in multiplication
// (use a specific cast instead)
if (DTYPE_IS_TEXT(desc1.dsc_dtype) || DTYPE_IS_TEXT(desc2.dsc_dtype))
{
ERRD_post(isc_expression_eval_err, 0);
}
dtype = DSC_multiply_result[desc1.dsc_dtype][desc2.dsc_dtype];
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
switch (dtype) {
case dtype_double:
desc->dsc_dtype = dtype_double;
@ -955,19 +981,20 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
}
dtype1 = desc1.dsc_dtype;
if (dtype_int64 == dtype1)
if (DTYPE_IS_EXACT(dtype1) || DTYPE_IS_TEXT(dtype1))
dtype1 = dtype_double;
dtype2 = desc2.dsc_dtype;
if (dtype_int64 == dtype2)
if (DTYPE_IS_EXACT(dtype2) || DTYPE_IS_TEXT(dtype2))
dtype2 = dtype_double;
dtype = MAX(dtype1, dtype2);
if (!DTYPE_CAN_DIVIDE(dtype)) {
if (!DTYPE_IS_NUMERIC(dtype)) {
ERRD_post(isc_sqlerr, isc_arg_number, (SLONG) - 607,
isc_arg_gds, isc_dsql_no_blob_array, 0);
}
desc->dsc_dtype = dtype_double;
desc->dsc_length = sizeof(double);
desc->dsc_scale = 0;
@ -986,10 +1013,17 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
return;
}
// In Dialect 2 or 3, strings can never partipate in division
// (use a specific cast instead)
if (DTYPE_IS_TEXT(desc1.dsc_dtype) || DTYPE_IS_TEXT(desc2.dsc_dtype))
{
ERRD_post(isc_expression_eval_err, 0);
}
dtype = DSC_multiply_result[desc1.dsc_dtype][desc2.dsc_dtype];
desc->dsc_dtype = static_cast<UCHAR>(dtype);
desc->dsc_flags = (desc1.dsc_flags | desc2.dsc_flags) & DSC_nullable;
switch (dtype) {
case dtype_int64:
desc->dsc_length = sizeof(SINT64);
@ -1020,10 +1054,25 @@ void MAKE_desc(dsql_req* request, dsc* desc, dsql_nod* node, dsql_nod* null_repl
return;
}
if (!DTYPE_CAN_NEGATE(desc->dsc_dtype)) {
// In Dialect 2 or 3, a string can never partipate in negation
// (use a specific cast instead)
if (DTYPE_IS_TEXT(desc->dsc_dtype)) {
if (request->req_client_dialect >= SQL_DIALECT_V6_TRANSITION) {
ERRD_post(isc_expression_eval_err, 0);
}
desc->dsc_dtype = dtype_double;
desc->dsc_length = sizeof(double);
}
// Forbid blobs and arrays
else if (DTYPE_IS_BLOB(desc->dsc_dtype))
{
ERRD_post(isc_sqlerr, isc_arg_number, (SLONG) - 607,
isc_arg_gds, isc_dsql_no_blob_array, 0);
}
// Forbid other not numeric datatypes
else if (!DTYPE_IS_NUMERIC(desc->dsc_dtype)) {
ERRD_post(isc_expression_eval_err, 0);
}
return;
case nod_alias:

View File

@ -944,14 +944,14 @@ void CMP_get_desc(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node, DSC * de
CMP_get_desc(tdbb, csb, node->nod_arg[1], &desc2);
// for compatibility with older versions of the product, we accept
// text types for division in blr_version4 (dialect <= 1) only
if (!(DTYPE_CAN_DIVIDE(desc1.dsc_dtype) ||
if (!(DTYPE_IS_NUMERIC(desc1.dsc_dtype) ||
DTYPE_IS_TEXT(desc1.dsc_dtype)))
{
if (desc1.dsc_dtype != dtype_unknown) {
break; // error, dtype not supported by arithmetic
}
}
if (!(DTYPE_CAN_DIVIDE(desc2.dsc_dtype) ||
if (!(DTYPE_IS_NUMERIC(desc2.dsc_dtype) ||
DTYPE_IS_TEXT(desc2.dsc_dtype)))
{
if (desc2.dsc_dtype != dtype_unknown) {
@ -974,7 +974,9 @@ void CMP_get_desc(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node, DSC * de
if (node->nod_type == nod_average) {
CMP_get_desc(tdbb, csb, node->nod_arg[e_stat_value], desc);
}
if (!DTYPE_CAN_AVERAGE(desc->dsc_dtype)) {
if (!(DTYPE_IS_NUMERIC(desc->dsc_dtype) ||
DTYPE_IS_TEXT(desc->dsc_dtype)))
{
if (desc->dsc_dtype != dtype_unknown) {
break;
}
@ -1015,7 +1017,7 @@ void CMP_get_desc(thread_db* tdbb, CompilerScratch* csb, jrd_nod* node, DSC * de
return;
default:
if (!DTYPE_CAN_AVERAGE(desc->dsc_dtype)) {
if (!DTYPE_IS_NUMERIC(desc->dsc_dtype)) {
break;
}
desc->dsc_dtype = DEFAULT_DOUBLE;

View File

@ -607,21 +607,21 @@ const BYTE DSC_multiply_blr4_result[DTYPE_TYPE_MAX][DTYPE_TYPE_MAX] = {
/* dtype_text */
{dtype_unknown, dtype_double, dtype_double, dtype_double,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT,
dtype_long, dtype_long, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_double, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_d_float, DTYPE_CANNOT, DTYPE_CANNOT,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, dtype_double},
/* dtype_cstring */
{dtype_unknown, dtype_double, dtype_double, dtype_double,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT,
dtype_long, dtype_long, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_double, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_d_float, DTYPE_CANNOT, DTYPE_CANNOT,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, dtype_double},
/* dtype_varying */
{dtype_unknown, dtype_double, dtype_double, dtype_double,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT,
dtype_long, dtype_long, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_double, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_d_float, DTYPE_CANNOT, DTYPE_CANNOT,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, dtype_double},
@ -654,14 +654,14 @@ const BYTE DSC_multiply_blr4_result[DTYPE_TYPE_MAX][DTYPE_TYPE_MAX] = {
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT},
/* dtype_short */
{dtype_unknown, dtype_long, dtype_long, dtype_long,
{dtype_unknown, dtype_double, dtype_double, dtype_double,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT,
dtype_long, dtype_long, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_d_float, DTYPE_CANNOT, DTYPE_CANNOT,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, dtype_double},
/* dtype_long */
{dtype_unknown, dtype_long, dtype_long, dtype_long,
{dtype_unknown, dtype_double, dtype_double, dtype_double,
DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT, DTYPE_CANNOT,
dtype_long, dtype_long, DTYPE_CANNOT, dtype_double,
dtype_double, dtype_d_float, DTYPE_CANNOT, DTYPE_CANNOT,

View File

@ -189,24 +189,4 @@ inline SCHAR NUMERIC_SCALE(const dsc desc) {
//#define NUMERIC_SCALE(desc) ((DTYPE_IS_TEXT((desc).dsc_dtype)) ? 0 : (desc).dsc_scale)
/* Macros defining what operations are legal on data types */
inline bool DTYPE_CAN_NEGATE(UCHAR d) {
return DTYPE_IS_NUMERIC(d);
}
//#define DTYPE_CAN_NEGATE(d) DTYPE_IS_NUMERIC(d)
inline bool DTYPE_CAN_AVERAGE(UCHAR d) {
return DTYPE_IS_NUMERIC(d);
}
//#define DTYPE_CAN_AVERAGE(d) DTYPE_IS_NUMERIC(d)
inline bool DTYPE_CAN_DIVIDE(UCHAR d) {
return DTYPE_IS_NUMERIC(d);
}
//#define DTYPE_CAN_DIVIDE(d) DTYPE_IS_NUMERIC(d)
inline bool DTYPE_CAN_MULTIPLY(UCHAR d) {
return DTYPE_IS_NUMERIC(d);
}
//#define DTYPE_CAN_MULTIPLY(d) DTYPE_IS_NUMERIC(d)
#endif /* JRD_DSC_H */