/**
  * 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);
     }
 }
示例#2
0
 /**
  * Merge two null check expression trees by removing duplicate nodes.
  *
  * @param AbstractExpression $nullCheckExpTree1 First expression.
  * @param AbstractExpression $nullCheckExpTree2 Second expression.
  * 
  * @return UnaryExpression or LogicalExpression
  */
 private function _mergeNullableExpressionTrees($nullCheckExpTree1, $nullCheckExpTree2)
 {
     $this->_mapTable = array();
     $this->_map($nullCheckExpTree1);
     $this->_map($nullCheckExpTree2);
     $expression = null;
     $isNullFunctionDescription = null;
     foreach ($this->_mapTable as $node) {
         if ($expression == null) {
             $expression = new UnaryExpression(new FunctionCallExpression(FunctionDescription::isNullCheckFunction($node->getType()), array($node)), ExpressionType::NOT_LOGICAL, new Boolean());
         } else {
             $expression = new LogicalExpression($expression, new UnaryExpression(new FunctionCallExpression(FunctionDescription::isNullCheckFunction($node->getType()), array($node)), ExpressionType::NOT_LOGICAL, new Boolean()), ExpressionType::AND_LOGICAL);
         }
     }
     return $expression;
 }
 /**
  * Function to create a nullable expression subtree for checking the
  * nullablilty of parent (and current poperty optionally) properties
  * 
  * @param boolean $includeMe Boolean flag indicating whether to include null
  *                           check for this property along with parents
  * 
  * @return AbstractExpression Instance of UnaryExpression, LogicalExpression
  *                            or Null
  * 
  */
 public function createNullableExpressionTree($includeMe)
 {
     $basePropertyExpression = $this;
     while ($basePropertyExpression != null && $basePropertyExpression->parent != null) {
         $basePropertyExpression = $basePropertyExpression->parent;
     }
     //This property is direct child of ResourceSet, no need to check
     //nullability for direct ResourceSet properties
     // ($c->CustomerID, $c->Order, $c->Address) unless $includeMe is true
     if ($basePropertyExpression == $this) {
         if ($includeMe) {
             return new UnaryExpression(new FunctionCallExpression(FunctionDescription::isNullCheckFunction($basePropertyExpression->getType()), array($basePropertyExpression)), ExpressionType::NOT_LOGICAL, new Boolean());
         }
         return null;
     }
     //This property is a property of a complex type or resource reference
     //$c->Order->OrderID, $c->Address->LineNumber,
     // $c->complex1->complex2->primitveVar
     //($c->Order != null),($c->Address != null),
     // (($c->complex1 != null) && ($c->complex1->complex2 != null))
     $expression = new UnaryExpression(new FunctionCallExpression(FunctionDescription::isNullCheckFunction($basePropertyExpression->getType()), array($basePropertyExpression)), ExpressionType::NOT_LOGICAL, new Boolean());
     while ($basePropertyExpression->getChild() != null && $basePropertyExpression->getChild()->getChild() != null) {
         $basePropertyExpression = $basePropertyExpression->getChild();
         $expression2 = new UnaryExpression(new FunctionCallExpression(FunctionDescription::isNullCheckFunction($basePropertyExpression->getType()), array($basePropertyExpression)), ExpressionType::NOT_LOGICAL, new Boolean());
         $expression = new LogicalExpression($expression, $expression2, ExpressionType::AND_LOGICAL);
     }
     if ($includeMe) {
         $basePropertyExpression = $basePropertyExpression->getChild();
         $expression2 = new UnaryExpression(new FunctionCallExpression(FunctionDescription::isNullCheckFunction($basePropertyExpression->getType()), array($basePropertyExpression)), ExpressionType::NOT_LOGICAL, new Boolean());
         $expression = new LogicalExpression($expression, $expression2, ExpressionType::AND_LOGICAL);
     }
     return $expression;
 }