Walks down a SimpleCaseExpression AST node and generates the corresponding SQL.

@param AST\SimpleCaseExpression $simpleCaseExpression

@return string The SQL.
961681
public function walkSimpleCaseExpression($simpleCaseExpression)
    {
        $sql = 'CASE ' . $this->walkStateFieldPathExpression($simpleCaseExpression->caseOperand);

        foreach ($simpleCaseExpression->simpleWhenClauses as $simpleWhenClause) {
            $sql .= ' WHEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->caseScalarExpression);
            $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->thenScalarExpression);
        }

        $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($simpleCaseExpression->elseScalarExpression) . ' END';

        return $sql;
    }
823509
public function generateAlias(Clause $clause)
    {
        if ($clause instanceof FieldName)
        {
            $table = $clause->getTable();
            if (empty($table))
            {
                // When no table is defined, it means only one table is being
                // used in the query. Aliases will not be required
                return "";
            }

            $prefix = $table->getPrefix();
            $alias = $prefix . '_' . $clause->getField();
        }
        elseif ($clause instanceof SQLFunction)
        {
            $func = $clause->getFunction();
            $alias = strtolower($func);
        }
        else
            throw new ImplementationException("No alias generation implemented for: " . get_class($clause));

        $cnt = 1;
        $base_alias = $alias;
        while (isset($this->field_aliases[$alias]))
            $alias = $base_alias . (++$cnt);

        $this->field_aliases[$alias] = true;
        return $alias;
    }
1138820
function() {
      switch (this.type) {
        case _Numeric:
        case _String:
        case _RegularExpression:
        case _Boolean:
        case _Null:
          return this.parseLiteral();
        case _Identifier:
          return this.parseIdentifier();
        case _Keyword:
          return this.parsePrimaryKeywordExpression();
        case _Punctuator:
          return this.parsePrimaryPunctuatorExpression();
        case _Template:
          return this.parseTemplateLiteral();
        default:
          this.unexpected();
      }
    }
569364
public function get_sql() : string {
		if ( empty( $this->columns_to_select ) ) {
			// this should be the default behavior
			$this->columns_to_select = [ '*' ];
		}

		$from = ' FROM ' . implode( ', ', $this->from ) . ' ';

		if ( ! empty( $this->joins ) ) {
			$from .= $this->joins;
		}

		$from  .= 'WHERE ' . $this->where_clause;
		$select = 'SELECT ' . implode( ', ', $this->columns_to_select ) . $from;

		if ( ! empty( $this->group_by ) ) {
			$select .= 'GROUP BY ' . implode( ', ', $this->group_by ) . ' ';
		}

		if ( $this->order_by !== '' ) {
			$select .= 'ORDER BY ' . $this->order_by . ' ';
		}

		$select .= 'LIMIT ' . $this->limit;

		if ( $this->offset !== '' ) {
			$select .= ' OFFSET ' . $this->offset;
		}

		return $select;
	}
1044750
public function SimpleArithmeticExpression()
    {
        $terms   = [];
        $terms[] = $this->ArithmeticTerm();

        while (($isPlus = $this->lexer->isNextToken(Lexer::T_PLUS)) || $this->lexer->isNextToken(Lexer::T_MINUS)) {
            $this->match($isPlus ? Lexer::T_PLUS : Lexer::T_MINUS);

            $terms[] = $this->lexer->token['value'];
            $terms[] = $this->ArithmeticTerm();
        }

        // Phase 1 AST optimization: Prevent AST\SimpleArithmeticExpression
        // if only one AST\ArithmeticTerm is defined
        if (count($terms) === 1) {
            return $terms[0];
        }

        return new AST\SimpleArithmeticExpression($terms);
    }
672158
public function simple_search($search)
	{
		$results = explode(';', $search);

		foreach ($results as $key => $result)
		{
			$results[$key] = '(' . $result . ')';
		}

		return $this->search($results);
	}
