When field is used as expression, this method will be called.
Universal way to convert ourselves to expression. Off-load implementation into persistence.

@param Expression $expression

@return Expression
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);
    }
285933
public function removeExpression($expression)
    {
        if ($this->expressions->contains($expression)) {
            $this->expressions->removeElement($expression);
        }

        return $this;
    }
1297854
public function orWhere(Expression $expression) : self
    {
        if ($this->expression === null) {
            return $this->where($expression);
        }

        $this->expression = new CompositeExpression(
            CompositeExpression::TYPE_OR,
            [$this->expression, $expression]
        );

        return $this;
    }
1230977
public function setExpression($expression)
    {
        $definitions = array(
            '@yearly' => '0 0 1 1 *',
            '@annually' => '0 0 1 1 *',
            '@monthly' => '0 0 1 * *',
            '@weekly' => '0 0 * * 0',
            '@daily' => '0 0 * * *',
            '@hourly' => '0 * * * *'
        );

        if (isset($definitions[$expression])) {
            $expression = $definitions[$expression];
        }

        $expressionParts = explode(' ', $expression);

        if (count($expressionParts) < 5 || count($expressionParts) > 6) {
            throw new \InvalidArgumentException(sprintf('%s is not a valid CRON expression.', $expression));
        }

        $this->expression = $expression;
        $this->fields = array();

        foreach ($expressionParts as $position => $value) {
            $this->fields[$position] = $this->getField($position, $value);
        }
    }
505672
public function addSelectExpression(string ...$expression) : self
    {
        $this->selectExpressions = array_merge($this->selectExpressions, $expression);

        return $this;
    }
