public function getQuery(): Query
    {
        $bindings = new Bindings();

        if (count($this->data) == 0 && $this->select === null) {
            throw new Exception('Can not execute Insert query, no records to insert');
        }

        if ($this->table === null) {
            throw new Exception('Can not execute Insert query when table name is not set');
        }

        $hasFields = count($this->fields) > 0;

        $query = "INSERT INTO {$this->table}";

        if ($hasFields) {
            $query .= ' (';

            foreach ($this->fields as $field) {
                $query .= $field . ',';
            }

            $query = substr($query, 0, -1) . ')';
        }

        if ($this->select !== null) {
            if ($this->select instanceof Select || $this->select instanceof Query) {
                $query .= "\n(\n\t" . str_replace("\n", "\n\t", $this->select->__toString()) . "\n)";
                $bindings->addBindingsFromInstance($this->select->getBindings());
            } else {
                throw new Exception('Can not use non-Select or non-Query instance in INSERT INTO SELECT statement - use Query instance to pass Select query');
            }
        } else {
            $query .= "\nVALUES\n";
            foreach ($this->data as $i1 => $row) {
                $query .= "\t(";

                if ($hasFields) {

                    foreach ($this->fields as $field) {
                        if (isset($row[$field])) {
                            $val = $row[$field];

                            if ($val instanceof Expr) {
                                $query .= "{$val},";
                            } else {
                                //$key = 'i' . $i1 . Query::getKeyIndex();
	                            $key = $bindings->makeAndSet("i{$i1}", $val);
                                $query .= ":{$key},";
                            }
                        } else {
                            $query .= 'NULL,';
                        }
                    }

                    $query = substr($query, 0, -1);

                } else {
                    $values = array_values($row);

                    foreach ($values as $i2 => $val) {
                        if ($val instanceof Expr) {
                            $query .= "{$val},";
                        } else {
                            //$key = 'i' . $i2 . Query::getKeyIndex();
	                        $key = $bindings->makeAndSet("i{$i2}", $val);
                            $query .= ":{$key},";
                        }
                    }

                    $query = substr($query, 0, -1);
                }

                $query .= "),\n";
            }

            $query = substr($query, 0, -2);
        }

        return new Query($query, $bindings, $this->getAdapterConnection());
    }