526246
private function caseStatement($terminator) {
    static $terminators = [T_CASE, T_DEFAULT];
    if ($this->currentType === T_CASE) {
      $node = new CaseNode();
      $this->mustMatch(T_CASE, $node);
      $node->addChild($this->expr(), 'matchOn');
      if (!$this->tryMatch(':', $node, NULL, TRUE, TRUE) && !$this->tryMatch(';', $node, NULL, TRUE, TRUE)) {
        throw new ParserException(
          $this->filename,
          $this->iterator->getLineNumber(),
          $this->iterator->getColumnNumber(),
          'expected :');
      }
      if ($this->currentType !== $terminator && !in_array($this->currentType, $terminators)) {
        $this->matchHidden($node);
        $node->addChild($this->innerCaseStatementList($terminator), 'body');
      }
      return $node;
    }
    elseif ($this->currentType === T_DEFAULT) {
      $node = new DefaultNode();
      $this->mustMatch(T_DEFAULT, $node);
      if (!$this->tryMatch(':', $node, NULL, TRUE, TRUE) && !$this->tryMatch(';', $node, NULL, TRUE, TRUE)) {
        throw new ParserException(
          $this->filename,
          $this->iterator->getLineNumber(),
          $this->iterator->getColumnNumber(),
          'expected :');
      }
      if ($this->currentType !== $terminator && !in_array($this->currentType, $terminators)) {
        $this->matchHidden($node);
        $node->addChild($this->innerCaseStatementList($terminator), 'body');
      }
      return $node;
    }
    throw new ParserException(
      $this->filename,
      $this->iterator->getLineNumber(),
      $this->iterator->getColumnNumber(),
      "expected case or default");
  }
570116
public function parse_sql($sql, $as_is = false){
		if ($as_is){
			$this->fieldset = $sql;
			return;
		}

		$sql= preg_replace("/[ \n\t]+limit[\n\t ,0-9]*$/i","",$sql);
		
		$data = preg_split("/[ \n\t]+\\_from\\_/i",$sql,2);
		if (count($data)!=2)
			$data = preg_split("/[ \n\t]+from/i",$sql,2);
		$this->fieldset = preg_replace("/^[\s]*select/i","",$data[0],1);

		//Ignore next type of calls
		//direct call to stored procedure without FROM
		if ((count($data) == 1) ||
			//UNION select
			preg_match("#[ \n\r\t]union[ \n\t\r]#i", $sql)){
				$this->fieldset = $sql;
				return;
		}

	  	$table_data = preg_split("/[ \n\t]+where/i",$data[1],2);
	  	/*
		  		if sql code contains group_by we will place all sql query in the FROM 
		  		it will not allow to use any filtering against the query
		  		still it is better than just generate incorrect sql commands for any group by query
	  	*/
	  	if (sizeof($table_data)>1 && !preg_match("#.*group by.*#i",$table_data[1])){ //where construction exists
	  		$this->set_source($table_data[0]);
  			$where_data = preg_split("/[ \n\t]+order[ ]+by/i",$table_data[1],2);
  			$this->filters[]=$where_data[0];
  			if (sizeof($where_data)==1) return; //end of line detected
  			$data=$where_data[1];
  		} else { 
  			$table_data = preg_split("/[ \n\t]+order[ ]+by/i",$data[1],2);	
  			$this->set_source($table_data[0]);
  			if (sizeof($table_data)==1) return; //end of line detected
  			$data=$table_data[1];
  		}
	  	
      	if (trim($data)){ //order by construction exists
			$s_data = preg_split("/\\,/",trim($data));
			for ($i=0; $i < count($s_data); $i++) { 
				$data=preg_split("/[ ]+/",trim($s_data[$i]),2);
				if (sizeof($data)>1)
					$this->set_sort($data[0],$data[1]);
				else
					$this->set_sort($data[0]);
			}
			
		}
	}
762997
public function getDSQLExpression($expression)
    {
        if (!$this->owner->persistence || !$this->owner->persistence instanceof Persistence\SQL) {
            throw new Exception([
                'Field must have SQL persistence if it is used as part of expression',
                'persistence'=> $this->owner->persistence ?? null,
            ]);
        }

        return $this->owner->persistence->getFieldSQLExpression($this, $expression);
    }
637939
private function innerCaseStatementList($terminator) {
    static $terminators = [T_CASE, T_DEFAULT];
    $node = new StatementBlockNode();
    while ($this->currentType !== NULL && $this->currentType !== $terminator && !in_array($this->currentType, $terminators)) {
      $this->matchHidden($node);
      $node->addChild($this->innerStatement());
    }
    return $node;
  }
