From cff24d613201af5a539456345cdb3c08f2f7ba74 Mon Sep 17 00:00:00 2001 From: Merlijn Buit Date: Fri, 21 May 2021 17:23:43 +0200 Subject: [PATCH 1/3] 2 bugfixes --- src/Database/RedshiftConnection.php | 52 ++--- .../Schema/Grammars/RedshiftGrammar.php | 205 ++++++++++-------- 2 files changed, 136 insertions(+), 121 deletions(-) diff --git a/src/Database/RedshiftConnection.php b/src/Database/RedshiftConnection.php index 5c95dd6..e54bead 100644 --- a/src/Database/RedshiftConnection.php +++ b/src/Database/RedshiftConnection.php @@ -1,4 +1,5 @@ withTablePrefix(new QueryGrammar); + protected function getDefaultQueryGrammar() + { + return $this->withTablePrefix(new QueryGrammar); + } + + public function getSchemaBuilder() + { + if (is_null($this->schemaGrammar)) { + $this->useDefaultSchemaGrammar(); } - public function getSchemaBuilder() - { - if (is_null($this->schemaGrammar)) { - $this->useDefaultSchemaGrammar(); - } - - return new RedshiftBuilder($this); - } + return new RedshiftBuilder($this); + } - protected function getDefaultSchemaGrammar() - { - return $this->withTablePrefix(new SchemaGrammar); - } + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } - public function getSchemaState(Filesystem $files = null, callable $processFactory = null) - { - return new RedshiftSchemaState($this, $files, $processFactory); - } - - protected function getDefaultPostProcessor() - { - return new RedshiftProcessor; - } + public function getSchemaState(Filesystem $files = null, callable $processFactory = null) + { + return new RedshiftSchemaState($this, $files, $processFactory); + } -} \ No newline at end of file + protected function getDefaultPostProcessor() + { + return new RedshiftProcessor; + } +} diff --git a/src/Database/Schema/Grammars/RedshiftGrammar.php b/src/Database/Schema/Grammars/RedshiftGrammar.php index 85f0a93..f3ee378 100644 --- a/src/Database/Schema/Grammars/RedshiftGrammar.php +++ b/src/Database/Schema/Grammars/RedshiftGrammar.php @@ -1,4 +1,5 @@ getAddedColumns() as $column) { - $sql = $this->wrap($column).' '.$this->getType($column); + protected function getColumns(Blueprint $blueprint) + { + $columns = []; - /** - * Add Redshift-specific encoding settings - */ - if ($encode = $this->getEncode($column)) { - $sql .= ' '.$encode; - } + foreach ($blueprint->getAddedColumns() as $column) { + $sql = $this->wrap($column) . ' ' . $this->getType($column); - $columns[] = $this->addModifiers($sql, $blueprint, $column); - } + /** + * Add Redshift-specific encoding settings + */ + if ($encode = $this->getEncode($column)) { + $sql .= ' ' . $encode; + } - return $columns; + $columns[] = $this->addModifiers($sql, $blueprint, $column); } - protected function getEncode(Fluent $column) { - return $column->encode !== null ? 'encode '.$column->encode : null; + return $columns; + } + + protected function getEncode(Fluent $column) + { + return $column->encode !== null ? 'encode ' . $column->encode : null; + } + + protected function generatableColumn($type, Fluent $column) + { + if (!$column->autoIncrement && is_null($column->generatedAs)) { + return $type; } - protected function generatableColumn($type, Fluent $column) - { - if (! $column->autoIncrement && is_null($column->generatedAs)) { - return $type; - } - - if ($column->autoIncrement && is_null($column->generatedAs)) { - return with([ - 'integer' => 'INTEGER', - 'bigint' => 'BIGINT', - 'smallint' => 'SMALLINT', - ])[$type]; - } - - return parent::generatableColumn($type, $column); + if ($column->autoIncrement && is_null($column->generatedAs)) { + return with([ + 'integer' => 'INTEGER', + 'bigint' => 'BIGINT', + 'smallint' => 'SMALLINT', + ])[$type]; } - protected function typeTimestamp(Fluent $column) - { - $columnType = 'timestamp without time zone'; + return parent::generatableColumn($type, $column); + } - return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType; - } + protected function typeTimestamp(Fluent $column) + { + $columnType = 'timestamp without time zone'; - protected function modifyIncrement(Blueprint $blueprint, Fluent $column) - { - if ((in_array($column->type, $this->serials) || ($column->generatedAs !== null)) && $column->autoIncrement) { - return ' identity(1,1)'; - } - } + return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType; + } - public function compileCreate(Blueprint $blueprint, Fluent $command) - { - return array_values(array_filter(array_merge([sprintf('%s table %s (%s)', - $blueprint->temporary ? 'create temporary' : 'create', - $this->wrapTable($blueprint), - implode(', ', $this->getColumns($blueprint)), - )], - $this->compileAlter($blueprint) - ))); + protected function modifyIncrement(Blueprint $blueprint, Fluent $column) + { + if ((in_array($column->type, $this->serials) || ($column->generatedAs !== null)) && $column->autoIncrement) { + return ' identity(1,1)'; } - - protected function compileAlter(Blueprint $blueprint) - { - $distKey = $this->compileDistKey($blueprint); - $sortKey = $this->compileSortKey($blueprint); - $keys = collect([ $distKey, $sortKey ])->flatten()->filter()->values(); - - return $keys->map(function($key) use($blueprint) { - return sprintf('alter table %s %s', $blueprint->getTable(), $key); + } + + public function compileCreate(Blueprint $blueprint, Fluent $command) + { + return array_values(array_filter(array_merge( + [sprintf( + '%s table %s (%s)', + $blueprint->temporary ? 'create temporary' : 'create', + $this->wrapTable($blueprint), + implode(', ', $this->getColumns($blueprint)), + )], + $this->compileAlter($blueprint) + ))); + } + + protected function compileAlter(Blueprint $blueprint) + { + $distKey = $this->compileDistKey($blueprint); + $sortKey = $this->compileSortKey($blueprint); + $keys = collect([$distKey, $sortKey])->flatten()->filter()->values(); + + return $keys->map(function ($key) use ($blueprint) { + return sprintf('alter table %s %s', $blueprint->getTable(), $key); + }) + ->values()->all(); + } + + protected function compileSortKey(Blueprint $blueprint) + { + if ($values = $blueprint->sortKeyValues()) { + return sprintf( + 'alter compound sortkey (%s)', + collect($values)->sort()->keys()->map(function ($value) { + return '"' . $value . '"'; }) - ->values()->all(); + ->join(', ') + ); } - - protected function compileSortKey(Blueprint $blueprint) - { - if ($values = $blueprint->sortKeyValues()) { - return sprintf('alter compound sortkey (%s)', - collect($values)->sort()->keys()->map(function($value) { - return '"' . $value . '"'; - }) - ->join(', ')); - } - return null; + return null; + } + + protected function compileDistKey(Blueprint $blueprint) + { + if ($distKeyColumn = $blueprint->distKeyValue()) { + $distKeyColumn = collect($distKeyColumn); + + switch ($distKeyColumn[0]) { + case 'key': + return sprintf('alter diststyle key distkey %s', $distKeyColumn[1]); + case 'all': + case 'auto': + case 'even': + return sprintf('alter diststyle %s', $distKeyColumn[0]); + default: + throw new LaravelRedshiftException(sprintf('Dist key name "%s" is not supported.', $distKeyColumn[0])); + } } - - protected function compileDistKey(Blueprint $blueprint) - { - if ($distKeyColumn = $blueprint->distKeyValue()) { - $distKeyColumn = collect($distKeyColumn); - - switch ($distKeyColumn[0]) { - case 'key': - return sprintf('alter diststyle key distkey %s', $distKeyColumn[1]); - case 'all': - case 'auto': - case 'even': - return sprintf('alter diststyle %s', $distKeyColumn[0]); - default: - throw new LaravelRedshiftException(sprintf('Dist key name "%s" is not supported.', $distKeyColumn[0])); - - } - } - return null; - } - -} \ No newline at end of file + return null; + } + + /** + * Create the column definition for a uuid type. + * + * @param \Illuminate\Support\Fluent $column + * @return string + */ + protected function typeUuid(Fluent $column) + { + return 'char(36)'; + } +} From af532c9b6448866a3988a96c73dcabfa96ca103b Mon Sep 17 00:00:00 2001 From: Nico van Zijl Date: Thu, 13 Jul 2023 15:35:51 +0200 Subject: [PATCH 2/3] bump illuminate --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5558f86..085a9d7 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ "homepage": "https://github.com/yuk1/laravel-redshift", "keywords": ["Laravel", "Redshift"], "require": { - "illuminate/support": "~7|~8" + "illuminate/support": ">= 7.0" }, "require-dev": { "phpunit/phpunit": "~9.0", From be8bba811c50f8af75ff38b2c404adb74de34ee0 Mon Sep 17 00:00:00 2001 From: Nico van Zijl Date: Thu, 13 Jul 2023 23:13:22 +0200 Subject: [PATCH 3/3] Fixed InsertGetId for redshift. --- .../Query/Grammars/RedshiftGrammar.php | 17 +++++++++++-- .../Query/Processors/RedshiftProcessor.php | 24 ++++++++++++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/Database/Query/Grammars/RedshiftGrammar.php b/src/Database/Query/Grammars/RedshiftGrammar.php index 6b4f650..acf2134 100644 --- a/src/Database/Query/Grammars/RedshiftGrammar.php +++ b/src/Database/Query/Grammars/RedshiftGrammar.php @@ -2,8 +2,21 @@ namespace YuK1\LaravelRedshift\Database\Query\Grammars; use Illuminate\Database\Query\Grammars\PostgresGrammar; +use Illuminate\Database\Query\Builder; class RedshiftGrammar extends PostgresGrammar { - -} \ No newline at end of file + /** + * Compile insert statement. + * Unlike PostgreSQL, in Redshift it is not possible to return the id at the same time + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $values + * @param string $sequence + * @return string + */ + public function compileInsertGetId(Builder $query, $values, $sequence) + { + return $this->compileInsert($query, $values); + } +} diff --git a/src/Database/Query/Processors/RedshiftProcessor.php b/src/Database/Query/Processors/RedshiftProcessor.php index ee0024c..99f4b95 100644 --- a/src/Database/Query/Processors/RedshiftProcessor.php +++ b/src/Database/Query/Processors/RedshiftProcessor.php @@ -2,8 +2,30 @@ namespace YuK1\LaravelRedshift\Database\Query\Processors; use Illuminate\Database\Query\Processors\PostgresProcessor; +use Illuminate\Database\Query\Builder; class RedshiftProcessor extends PostgresProcessor { + /** + * Process an "insert get ID" query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param string $sql + * @param array $values + * @param string|null $sequence + * @return int + */ + public function processInsertGetId(Builder $query, $sql, $values, $sequence = null) + { + $connection = $query->getConnection(); -} \ No newline at end of file + $connection->insert($sql, $values); + + $idColumn = $sequence ?: 'id'; + $wrappedTable = $query->getGrammar()->wrapTable($query->from); + $result = $connection->selectOne('select max('. $idColumn .') from '.$wrappedTable); + $id = array_values((array) $result)[0]; + + return is_numeric($id) ? (int) $id : $id; + } +}