The nullability of a field defines whether the field can
contain a null. A field containing a null does not contain a value.
For example, you can have a data set whose record schema contains
an age field. If the age field of a particular record is null, the
age is not known for the person corresponding to the record.
As part of processing a record field, you can detect a null and
take the appropriate action. For instance, you can omit the null field
from a calculation, signal an error condition, or take some other
action.
To recognize a nullable field, the field of the interface must
be defined to be nullable. You include the keyword nullable in the
interface specification of a field to make it nullable. For example,
all fields of the operator shown in the following figure are nullable:
Figure 1. AddOperator with nullable field information
The following code example is the describeOperator() function for
AddOperator:
Table 1. Nullable fields in describeOperator()
schema codeComment |
Code |
6
7
|
APT_Status AddOperator::describeOperator()
{
setKind(APT_Operator::eParallel);
setInputDataSets(1);
setOutputDataSets(1);
setInputInterfaceSchema("record (field1:nullable int32;"
"field2:nullable int32)",0);
setOutInterfaceSchema("record (field1:nullable int32;"
"field2:nullable int32)",0);
return APT_StatusOk;
}
|
- 6
- Specify that all fields of the interface schema of input 0 are
nullable. You can individually specify any or all fields of the interface
schema as nullable.
- 7
- Specify that all fields of the output interface schema are nullable.
For the first record in the output data set, and after each call to
APT_OutputCursor::putRecord(), the null indicator in all nullable
output fields is set, marking the field as containing a null. Writing
a value to an output field clears the null indicator.
If an input field to an operator contains null and
the corresponding operator interface field is not nullable, InfoSphere
DataStage issues a fatal error and aborts your application. You can
use view adapters to prevent a fatal error in this case.
Both input
and output accessors contain member functions for working with nulls.
For input accessors, you use:
- isNull()
- Returns true if the accessor references a field containing a null.
- isNullAt()
- Returns true if the accessor references a vector element containing
a null.
- isNullable()
- Returns true if the accessor references a nullable field.
For output accessors, you use:
- isNull()
- Returns true if the accessor references a field containing a null.
- isNullAt()
- Returns true if the accessor references a vector element containing
a null.
- isNullable()
- Returns true if the accessor references a nullable field.
- clearIsNull()
- Clears the null indicator for the field referenced by an accessor
and sets the field to the default value. If isNullable() returns false,
clearIsNull() does nothing.
- For the first record in the output data set, and after each call
to APT_OutputCursor::putRecord(), the null indicator in all nullable
output fields of the new output record is set, marking the field as
containing a null. Writing a value to an output field clears the null
indicator, so it is typically unnecessary to call clearIsNull().
- clearIsNullAt()
- Clears the null indicator for the vector element referenced by
an accessor, and sets the value of the field to the default value
for its type.
- setIsNull()
- Sets the null indicator for the field referenced by an accessor,
marking the field to contain a null. setIsNull() requires that isNullable()
returns true.
- Because the null flag for all nullable output fields is initially
set, you only need to call setIsNull() if you have written valid data
to an output field and later decide to set the field to null.
- setIsNullAt()
- Sets the null indicator for a vector element referenced by an
accessor, marking the field to contain a null.
You typically use the operator*
member function of an input and output accessor to obtain the value
of a field. For an input accessor, using operator*
on a field containing a null causes a requirements violation and aborts
your application. Therefore, you must first determine if a nullable
input field contains a null, using isNull(), before attempting to
access it.
For an output accessor, calling operator*
always clears the null indicator for a nullable field, marking the
field to contain valid data. You can use setIsNull() to explicitly
set the null indicator in an output field, if necessary.
How
you choose to handle nulls detected in an input field or what conditions
cause an output field to be set to null is determined by your operator
logic. Often, a null in an input field will be propagated through
to the output. For example, the following code example is the APT_Operator::runLocally()
function for AddOperator:
Table 2. Handling nullable fields in runLocally()
codeComment |
Code |
14
16
18
20
|
APT_Status AddOperator::runLocally()
{
APT_InputCursor inCur;
APT_OutputCursor outCur;
setupInputCursor(&inCur, 0);
setupOutputCursor(&outCur, 0);
APT_InputAccessorToInt32 field1InAcc("field1", &inCur);
APT_InputAccessorToInt32 field2InAcc("field2", &inCur);
APT_OutputAccessorToInt32 field1OutAcc("field1", &outCur);
APT_OutputAccessorToInt32 field2OutAcc("field2", &outCur);
APT_OutputAccessorToInt32 totalOutAcc("total", &outCur);
while (inCur.getRecord())
{
if (!field1InAcc.isNull())
*field1OutAcc = *field1InAcc;
if (!field2InAcc.isNull())
*field2OutAcc = *field2InAcc;
if (!field1InAcc.isNull() && !field2InAcc.isNull())
*totalOutAcc = *field1InAcc + *field2InAcc;
outCur.putRecord();
}
return APT_StatusOk;
}
|
- 14
- Use field1InAcc.isNull() to determine if field1 contains
a null. If not, copy it to the output record.
- 16
- Determine if field2 contains a null. If not,
copy it to the output record.
- 18
- If both field1 and field2 contain
valid data, perform the addition. Writing to total clears the null
indicator for the field.
- 20
- Call APT_OutputCursor::putRecord() to write the output record.