-
Bug
-
Resolution: Won't Fix
-
P4
-
None
-
1.4.1
-
x86
-
windows_2000
or into the 2 parametered version of the method:
value.decimalValues (_dis0, _decimalValues);
(Review ID: 158875)
======================================================================
Name: nt126004 Date: 07/08/2002
FULL PRODUCT VERSION :
java version "1.3.1_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_04-b02)
Java HotSpot(TM) Client VM (build 1.3.1_04-b02, mixed mode)
FULL OPERATING SYSTEM VERSION : Microsoft Windows 2000
[Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
I believe I have spotted a subtle bug in the idlj compiler
to do with discriminators in unions. I encountered this
problem using JDK1.3 but I have produced the same result
using the latest 1.4.1 Beta.
I am compiling three IDL files from Sybase's EAServer
product: TabularResults.idl, MJD.idl and BCD.idl.
As I understand it, the union discriminator is not being
set correctly when the unioned 'Data' object is being read
(rebuilt) on the client side. I have drilled down into the
stub code and the problem seems to be the line marked
*HERE* in the following stub:
TabularResults.Data read(...)
{
TabularResults.Data value = new TabularResults.Data ();
int _dis0 = (int)0;
_dis0 = istream.read_long ();
switch (_dis0)
{
...
case TabularResults.TYPE_BIGINT.value:
case TabularResults.TYPE_DECIMAL.value:
case TabularResults.TYPE_NUMERIC.value:
BCD.Decimal _decimalValues[] = null;
_decimalValues = TabularResults.DecimalSeqHelper.read
(istream);
value.decimalValues (_decimalValues); -- *HERE*
break;
...
}
}
As I understand it the code switches on the discriminator
to figure out what type of unioned object should be built.
What I believe should be happening is that the line I have
marked should be passing in the discriminator like this:
value.decimalValues (_dis0, _decimalValues); -- *HERE*
Yes there are two versions of this method and the first one
just sets a default discriminator value. Here they are:
public void decimalValues (BCD.Decimal[] value)
{
__discriminator = TabularResults.TYPE_BIGINT.value;
___decimalValues = value;
__uninitialized = false;
}
public void decimalValues (int discriminator, BCD.Decimal[]
value)
{
verifydecimalValues (discriminator);
__discriminator = discriminator;
___decimalValues = value;
__uninitialized = false;
}
As I've said, I reckon it should be calling the second one.
The interesting part is that if I compile the same IDL file
using the Sybase tools it does create stubs that call the
2nd version. Here's the code that is created in this case:
case (int)-5:
case (int)3:
case (int)2:
{
value.decimalValues(_switch,
TabularResults.DecimalSeqHelper.read(_input));
break;
}
Do you think that I am on to something here, or is there is
something that I am overlooking?
Thanks for your time,
Paul.
-- IDL Source Files are below here --
------------------
TabularResutls.idl
------------------
#include "BCD.idl"
#include "MJD.idl"
/*
* This module defines CORBA IDL constants and types for
dynamic result
* set handling, with the intention of supporting easy
conversion from
* and to java.sql.ResultSet (or jdbc.sql.ResultSet for JDK
1.0.2).
*
* <p>No interface types are defined for result set
handling.
* When an operation returns a result set, the entire
result set
* must be transmitted from server to client before the
client can begin
* processing the results.
*
* <p>This approach has the potential to be much more
efficient in a wide-area
* network environment than the use of interface types,
which would result in a
* large number of small requests from client to server to
fetch an entire
* result set. It is also preferable to streaming the
result set into an
* octet sequence, since the IDL language mappings for the
<code>ResultSet</code>
* type allow for convenient manipulation of result set
data and meta-data.
*
* <p>If a client requires the ability to process some
results before all the
* results have been transmitted, the result set can be
explicitly broken
* into batches by the server programmer using an IDL
interface such as:
* <pre>
* interface SampleInterface
* {
* TabularResults::ResultSet
operationWhichReturnsResultSet(...);
*
* TabularResults::ResultSet getMoreResults();
* };
* </pre>
*/
module TabularResults
{
// The following constants define the column data types
for result sets.
// The actual constant values are equivalent to those
in XOPEN (and JDBC).
// The leading 'TYPE_' prefix is used since some of the
type names are IDL
// reserved words.
const long TYPE_BIGINT = -5;
const long TYPE_BINARY = -2;
const long TYPE_BIT = -7;
const long TYPE_CHAR = 1;
const long TYPE_DATE = 91;
const long TYPE_DECIMAL = 3;
const long TYPE_DOUBLE = 8;
const long TYPE_FLOAT = 6;
const long TYPE_INTEGER = 4;
const long TYPE_LONGVARBINARY = -4;
const long TYPE_LONGVARCHAR = -1;
const long TYPE_NUMERIC = 2;
const long TYPE_REAL = 7;
const long TYPE_SMALLINT = 5;
const long TYPE_TIME = 92;
const long TYPE_TIMESTAMP = 93;
const long TYPE_TINYINT = -6;
const long TYPE_VARBINARY = -3;
const long TYPE_VARCHAR = 12;
// The following constants define flags for result
columns. These are
// used to convey meta-data which is not indicated by
the column type.
const unsigned long FLAG_AUTO_INCREMENT = 1;
const unsigned long FLAG_CASE_SENSITIVE = 2;
const unsigned long FLAG_CURRENCY = 4;
const unsigned long FLAG_NOT_NULLABLE = 8;
const unsigned long FLAG_NULLABLE = 16;
const unsigned long FLAG_READONLY = 32;
const unsigned long FLAG_SEARCHABLE = 64;
const unsigned long FLAG_UNSIGNED = 128;
const unsigned long FLAG_WRITABLE = 256;
const unsigned long FLAG_DEFINITELY_WRITABLE = 512;
typedef sequence < boolean > BooleanSeq;
typedef sequence < octet > OctetSeq;
typedef sequence < short > ShortSeq;
typedef sequence < long > LongSeq;
typedef sequence < float > FloatSeq;
typedef sequence < double > DoubleSeq;
typedef sequence < string > StringSeq;
typedef sequence < BCD::Binary > BinarySeq;
typedef sequence < BCD::Decimal > DecimalSeq;
typedef sequence < MJD::Date > DateSeq;
typedef sequence < MJD::Time > TimeSeq;
typedef sequence < MJD::Timestamp > TimestampSeq;
/*
* The <code>Data</code> type represents an entire
column in a result set.
* Data is stored in a result set in column-major
order. This means the
* column data type (the union discriminator) only
needs to be transmitted
* over the network once, and minimises padding when
using GIOP.
*
* <p>Notes:
* <ul>
* <li>Type BIGINT uses BCD::Decimal because some CORBA
ORBs do not support
* the IDL "long long" type that was introduced with
CORBA 2.1 / GIOP 1.1.
* </ul>
*/
union Data switch (long)
{
case TYPE_BIT : BooleanSeq booleanValues;
case TYPE_TINYINT : OctetSeq octetValues;
case TYPE_SMALLINT : ShortSeq shortValues;
case TYPE_INTEGER : LongSeq longValues;
case TYPE_REAL : FloatSeq floatValues;
case TYPE_DOUBLE :
case TYPE_FLOAT : DoubleSeq doubleValues;
case TYPE_CHAR :
case TYPE_LONGVARCHAR :
case TYPE_VARCHAR : StringSeq stringValues;
case TYPE_BINARY :
case TYPE_LONGVARBINARY :
case TYPE_VARBINARY : BinarySeq binaryValues;
case TYPE_BIGINT :
case TYPE_DECIMAL :
case TYPE_NUMERIC : DecimalSeq decimalValues;
case TYPE_DATE : DateSeq dateValues;
case TYPE_TIME : TimeSeq timeValues;
case TYPE_TIMESTAMP : TimestampSeq
timestampValues;
};
/*
* A result column consists of meta data and data
values, as well as
* a sequence indicating which rows contain null
values. The length of
* 'nulls' may be less than the number of result rows.
The default value
* if a row's 'nulls' entry is not present is false
(i.e. non-null). This
* optimisation is particularly useful when the
column's 'flags' contains
* the FLAG_NOT_NULLABLE bit.
* <p>The precision for floating-point decimal values
is calculated as
* 'width - sign - dot', where sign = 1 if the flags
bit FLAG_UNSIGNED
* is set (otherwise sign = 0), and dot = 1 if scale >
0 (otherwise
* dot = 0).
* <p>The scale must be zero for TYPE_BIGINT.
*/
struct Column
{
unsigned long flags; // Column's meta-data flags
unsigned long width; // Column's normal display
width in characters
unsigned long scale; // Column's scale for fixed-
point decimal values
string name; // Column's name
string label; // Column's label (may be
empty if equal to name)
Data values; // Data values for this column
(for all rows)
BooleanSeq nulls; // May be less than the number
of rows
};
typedef sequence < Column > ColumnSeq;
/*
* The <code>ResultSet</code> type may be used as the
return type
* for an operation returning a single result set.
*/
struct ResultSet
{
unsigned long rows;
ColumnSeq columns;
};
/*
* The <code>ResultSets</code> type may be used as the
return type
* for an operation returning multiple result sets.
*/
typedef sequence<ResultSet> ResultSets;
};
-------
BCD.idl
-------
/**
** This module defines generic binary (octet sequence)
types, and arbitrary
** precision floating-point decimal data types.
** <p>For generic coding, the decimal types are a useful
alternative to the IDL
** <code>fixed</code> template types which were introduced
by CORBA 2.1 and
** GIOP 1.1, since the use of template types introduces a
distinct type for
** each combination of precision and scale.
**/
module BCD
{
/**
** A generic octet sequence type.
**/
typedef sequence < octet > Binary;
/**
** <p>A floating-point decimal type.
** <p>The <code>Binary</code> representation of
floating-point values is
** designed to support easy conversion to and from
strings, while at the
** same time minimising the size of the binary
representation for GIOP.
** <p>A number is converted to the binary
representation using the
** following algorithm.
** <ul>
** <li>Convert the number to a decimal string, with a
leading '-' if
** negative, and no leading sign if zero or positive.
** <li>The string may contain a decimal point. If the
number's scale is
** greater than zero, the decimal point is followed by
the number's decimal
** fraction. The number of digits in the fraction
indicates the scale;
** trailing zeroes should not be truncated as that
would reduce the implied
** scale.
** <li>Convert the string's characters to an octet
sequence where each
** half-octet represents padding, a decimal digit,
negative sign, or
** decimal point, as follows:
** <ul>
** <li>If the string length is odd, the initial half-
octet value is 12.
** This is used as padding to ensure an even number of
half-octets.
** <li>'0' to '9' map to half-octet values 0 to 9.
** <li>'.' maps to half-octet value 10.
** <li>'-' maps to half-octet value 13.
** </ul>
** <li>In each octet of the sequence, the most
significant half-octet is
** filled first. Thus the value "-9" would be encoded
as octet value
** <code>13 * 16 + 9 = 217</code>.
** </ul>
** <p>Any program receiving a binary value which is
not formed according
** to the above specification should raise a
CORBA::DATA_CONVERSION system
** exception.
** <p>Note: a struct is used because it allows
overloaded methods to be
** defined in C++ and Java for decimal manipulation.
It also guarantees
** that a distinct type is generated for the Java IDL
language mapping.
**/
struct Decimal
{
Binary value;
};
/**
** <p>A floating-point decimal (money) type. Uses the
same representation
** as <code>Decimal</code> but may be used where a
semantic distinction is
** required.
** <p>Note: a struct is used because it allows
overloaded methods to be
** defined in C++ and Java for money manipulation. It
also guarantees
** that a distinct type is generated for the Java IDL
language mapping.
**/
struct Money
{
Binary value;
};
};
-------
MJD.idl
-------
/*
* This module defines date/time types based on the
Modified Astronomical
* Julian Date (M.J.D.) standard. The Modified Julian Date
is given in
* decimal form, not in hours and minutes.
*
* <p>Source: Norton's Star Atlas and Reference Handbook,
17th edition.
*/
module MJD
{
/*
* The <code>Date</code> type encodes a date/time as
J.D. - 2,400,000.5,
* where J.D. = 0 represents Jan 1, 4713 B.C. at
Greenwich noon.
* For example, Greenwich midnight Jan 1, 1970 is
M.J.D. 40222.0.
* <p>This type provides millsecond resolution for
dates at least
* 10,000 years either side of the base value (MJD =
0.0).
* <p>Note: a struct is used because it allows
overloaded methods to be
* defined in C++ and Java for date manipulation.
*/
struct Date
{
double dateValue;
};
/*
* The <code>Time</code> type encodes a time with
nanosecond
* resolution. The encoded value <code>timeValue</code>
is equivalent
* to <code>Date's</code> dateValue, but only the
fractional part of
* <code>timeValue</code> is understood to have
significance.
* The integral part should be zero, since any
significant digits in
* the integral part reduce the precision of the time
value.
* <p>Note: a struct is used because it allows
overloaded methods to be
* defined in C++ and Java for time manipulation.
*/
struct Time
{
double timeValue;
};
/*
* The <code>Timestamp</code> type encodes a date/time
with nanosecond
* resolution. The encoded value dateValue + timeValue
is equivalent
* to <code>Date's</code> dateValue, but allows for
nanosecond resolution.
* To ensure no loss of significance,
<code>dateValue</code> must be
* integral (may be negative) and <code>0 <=
timeValue < 1</code>.
* <p>This type provides nanosecond resolution for
dates at least
* 100,000,000,000 years either side of the base value
(MJD = 0.0).
*/
struct Timestamp
{
double dateValue;
double timeValue;
};
};
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the IDL files using idlj.
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER WORKAROUND :
Nobble the DataHelper.read() so that it passes the
discriminat
value.decimalValues (_dis0, _decimalValues);
(Review ID: 158875)
======================================================================
Name: nt126004 Date: 07/08/2002
FULL PRODUCT VERSION :
java version "1.3.1_04"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_04-b02)
Java HotSpot(TM) Client VM (build 1.3.1_04-b02, mixed mode)
FULL OPERATING SYSTEM VERSION : Microsoft Windows 2000
[Version 5.00.2195]
A DESCRIPTION OF THE PROBLEM :
I believe I have spotted a subtle bug in the idlj compiler
to do with discriminators in unions. I encountered this
problem using JDK1.3 but I have produced the same result
using the latest 1.4.1 Beta.
I am compiling three IDL files from Sybase's EAServer
product: TabularResults.idl, MJD.idl and BCD.idl.
As I understand it, the union discriminator is not being
set correctly when the unioned 'Data' object is being read
(rebuilt) on the client side. I have drilled down into the
stub code and the problem seems to be the line marked
*HERE* in the following stub:
TabularResults.Data read(...)
{
TabularResults.Data value = new TabularResults.Data ();
int _dis0 = (int)0;
_dis0 = istream.read_long ();
switch (_dis0)
{
...
case TabularResults.TYPE_BIGINT.value:
case TabularResults.TYPE_DECIMAL.value:
case TabularResults.TYPE_NUMERIC.value:
BCD.Decimal _decimalValues[] = null;
_decimalValues = TabularResults.DecimalSeqHelper.read
(istream);
value.decimalValues (_decimalValues); -- *HERE*
break;
...
}
}
As I understand it the code switches on the discriminator
to figure out what type of unioned object should be built.
What I believe should be happening is that the line I have
marked should be passing in the discriminator like this:
value.decimalValues (_dis0, _decimalValues); -- *HERE*
Yes there are two versions of this method and the first one
just sets a default discriminator value. Here they are:
public void decimalValues (BCD.Decimal[] value)
{
__discriminator = TabularResults.TYPE_BIGINT.value;
___decimalValues = value;
__uninitialized = false;
}
public void decimalValues (int discriminator, BCD.Decimal[]
value)
{
verifydecimalValues (discriminator);
__discriminator = discriminator;
___decimalValues = value;
__uninitialized = false;
}
As I've said, I reckon it should be calling the second one.
The interesting part is that if I compile the same IDL file
using the Sybase tools it does create stubs that call the
2nd version. Here's the code that is created in this case:
case (int)-5:
case (int)3:
case (int)2:
{
value.decimalValues(_switch,
TabularResults.DecimalSeqHelper.read(_input));
break;
}
Do you think that I am on to something here, or is there is
something that I am overlooking?
Thanks for your time,
Paul.
-- IDL Source Files are below here --
------------------
TabularResutls.idl
------------------
#include "BCD.idl"
#include "MJD.idl"
/*
* This module defines CORBA IDL constants and types for
dynamic result
* set handling, with the intention of supporting easy
conversion from
* and to java.sql.ResultSet (or jdbc.sql.ResultSet for JDK
1.0.2).
*
* <p>No interface types are defined for result set
handling.
* When an operation returns a result set, the entire
result set
* must be transmitted from server to client before the
client can begin
* processing the results.
*
* <p>This approach has the potential to be much more
efficient in a wide-area
* network environment than the use of interface types,
which would result in a
* large number of small requests from client to server to
fetch an entire
* result set. It is also preferable to streaming the
result set into an
* octet sequence, since the IDL language mappings for the
<code>ResultSet</code>
* type allow for convenient manipulation of result set
data and meta-data.
*
* <p>If a client requires the ability to process some
results before all the
* results have been transmitted, the result set can be
explicitly broken
* into batches by the server programmer using an IDL
interface such as:
* <pre>
* interface SampleInterface
* {
* TabularResults::ResultSet
operationWhichReturnsResultSet(...);
*
* TabularResults::ResultSet getMoreResults();
* };
* </pre>
*/
module TabularResults
{
// The following constants define the column data types
for result sets.
// The actual constant values are equivalent to those
in XOPEN (and JDBC).
// The leading 'TYPE_' prefix is used since some of the
type names are IDL
// reserved words.
const long TYPE_BIGINT = -5;
const long TYPE_BINARY = -2;
const long TYPE_BIT = -7;
const long TYPE_CHAR = 1;
const long TYPE_DATE = 91;
const long TYPE_DECIMAL = 3;
const long TYPE_DOUBLE = 8;
const long TYPE_FLOAT = 6;
const long TYPE_INTEGER = 4;
const long TYPE_LONGVARBINARY = -4;
const long TYPE_LONGVARCHAR = -1;
const long TYPE_NUMERIC = 2;
const long TYPE_REAL = 7;
const long TYPE_SMALLINT = 5;
const long TYPE_TIME = 92;
const long TYPE_TIMESTAMP = 93;
const long TYPE_TINYINT = -6;
const long TYPE_VARBINARY = -3;
const long TYPE_VARCHAR = 12;
// The following constants define flags for result
columns. These are
// used to convey meta-data which is not indicated by
the column type.
const unsigned long FLAG_AUTO_INCREMENT = 1;
const unsigned long FLAG_CASE_SENSITIVE = 2;
const unsigned long FLAG_CURRENCY = 4;
const unsigned long FLAG_NOT_NULLABLE = 8;
const unsigned long FLAG_NULLABLE = 16;
const unsigned long FLAG_READONLY = 32;
const unsigned long FLAG_SEARCHABLE = 64;
const unsigned long FLAG_UNSIGNED = 128;
const unsigned long FLAG_WRITABLE = 256;
const unsigned long FLAG_DEFINITELY_WRITABLE = 512;
typedef sequence < boolean > BooleanSeq;
typedef sequence < octet > OctetSeq;
typedef sequence < short > ShortSeq;
typedef sequence < long > LongSeq;
typedef sequence < float > FloatSeq;
typedef sequence < double > DoubleSeq;
typedef sequence < string > StringSeq;
typedef sequence < BCD::Binary > BinarySeq;
typedef sequence < BCD::Decimal > DecimalSeq;
typedef sequence < MJD::Date > DateSeq;
typedef sequence < MJD::Time > TimeSeq;
typedef sequence < MJD::Timestamp > TimestampSeq;
/*
* The <code>Data</code> type represents an entire
column in a result set.
* Data is stored in a result set in column-major
order. This means the
* column data type (the union discriminator) only
needs to be transmitted
* over the network once, and minimises padding when
using GIOP.
*
* <p>Notes:
* <ul>
* <li>Type BIGINT uses BCD::Decimal because some CORBA
ORBs do not support
* the IDL "long long" type that was introduced with
CORBA 2.1 / GIOP 1.1.
* </ul>
*/
union Data switch (long)
{
case TYPE_BIT : BooleanSeq booleanValues;
case TYPE_TINYINT : OctetSeq octetValues;
case TYPE_SMALLINT : ShortSeq shortValues;
case TYPE_INTEGER : LongSeq longValues;
case TYPE_REAL : FloatSeq floatValues;
case TYPE_DOUBLE :
case TYPE_FLOAT : DoubleSeq doubleValues;
case TYPE_CHAR :
case TYPE_LONGVARCHAR :
case TYPE_VARCHAR : StringSeq stringValues;
case TYPE_BINARY :
case TYPE_LONGVARBINARY :
case TYPE_VARBINARY : BinarySeq binaryValues;
case TYPE_BIGINT :
case TYPE_DECIMAL :
case TYPE_NUMERIC : DecimalSeq decimalValues;
case TYPE_DATE : DateSeq dateValues;
case TYPE_TIME : TimeSeq timeValues;
case TYPE_TIMESTAMP : TimestampSeq
timestampValues;
};
/*
* A result column consists of meta data and data
values, as well as
* a sequence indicating which rows contain null
values. The length of
* 'nulls' may be less than the number of result rows.
The default value
* if a row's 'nulls' entry is not present is false
(i.e. non-null). This
* optimisation is particularly useful when the
column's 'flags' contains
* the FLAG_NOT_NULLABLE bit.
* <p>The precision for floating-point decimal values
is calculated as
* 'width - sign - dot', where sign = 1 if the flags
bit FLAG_UNSIGNED
* is set (otherwise sign = 0), and dot = 1 if scale >
0 (otherwise
* dot = 0).
* <p>The scale must be zero for TYPE_BIGINT.
*/
struct Column
{
unsigned long flags; // Column's meta-data flags
unsigned long width; // Column's normal display
width in characters
unsigned long scale; // Column's scale for fixed-
point decimal values
string name; // Column's name
string label; // Column's label (may be
empty if equal to name)
Data values; // Data values for this column
(for all rows)
BooleanSeq nulls; // May be less than the number
of rows
};
typedef sequence < Column > ColumnSeq;
/*
* The <code>ResultSet</code> type may be used as the
return type
* for an operation returning a single result set.
*/
struct ResultSet
{
unsigned long rows;
ColumnSeq columns;
};
/*
* The <code>ResultSets</code> type may be used as the
return type
* for an operation returning multiple result sets.
*/
typedef sequence<ResultSet> ResultSets;
};
-------
BCD.idl
-------
/**
** This module defines generic binary (octet sequence)
types, and arbitrary
** precision floating-point decimal data types.
** <p>For generic coding, the decimal types are a useful
alternative to the IDL
** <code>fixed</code> template types which were introduced
by CORBA 2.1 and
** GIOP 1.1, since the use of template types introduces a
distinct type for
** each combination of precision and scale.
**/
module BCD
{
/**
** A generic octet sequence type.
**/
typedef sequence < octet > Binary;
/**
** <p>A floating-point decimal type.
** <p>The <code>Binary</code> representation of
floating-point values is
** designed to support easy conversion to and from
strings, while at the
** same time minimising the size of the binary
representation for GIOP.
** <p>A number is converted to the binary
representation using the
** following algorithm.
** <ul>
** <li>Convert the number to a decimal string, with a
leading '-' if
** negative, and no leading sign if zero or positive.
** <li>The string may contain a decimal point. If the
number's scale is
** greater than zero, the decimal point is followed by
the number's decimal
** fraction. The number of digits in the fraction
indicates the scale;
** trailing zeroes should not be truncated as that
would reduce the implied
** scale.
** <li>Convert the string's characters to an octet
sequence where each
** half-octet represents padding, a decimal digit,
negative sign, or
** decimal point, as follows:
** <ul>
** <li>If the string length is odd, the initial half-
octet value is 12.
** This is used as padding to ensure an even number of
half-octets.
** <li>'0' to '9' map to half-octet values 0 to 9.
** <li>'.' maps to half-octet value 10.
** <li>'-' maps to half-octet value 13.
** </ul>
** <li>In each octet of the sequence, the most
significant half-octet is
** filled first. Thus the value "-9" would be encoded
as octet value
** <code>13 * 16 + 9 = 217</code>.
** </ul>
** <p>Any program receiving a binary value which is
not formed according
** to the above specification should raise a
CORBA::DATA_CONVERSION system
** exception.
** <p>Note: a struct is used because it allows
overloaded methods to be
** defined in C++ and Java for decimal manipulation.
It also guarantees
** that a distinct type is generated for the Java IDL
language mapping.
**/
struct Decimal
{
Binary value;
};
/**
** <p>A floating-point decimal (money) type. Uses the
same representation
** as <code>Decimal</code> but may be used where a
semantic distinction is
** required.
** <p>Note: a struct is used because it allows
overloaded methods to be
** defined in C++ and Java for money manipulation. It
also guarantees
** that a distinct type is generated for the Java IDL
language mapping.
**/
struct Money
{
Binary value;
};
};
-------
MJD.idl
-------
/*
* This module defines date/time types based on the
Modified Astronomical
* Julian Date (M.J.D.) standard. The Modified Julian Date
is given in
* decimal form, not in hours and minutes.
*
* <p>Source: Norton's Star Atlas and Reference Handbook,
17th edition.
*/
module MJD
{
/*
* The <code>Date</code> type encodes a date/time as
J.D. - 2,400,000.5,
* where J.D. = 0 represents Jan 1, 4713 B.C. at
Greenwich noon.
* For example, Greenwich midnight Jan 1, 1970 is
M.J.D. 40222.0.
* <p>This type provides millsecond resolution for
dates at least
* 10,000 years either side of the base value (MJD =
0.0).
* <p>Note: a struct is used because it allows
overloaded methods to be
* defined in C++ and Java for date manipulation.
*/
struct Date
{
double dateValue;
};
/*
* The <code>Time</code> type encodes a time with
nanosecond
* resolution. The encoded value <code>timeValue</code>
is equivalent
* to <code>Date's</code> dateValue, but only the
fractional part of
* <code>timeValue</code> is understood to have
significance.
* The integral part should be zero, since any
significant digits in
* the integral part reduce the precision of the time
value.
* <p>Note: a struct is used because it allows
overloaded methods to be
* defined in C++ and Java for time manipulation.
*/
struct Time
{
double timeValue;
};
/*
* The <code>Timestamp</code> type encodes a date/time
with nanosecond
* resolution. The encoded value dateValue + timeValue
is equivalent
* to <code>Date's</code> dateValue, but allows for
nanosecond resolution.
* To ensure no loss of significance,
<code>dateValue</code> must be
* integral (may be negative) and <code>0 <=
timeValue < 1</code>.
* <p>This type provides nanosecond resolution for
dates at least
* 100,000,000,000 years either side of the base value
(MJD = 0.0).
*/
struct Timestamp
{
double dateValue;
double timeValue;
};
};
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile the IDL files using idlj.
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER WORKAROUND :
Nobble the DataHelper.read() so that it passes the
discriminat