/** * Process an arithmetic expression node for nullability * * @param FunctionCallExpression $expression The function call expression * node to process. * @param AbstractExpression $parentExpression The parent expression of * expression node to process. * * @return LogicalExpression or NULL */ private function _processFuncationCallNode(FunctionCallExpression $expression, $parentExpression) { $paramExpressions = $expression->getParamExpressions(); $checkNullForMostChild = strcmp($expression->getFunctionDescription()->functionName, 'is_null') === 0; $resultExpression = null; foreach ($paramExpressions as $paramExpression) { $resultExpression1 = $this->_processNodeForNullability($paramExpression, $expression, !$checkNullForMostChild); if ($resultExpression1 != null && $resultExpression != null) { $resultExpression = $this->_mergeNullableExpressionTrees($resultExpression, $resultExpression1); } else { if ($resultExpression1 != null && $resultExpression == null) { $resultExpression = $resultExpression1; } } } if ($resultExpression == null) { return null; } if ($parentExpression == null) { return new LogicalExpression($resultExpression, $expression, ExpressionType::AND_LOGICAL); } return $resultExpression; }
/** * Generates Comparison Expression * * @param AbstractExpression $left The LHS expression. * @param AbstractExpression $right The RHS expression. * @param ExpressionToken $expressionToken The cmparision expression token. * @param boolean $isCustomExpressionProvider True if the end user is responsible * for providing the IExpressionProvider * implementation. * * @return AbstractExpression */ private static function _generateComparisonExpression($left, $right, $expressionToken, $isCustomExpressionProvider) { FunctionDescription::verifyRelationalOpArguments($expressionToken, $left, $right); //We need special handling for comparison of following types: //1. String //2. DateTime //3. Guid //4. Binary //Will make these comparison as function calls, which will // be converted to language specific function call by expression // provider $string = new OString(); if ($left->typeIs($string) && $right->typeIs($string)) { $strcmpFunctions = FunctionDescription::stringComparisionFunctions(); $left = new FunctionCallExpression($strcmpFunctions[0], array($left, $right)); $right = new ConstantExpression(0, new Int32()); } $dateTime = new DateTime(); if ($left->typeIs($dateTime) && $right->typeIs($dateTime)) { $dateTimeCmpFunctions = FunctionDescription::dateTimeComparisonFunctions(); $left = new FunctionCallExpression($dateTimeCmpFunctions[0], array($left, $right)); $right = new ConstantExpression(0, new Int32()); } $guid = new Guid(); if ($left->typeIs($guid) && $right->typeIs($guid)) { $guidEqualityFunctions = FunctionDescription::guidEqualityFunctions(); $left = new FunctionCallExpression($guidEqualityFunctions[0], array($left, $right)); $right = new ConstantExpression(true, new Boolean()); } $binary = new Binary(); if ($left->typeIs($binary) && $right->typeIs($binary)) { $binaryEqualityFunctions = FunctionDescription::binaryEqualityFunctions(); $left = new FunctionCallExpression($binaryEqualityFunctions[0], array($left, $right)); $right = new ConstantExpression(true, new Boolean()); } $null = new Null1(); if ($left->typeIs($null) || $right->typeIs($null)) { // If the end user is responsible for implementing IExpressionProvider // then the sub-tree for a nullability check would be: // // RelationalExpression(EQ/NE) // | // ------------ // | | // | | // CustomerID NULL // // Otherwise (In case of default PHPExpressionProvider): // // CustomerID eq null // ================== // // FunctionCallExpression(is_null) // | // |- Signature => bool (typeof(CustomerID)) // |- args => {CustomerID} // // // CustomerID ne null // ================== // // UnaryExpression (not) // | // FunctionCallExpression(is_null) // | // |- Signature => bool (typeof(CustomerID)) // |- args => {CustomerID} // if (!$isCustomExpressionProvider) { $arg = $left->typeIs($null) ? $right : $left; $isNullFunctionDescription = new FunctionDescription('is_null', new Boolean(), array($arg->getType())); switch ($expressionToken->Text) { case ODataConstants::KEYWORD_EQUAL: return new FunctionCallExpression($isNullFunctionDescription, array($arg)); break; case ODataConstants::KEYWORD_NOT_EQUAL: return new UnaryExpression(new FunctionCallExpression($isNullFunctionDescription, array($arg)), ExpressionType::NOT_LOGICAL, new Boolean()); break; } } } switch ($expressionToken->Text) { case ODataConstants::KEYWORD_EQUAL: return new RelationalExpression($left, $right, ExpressionType::EQUAL); case ODataConstants::KEYWORD_NOT_EQUAL: return new RelationalExpression($left, $right, ExpressionType::NOTEQUAL); case ODataConstants::KEYWORD_GREATERTHAN: return new RelationalExpression($left, $right, ExpressionType::GREATERTHAN); case ODataConstants::KEYWORD_GREATERTHAN_OR_EQUAL: return new RelationalExpression($left, $right, ExpressionType::GREATERTHAN_OR_EQUAL); case ODataConstants::KEYWORD_LESSTHAN: return new RelationalExpression($left, $right, ExpressionType::LESSTHAN); default: return new RelationalExpression($left, $right, ExpressionType::LESSTHAN_OR_EQUAL); } }