-
-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Base refresh materialized view #800
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -424,4 +424,15 @@ public function renameTable(string $oldName, string $newName): string; | |||||
* Note: The method will quote the `table` parameter before using it in the generated SQL. | ||||||
*/ | ||||||
public function truncateTable(string $table): string; | ||||||
|
||||||
/** | ||||||
* Refresh materialized view | ||||||
* | ||||||
* @param string $viewName The name of the view to refresh. | ||||||
* @param bool $concurrently Refresh the materialized view without locking out concurrent selects on the materialized view. | ||||||
* @param bool|null $withData When `true` then the backing query is executed to provide the new data. Otherwise if `false` then no new data is generated and the materialized view is left in an unscannable state | ||||||
* | ||||||
* @return string The `REFRESH MATERIALIZED VIEW` SQL statement | ||||||
*/ | ||||||
public function refreshMaterializedView(string $viewName, bool $concurrently = false, ?bool $withData = null): string; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Not sure the argument |
||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -727,4 +727,48 @@ public function testProfilerData(string $sql = null): void | |
); | ||
parent::testProfilerData(); | ||
} | ||
|
||
public static function refreshMaterializedViewDataProvider(): array | ||
{ | ||
return [ | ||
[ | ||
'default_mt', | ||
null, | ||
null, | ||
], | ||
[ | ||
'concurrently_mt', | ||
true, | ||
null, | ||
], | ||
[ | ||
'concurrently_with_data_mt', | ||
true, | ||
true, | ||
], | ||
[ | ||
'concurrently_without_data_mt', | ||
true, | ||
false, | ||
], | ||
]; | ||
} | ||
Comment on lines
+731
to
+755
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
|
||
/** | ||
* @dataProvider refreshMaterializedViewDataProvider | ||
* @param string $viewName | ||
* @param bool|null $concurrently | ||
* @param bool|null $withData | ||
* @return void | ||
* @throws \Yiisoft\Db\Exception\Exception | ||
* @throws \Yiisoft\Db\Exception\InvalidConfigException | ||
*/ | ||
public function testRefreshMaterializedView(string $viewName, ?bool $concurrently, ?bool $withData): void | ||
{ | ||
$db = $this->getConnection(); | ||
$this->expectException(NotSupportedException::class); | ||
|
||
$db->createCommand()->refreshMaterializedView($viewName, $concurrently, $withData); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -178,7 +178,7 @@ public function testGetExpressionBuilderException(): void | |||||||
|
||||||||
$this->expectException(Exception::class); | ||||||||
|
||||||||
$expression = new class () implements ExpressionInterface { | ||||||||
$expression = new class() implements ExpressionInterface { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||
}; | ||||||||
$qb = $db->getQueryBuilder(); | ||||||||
$qb->getExpressionBuilder($expression); | ||||||||
|
@@ -310,4 +310,64 @@ public function testUpsertExecute( | |||||||
$actualParams = []; | ||||||||
$actualSQL = $db->getQueryBuilder()->upsert($table, $insertColumns, $updateColumns, $actualParams); | ||||||||
} | ||||||||
|
||||||||
|
||||||||
public static function refreshMaterializedViewDataProvider(): array | ||||||||
{ | ||||||||
return [ | ||||||||
[ | ||||||||
'concurrently_mt', | ||||||||
true, | ||||||||
null, | ||||||||
'REFRESH MATERIALIZED VIEW CONCURRENTLY [[concurrently_mt]]', | ||||||||
], | ||||||||
[ | ||||||||
'concurrently_with_data_mt', | ||||||||
true, | ||||||||
true, | ||||||||
'REFRESH MATERIALIZED VIEW CONCURRENTLY [[concurrently_with_data_mt]] WITH DATA', | ||||||||
], | ||||||||
[ | ||||||||
'concurrently_without_data_mt', | ||||||||
true, | ||||||||
false, | ||||||||
'REFRESH MATERIALIZED VIEW CONCURRENTLY [[concurrently_without_data_mt]] WITH NO DATA', | ||||||||
], | ||||||||
[ | ||||||||
'not_concurrently_mt', | ||||||||
false, | ||||||||
null, | ||||||||
'REFRESH MATERIALIZED VIEW [[not_concurrently_mt]]', | ||||||||
], | ||||||||
[ | ||||||||
'not_concurrently_with_data_mt', | ||||||||
false, | ||||||||
true, | ||||||||
'REFRESH MATERIALIZED VIEW [[not_concurrently_with_data_mt]] WITH DATA', | ||||||||
], | ||||||||
[ | ||||||||
'not_concurrently_without_data_mt', | ||||||||
false, | ||||||||
false, | ||||||||
'REFRESH MATERIALIZED VIEW [[not_concurrently_without_data_mt]] WITH NO DATA', | ||||||||
], | ||||||||
]; | ||||||||
} | ||||||||
Comment on lines
+315
to
+355
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to move it to |
||||||||
|
||||||||
/** | ||||||||
* @dataProvider refreshMaterializedViewDataProvider | ||||||||
* @param bool $concurrently | ||||||||
* @param bool|null $withData | ||||||||
* @return void | ||||||||
*/ | ||||||||
public function testRefreshMaterializedView(string $viewName, bool $concurrently, ?bool $withData, string $expected): void | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks need to move this test to |
||||||||
{ | ||||||||
$db = $this->getConnection(); | ||||||||
$driver = $db->getDriverName(); | ||||||||
$sql = $db->getQueryBuilder()->refreshMaterializedView($viewName, $concurrently, $withData); | ||||||||
$actual = DbHelper::replaceQuotes($sql, $driver); | ||||||||
Comment on lines
+367
to
+368
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Result from |
||||||||
$expected = DbHelper::replaceQuotes($expected, $driver); | ||||||||
|
||||||||
$this->assertSame($expected, $actual); | ||||||||
} | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the interface is different from
DDLQueryBuilderInterface::refreshMaterializedView()
?Looks like should be the same.
When execute
$command->refreshMaterializedView($viewName);
expect this is not concurently.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I see in MS SQL / Oracle / Clickhouse docs:
WITH [NO] DATA
is PostgreSQL only option and pretty much useless one.REFRESH
exists only on PG and Oracle. MS SQL and Clickhouse do automatic updates, so their implementations should always returntrue
.There are a lot of variants in Oracle: 3 commands (
REFRESH
,REFREASH_ALL_MVIEWS
,REFRESH_DEPENDENT
) and at least 6 options. Optionout_of_place
seems to be equivalent of CONCURRENTLY in PostgreSQL.So, the most common part is refresh + option for non-blocking update, but it will be very hard to take full advantage of database capabilities like Oracle's refresh method.