509783
public static Expression createExpression(String expression) {
        try {
            return INSTANCE.ctorExpression.newInstance(expression);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
687632
public function addOperator($expression) {
        /**
         * SELECT DISTINCT subject FROM statements WHERE
         */
        $this->query .= '(' .
                $this->getDriverEscaper()->dbCommand('SELECT') . ' ' .
                $this->getDriverEscaper()->dbCommand('DISTINCT') . ' ' .
                $this->getDriverEscaper()->reserved('subject') . ' ' .
                $this->getDriverEscaper()->dbCommand('FROM') . ' ' .
                $this->getDriverEscaper()->reserved($this->options['table']) . ' ' .
                $this->getDriverEscaper()->dbCommand('WHERE') .
                $this->operationSeparator .
                $this->userLanguage . ' ' . $expression;

        if (!empty($this->model)) {
            $this->query .=  $this->getDriverEscaper()->dbCommand('AND') . ' '.
                $this->getDriverEscaper()->reserved('modelid') . ' '.
                $this->getDriverEscaper()->dbCommand('IN') . ' '.
                '(' . implode(',', $this->model->getReadableModels()) . ')'.
                $this->operationSeparator ;
        }
        $this->query .= ' )'.')';

        $this->predicateLoop ++;

        return $this;
    }
494717
private function ensureArray($expression)
    {
        if (is_string($expression) && substr($expression, 0, 1) === '$') {
            return '$' . $this->getDocumentPersister()->prepareFieldName(substr($expression, 1));
        } elseif (is_array($expression)) {
            return array_map([$this, 'ensureArray'], $expression);
        } elseif ($expression instanceof self) {
            return $expression->getExpression();
        }

        // Convert PHP types to MongoDB types for everything else
        return Type::convertPHPToDatabaseValue($expression);
    }
1221886
protected function _transformFunctionExpression(FunctionExpression $expression)
    {
        switch ($expression->getName()) {
            case 'CONCAT':
                // CONCAT function is expressed as exp1 + exp2
                $expression->setName('')->setConjunction(' +');
                break;
            case 'DATEDIFF':
                $hasDay = false;
                $visitor = function ($value) use (&$hasDay) {
                    if ($value === 'day') {
                        $hasDay = true;
                    }

                    return $value;
                };
                $expression->iterateParts($visitor);

                if (!$hasDay) {
                    $expression->add(['day' => 'literal'], [], true);
                }
                break;
            case 'CURRENT_DATE':
                $time = new FunctionExpression('GETUTCDATE');
                $expression->setName('CONVERT')->add(['date' => 'literal', $time]);
                break;
            case 'CURRENT_TIME':
                $time = new FunctionExpression('GETUTCDATE');
                $expression->setName('CONVERT')->add(['time' => 'literal', $time]);
                break;
            case 'NOW':
                $expression->setName('GETUTCDATE');
                break;
            case 'EXTRACT':
                $expression->setName('DATEPART')->setConjunction(' ,');
                break;
            case 'DATE_ADD':
                $params = [];
                $visitor = function ($p, $key) use (&$params) {
                    if ($key === 0) {
                        $params[2] = $p;
                    } else {
                        $valueUnit = explode(' ', $p);
                        $params[0] = rtrim($valueUnit[1], 's');
                        $params[1] = $valueUnit[0];
                    }

                    return $p;
                };
                $manipulator = function ($p, $key) use (&$params) {
                    return $params[$key];
                };

                $expression
                    ->setName('DATEADD')
                    ->setConjunction(',')
                    ->iterateParts($visitor)
                    ->iterateParts($manipulator)
                    ->add([$params[2] => 'literal']);
                break;
            case 'DAYOFWEEK':
                $expression
                    ->setName('DATEPART')
                    ->setConjunction(' ')
                    ->add(['weekday, ' => 'literal'], [], true);
                break;
            case 'SUBSTR':
                $expression->setName('SUBSTRING');
                if (count($expression) < 4) {
                    $params = [];
                    $expression
                        ->iterateParts(function ($p) use (&$params) {
                            return $params[] = $p;
                        })
                        ->add([new FunctionExpression('LEN', [$params[0]]), ['string']]);
                }

                break;
        }
    }
76751
public function setExpression($expression)
    {
        if (is_string($expression)) {
            $expression = CronExpression::factory($expression);
        }

        $this->expression = $expression;

        return $this;
    }
129893
public function addAnd($expression)
    {
        $this->query['$and'][] = $expression instanceof Expr ? $expression->getQuery() : $expression;
        return $this;
    }
665317
public static function parse(string $expression): string
    {
        $expression = \trim($expression);

        if ($expression === '' || \is_numeric($expression)) {
            return $expression;
        }

        if (!isset(self::$cache[$expression])) {
            $tree = self::treeStruct($expression);
            self::$cache[$expression] = self::transform($tree);
        }

        return self::$cache[$expression];
    }
1098537
public function addOperator($expression)
    {
       $this->query .= '( ' . $this->getDriverEscaper()->reserved('subject') . ' ' . 
               $this->getDriverEscaper()->dbCommand('IN') . 
               $this->operationSeparator .'(' . 
               $this->getDriverEscaper()->dbCommand('SELECT') . ' ' . 
               $this->getDriverEscaper()->dbCommand('DISTINCT') . ' ' . 
               $this->getDriverEscaper()->reserved('subject') . ' ' .
               $this->getDriverEscaper()->dbCommand('FROM') .' ' . 
               $this->getDriverEscaper()->reserved($this->options['table']) . ' ' .
               $this->getDriverEscaper()->dbCommand('WHERE') . 
               $this->operationSeparator . $this->language . 
               $this->operationSeparator .$expression . ')' .
               ')';
       return $this;
    }
1056895
private function operator(string $operator, $expression) : self
    {
        if ($this->currentField) {
            $this->expr[$this->currentField][$operator] = $this->ensureArray($expression);
        } else {
            $this->expr[$operator] = $this->ensureArray($expression);
        }

        return $this;
    }
988346
public function match($expression)
    {
        if (is_callable($expression)) {
            $expressionConfigurator = $expression;
            $expression = new Expression();
            call_user_func($expressionConfigurator, $expression);
        }

        if ($expression instanceof Expression) {
            $expression = $expression->toArray();
        } elseif (!is_array($expression)) {
            throw new Exception('Must be array, callable or instance of \Sokil\Mongo\Expression');
        }

        $this->addStage('$match', $expression);
        return $this;
    }
1298556
public function onPropertyAccessExpression($expression)
    {
        $parent = $expression;
        $variable = null;
        do {
            $variable = $parent->getResourceProperty()->getName() . self::MEMBER_ACCESS . $variable;
            $parent = $parent->getParent();
        } while ($parent != null);
        $variable = rtrim($variable, self::MEMBER_ACCESS);
        $variable = $this->getIteratorName() . self::MEMBER_ACCESS . $variable;
        return $variable;
    }
345355
public function remove(ExpressionContract $expression)
    {
        $this->checkType($expression);
        unset($this->constraints[$expression->name()]);
        return $this;
    }