public function whereIn($column, $values, bool $not = false, string $appendRule = 'AND'): self
    {
        $column = $this->checkStringValue('Argument $column', $column);

        if (
            !is_array($values) &&
            !($values instanceof \Closure) &&
            !($values instanceof Query) &&
            !($values instanceof StatementInterface)
        ) {
            return $this->handleException(InvalidArgumentException::create(
                'The IN value',
                $values,
                ['array', \Closure::class, Query::class, StatementInterface::class, 'null']
            ));
        }

        if (is_array($values)) {
            foreach ($values as $index => &$value) {
                $value = $this->checkScalarOrNullValue('Argument $values['.$index.']', $value);
            }
        } elseif ($values instanceof \Closure) {
            $values = $this->resolveSubQueryClosure($values);
        }

        $this->where[] = new InCriterion($column, $values, $not, $appendRule);
        return $this;
    }