I'm a little unclear why this making UnaryOperatorNode extend
ParameterNode and the subsequent changes are needed. Currently
triggers/views can check to see if the statement has a parameter node
anywhere in the tree without having every node implement ParameterNode,
so what is different about UnaryOperatorNode now?
I agree with Dan that it's not a good idea to make UnaryOperatorNode
extend ParameterNode, but I disagree about what we should do about it.
Here's some context --- when it comes to figuring out the type of a
node, in almost all cases the type is determined by the node itself,
or the node figures it out based on its children. For example, all
comparison operators have a type of boolean, while an arithmetic
operator node (like +) figures out its type based on its operands
(e.g. adding two ints gives an int).
ParameterNode is an exception. It gets its type from the context in
which it is used. For example, in:
t1.int_col = ?
the type of the ? is derived from what it is being compared to.
From a coding point of view, most type resolution is done bottom-up.
Each node resolves its children, then figures out what its own type
is. Parameters are different in that the type resolution must be done
top-down. In the "=" operator in the above example, the children of
the equals node are bound first, after which it checks to see whether
either child is a parameter node. If so, it takes the type from the
non-parameter side and sets the parameter to the same type.
There are something like 13 different cases in which a parameter node
can be used, and each case requires some special code of the type I
just described. Mamta is trying to avoid introducing even more
special-case code. One way to do this is to make UnaryOperatorNode
extend ParameterNode.
The biggest problem I have with this is that a unary operator isn't a
type of parameter. I think that changing the class hierarchy in this
way will only confuse people in the future.
Another problem is that allowing "- ?" is only one possible extension
to the cases parameters are allowed. If we add more extensions, will
we have to make more node types into parameters? We could eventually
end up with a large proportion of ValueNodes as extensions of ParameterNode.
It seems to me that, to determine whether a node needs this special
top-down type processing, the code shouldn't be asking whether it's a
parameter node. It should ask whether the node (or expression) has to
derive its type from context. For example, BinaryOperatorNode could
be changed to something like this:
if (leftOperand.getsTypeFromContext())
{
if (rightOperand.getsTypeFromContext())
{
throw StandardException.newException(. . .);
}
leftOperand.setDescriptor(rightOperand.getTypeServices());
}
if (rightOperand.getsTypeFromContext())
{
rightOperand.setDescriptor(leftOperand.getTypeServices());
}
In ValueNode, getsTypeFromContext() would return false. In
ParameterNode it would return true. In UnaryArithmeticOperatorNode it
would return true if its operand is a ParameterNode and false
otherwise (one way to do this is to make it return
operand.getsTypeFromContext()).
As for why there are two methods for setting types (setType() and
setDescriptor()), they do different things for ParameterNode. All
that setType() does is set the type for the node itself.
ParameterNode.setDescriptor() also sets the type in the array of
parameter types in the StatementNode. There's also some stuff in
there having to do with replication/synchronization that could be
obsolete (depending on whether this feature is ever resurrected). I
agree that it's confusing to have two different methods do similar
things. Perhaps the two methods could be collapsed into one.
- Jeff Lichtman
[EMAIL PROTECTED]
Check out Swazoo Koolak's Web Jukebox at
http://swazoo.com/