public function addField($field, $their_field = null) : Field_SQL_Expression
    {
        if (is_array($field)) {
            $defaults = $field;
            if (!isset($defaults[0])) {
                throw new Exception([
                    'Field name must be specified',
                    'field' => $field,
                ]);
            }
            $field = $defaults[0];
            unset($defaults[0]);
        } else {
            $defaults = [];
        }

        if ($their_field === null) {
            $their_field = $field;
        }

        $e = $this->owner->addExpression($field, array_merge([
            function ($m) use ($their_field) {
                // remove order if we just select one field from hasOne model
                // that is mandatory for Oracle
                return $m->refLink($this->link)->action('field', [$their_field])->reset('order');
            }, ],
            $defaults
        ));

        $e->read_only = false;
        $e->never_save = true;

        // Will try to execute last
        $this->owner->addHook('beforeSave', function ($m) use ($field, $their_field) {
            // if title field is changed, but reference ID field (our_field)
            // is not changed, then update reference ID field value
            if ($m->isDirty($field) && !$m->isDirty($this->our_field)) {
                $mm = $this->getModel();

                $mm->addCondition($their_field, $m[$field]);
                $m[$this->our_field] = $mm->action('field', [$mm->id_field]);
                unset($m[$field]);
            }
        }, null, 21);

        return $e;
    }