352580
protected function transpileNodes(AbstractSyntaxTree $ast) : string
    {
        $transpiledView = '';
        $rootNode = $ast->getRootNode();
        $previousNodeWasExpression = false;

        foreach ($rootNode->getChildren() as $childNode) {
            switch (get_class($childNode)) {
                case DirectiveNode::class:
                    $transpiledView .= $this->transpileDirectiveNode($childNode);
                    $previousNodeWasExpression = false;

                    break;
                case SanitizedTagNode::class:
                    $transpiledView .= $this->transpileSanitizedTagNode($childNode);
                    $previousNodeWasExpression = false;

                    break;
                case UnsanitizedTagNode::class:
                    $transpiledView .= $this->transpileUnsanitizedTagNode($childNode);
                    $previousNodeWasExpression = false;

                    break;
                case CommentNode::class:
                    $transpiledView .= $this->transpileCommentNode($childNode);
                    $previousNodeWasExpression = false;

                    break;
                case ExpressionNode::class:
                    // To keep expressions from running against each other, we pad all expressions but the first
                    if ($previousNodeWasExpression) {
                        $transpiledView .= ' ';
                    }

                    $transpiledView .= $this->transpileExpressionNode($childNode);
                    $previousNodeWasExpression = true;

                    break;
                default:
                    throw new RuntimeException(
                        sprintf(
                            'Unknown node class %s',
                            get_class($childNode)
                        )
                    );
            }
        }

        return $transpiledView;
    }
689276
public function walkCaseExpression($expression)
    {
        switch (true) {
            case ($expression instanceof AST\CoalesceExpression):
                return $this->walkCoalesceExpression($expression);

            case ($expression instanceof AST\NullIfExpression):
                return $this->walkNullIfExpression($expression);

            case ($expression instanceof AST\GeneralCaseExpression):
                return $this->walkGeneralCaseExpression($expression);

            case ($expression instanceof AST\SimpleCaseExpression):
                return $this->walkSimpleCaseExpression($expression);

            default:
                return '';
        }
    }
983499
public function NullIfExpression()
    {
        $this->match(Lexer::T_NULLIF);
        $this->match(Lexer::T_OPEN_PARENTHESIS);

        $firstExpression = $this->ScalarExpression();
        $this->match(Lexer::T_COMMA);
        $secondExpression = $this->ScalarExpression();

        $this->match(Lexer::T_CLOSE_PARENTHESIS);

        return new AST\NullIfExpression($firstExpression, $secondExpression);
    }
1162383
public function ScalarExpression()
    {
        $lookahead = $this->lexer->lookahead['type'];
        $peek      = $this->lexer->glimpse();

        switch (true) {
            case ($lookahead === Lexer::T_INTEGER):
            case ($lookahead === Lexer::T_FLOAT):
            // SimpleArithmeticExpression : (- u.value ) or ( + u.value )  or ( - 1 ) or ( + 1 )
            case ($lookahead === Lexer::T_MINUS):
            case ($lookahead === Lexer::T_PLUS):
                return $this->SimpleArithmeticExpression();

            case ($lookahead === Lexer::T_STRING):
                return $this->StringPrimary();

            case ($lookahead === Lexer::T_TRUE):
            case ($lookahead === Lexer::T_FALSE):
                $this->match($lookahead);

                return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token['value']);

            case ($lookahead === Lexer::T_INPUT_PARAMETER):
                switch (true) {
                     case $this->isMathOperator($peek):
                        // :param + u.value
                        return $this->SimpleArithmeticExpression();

                    default:
                        return $this->InputParameter();
                }

            case ($lookahead === Lexer::T_CASE):
            case ($lookahead === Lexer::T_COALESCE):
            case ($lookahead === Lexer::T_NULLIF):
                // Since NULLIF and COALESCE can be identified as a function,
                // we need to check these before checking for FunctionDeclaration
                return $this->CaseExpression();

            case ($lookahead === Lexer::T_OPEN_PARENTHESIS):
                return $this->SimpleArithmeticExpression();

            // this check must be done before checking for a filed path expression
            case ($this->isFunction()):
                $this->lexer->peek(); // "("

                switch (true) {
                    case ($this->isMathOperator($this->peekBeyondClosingParenthesis())):
                        // SUM(u.id) + COUNT(u.id)
                        return $this->SimpleArithmeticExpression();

                    case ($this->isAggregateFunction($this->lexer->lookahead['type'])):
                        return $this->AggregateExpression();

                    default:
                        // IDENTITY(u)
                        return $this->FunctionDeclaration();
                }

                break;
            // it is no function, so it must be a field path
            case ($lookahead === Lexer::T_IDENTIFIER):
                $this->lexer->peek(); // lookahead => '.'
                $this->lexer->peek(); // lookahead => token after '.'
                $peek = $this->lexer->peek(); // lookahead => token after the token after the '.'
                $this->lexer->resetPeek();

                if ($this->isMathOperator($peek)) {
                    return $this->SimpleArithmeticExpression();
                }

                return $this->StateFieldPathExpression();

            default:
                $this->syntaxError();
        }
    }
