Build Number:751
Update of /cvsroot/firebird/interbase/jrd
In directory usw-pr-cvs1:/tmp/cvs-serv23327
Modified Files:
cmp.c
Log Message:
Substring() v/s blobs, round two. SF Bug #522296.
Teach concatenate() to behave properly, SF Bug #518282.
Index: cmp.c
===================================================================
RCS file: /cvsroot/firebird/interbase/jrd/cmp.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -U3 -r1.14 -r1.15
--- cmp.c 11 Oct 2001 04:25:56 -0000 1.14
+++ cmp.c 25 Feb 2002 08:37:55 -0000 1.15
@@ -23,6 +23,10 @@
* 2001.07.17 Claudio Valderrama: Stop crash when parsing user-supplied SQL plan.
* 2001.10.04 Claudio Valderrama: Fix annoying & invalid server complaint about
* triggers not having REFERENCES privilege over their owner table.
+ * 2002.02.24 Claudio Valderrama: substring() should signal output as string even
+ * if source is blob and should check implementation limits on field lengths.
+ * 2002.02.25 Claudio Valderrama: concatenate() should be a civilized function.
+ * This closes the heart of SF Bug #518282.
*/
/*
$Id$
@@ -1401,22 +1405,28 @@
case nod_concatenate:
{
DSC desc1, desc2;
-
+ ULONG rc_len;
CMP_get_desc (tdbb, csb, node->nod_arg [0], &desc1);
CMP_get_desc (tdbb, csb, node->nod_arg [1], &desc2);
desc->dsc_dtype = dtype_text;
if (desc1.dsc_dtype <= dtype_varying)
{
- desc->dsc_length = desc1.dsc_length;
+ rc_len = desc1.dsc_length;
desc->dsc_ttype = desc1.dsc_ttype;
}
else
{
- desc->dsc_length = DSC_convert_to_text_length( desc1.dsc_dtype);
+ rc_len = DSC_convert_to_text_length (desc1.dsc_dtype);
desc->dsc_ttype = ttype_ascii;
}
- desc->dsc_length += (desc2.dsc_dtype <= dtype_varying) ?
- desc2.dsc_length : DSC_convert_to_text_length( desc2.dsc_dtype);
+ if (desc2.dsc_dtype <= dtype_varying)
+ rc_len += desc2.dsc_length;
+ else
+ rc_len += DSC_convert_to_text_length (desc2.dsc_dtype);
+ /* error() is a local routine in par.c, so we use plain ERR_post. */
+ if (rc_len > MAX_COLUMN_SIZE)
+ ERR_post (gds__imp_exc, gds_arg_gds, gds__blktoobig, 0);
+ desc->dsc_length = (USHORT) rc_len;
desc->dsc_scale = 0;
desc->dsc_flags = 0;
return;
@@ -1555,6 +1565,31 @@
case nod_substr:
CMP_get_desc (tdbb, csb, node->nod_arg [0], desc);
+ if (desc->dsc_dtype == dtype_blob)
+ {
+ DSC desc1, desc2;
+ ULONG rc_len;
+ CMP_get_desc (tdbb, csb, node->nod_arg [1], &desc1);
+ CMP_get_desc (tdbb, csb, node->nod_arg [2], &desc2);
+ if (desc1.dsc_flags & DSC_null || desc2.dsc_flags & DSC_null)
+ {
+ rc_len = 0;
+ desc->dsc_flags |= DSC_null;
+ }
+ else
+ {
+ SLONG sl1 = MOV_get_long (&desc1, 0);
+ SLONG sl2 = MOV_get_long (&desc2, 0);
+ /* error() is a local routine in par.c, so we use plain ERR_post. */
+ if (sl1 < 0 || sl2 < 0 || sl2 > MAX_COLUMN_SIZE - sizeof (USHORT))
+ ERR_post (gds__imp_exc, gds_arg_gds, gds__blktoobig, 0);
+ rc_len = sl2;
+ }
+ desc->dsc_dtype = dtype_varying;
+ desc->dsc_ttype = desc->dsc_scale;
+ desc->dsc_scale = 0;
+ desc->dsc_length = (USHORT) rc_len + sizeof (USHORT);
+ }
return;
case nod_function:
|