1078572
public function toString()
    {
        if (!$this->_parts['table']) {
            throw new SqlException("Invalid `DROP TABLE` statement, missing `TABLE` clause.");
        }

        return 'DROP TABLE' .
            $this->_buildFlag('IF EXISTS', $this->_parts['ifExists']) .
            $this->_buildChunk($this->dialect()->names($this->_parts['table'])) .
            $this->_buildFlag('CASCADE', $this->_parts['cascade']) .
            $this->_buildFlag('RESTRICT', $this->_parts['restrict']);
    }
234465
public function EntityExpression()
    {
        $glimpse = $this->lexer->glimpse();

        if ($this->lexer->isNextToken(Lexer::T_IDENTIFIER) && $glimpse['value'] === '.') {
            return $this->SingleValuedAssociationPathExpression();
        }

        return $this->SimpleEntityExpression();
    }
920944
public function SimpleConditionalExpression()
    {
        if ($this->lexer->isNextToken(Lexer::T_EXISTS)) {
            return $this->ExistsExpression();
        }

        $token     = $this->lexer->lookahead;
        $peek      = $this->lexer->glimpse();
        $lookahead = $token;

        if ($this->lexer->isNextToken(Lexer::T_NOT)) {
            $token = $this->lexer->glimpse();
        }

        if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER || $this->isFunction()) {
            // Peek beyond the matching closing parenthesis.
            $beyond = $this->lexer->peek();

            switch ($peek['value']) {
                case '(':
                    // Peeks beyond the matched closing parenthesis.
                    $token = $this->peekBeyondClosingParenthesis(false);

                    if ($token['type'] === Lexer::T_NOT) {
                        $token = $this->lexer->peek();
                    }

                    if ($token['type'] === Lexer::T_IS) {
                        $lookahead = $this->lexer->peek();
                    }
                    break;

                default:
                    // Peek beyond the PathExpression or InputParameter.
                    $token = $beyond;

                    while ($token['value'] === '.') {
                        $this->lexer->peek();

                        $token = $this->lexer->peek();
                    }

                    // Also peek beyond a NOT if there is one.
                    if ($token['type'] === Lexer::T_NOT) {
                        $token = $this->lexer->peek();
                    }

                    // We need to go even further in case of IS (differentiate between NULL and EMPTY)
                    $lookahead = $this->lexer->peek();
            }

            // Also peek beyond a NOT if there is one.
            if ($lookahead['type'] === Lexer::T_NOT) {
                $lookahead = $this->lexer->peek();
            }

            $this->lexer->resetPeek();
        }

        if ($token['type'] === Lexer::T_BETWEEN) {
            return $this->BetweenExpression();
        }

        if ($token['type'] === Lexer::T_LIKE) {
            return $this->LikeExpression();
        }

        if ($token['type'] === Lexer::T_IN) {
            return $this->InExpression();
        }

        if ($token['type'] === Lexer::T_INSTANCE) {
            return $this->InstanceOfExpression();
        }

        if ($token['type'] === Lexer::T_MEMBER) {
            return $this->CollectionMemberExpression();
        }

        if ($token['type'] === Lexer::T_IS && $lookahead['type'] === Lexer::T_NULL) {
            return $this->NullComparisonExpression();
        }

        if ($token['type'] === Lexer::T_IS && $lookahead['type'] === Lexer::T_EMPTY) {
            return $this->EmptyCollectionComparisonExpression();
        }

        return $this->ComparisonExpression();
    }