-
Notifications
You must be signed in to change notification settings - Fork 213
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
[Oracle] Sqitch does not detect missing schema #668
Comments
Odd. Can you apply this patch, try again, and send me the output? --- a/lib/App/Sqitch/Command/deploy.pm
+++ b/lib/App/Sqitch/Command/deploy.pm
@@ -114,6 +114,7 @@ sub execute {
# Warn on multiple targets.
my $target = shift @{ $targets };
+ say 'Registry: ', $target->registry;
$self->warn(__x(
'Too many targets specified; connecting to {target}',
target => $target->name, |
with
|
Oh interesting! |
Oh I see what's happening. Sqitch attempts to set the schema path on connect, but doesn't fail if the schema doesn't exist, on the assumption that it will be created and set on the first deploy. sqitch/lib/App/Sqitch/Engine/oracle.pm Lines 112 to 118 in f2fb8f8
And since you're not doing a deploy, it just defaults to the current schema. It seems as though you previously used the same schema for your own database object and for Sqitch, yes? This usually doesn't fail because the ideal is to use a separate schema for the registry, and you don't specify (or default to) the registry for your target. So my short answer is "don't use your own schema for the registry". The longer response is…I'm not sure this is something that'd be easy to change. |
Hmm, in Oracle at least I wouldn't expect Sqitch to automatically create the registry schema. That is because in Oracle there is an isomorphism between schemas and users, and to me creating users is something that shouldn't be done implicitly. Do we rely on this error-swallowing functionality? |
Yep: sqitch/lib/App/Sqitch/Engine/oracle.pm Lines 112 to 118 in ef7767d
It gets created here: sqitch/lib/App/Sqitch/Engine/oracle.pm Lines 461 to 464 in ef7767d
But the Oracle registry script doesn't create the schema (user). Instead, according to the tutorial, it just uses the current schema. From the tutorial:
|
I just worked through it all again, committing 8be3608 to improve the consistency of handling the registry username. But I still can't work out how this is happening, unless it's not capturing some errors somewhere. Would you try again with this patch, please? --- a/lib/App/Sqitch/Engine/oracle.pm
+++ b/lib/App/Sqitch/Engine/oracle.pm
@@ -459,8 +459,11 @@ sub initialize {
# Load up our database.
(my $file = file(__FILE__)->dir->file('oracle.sql')) =~ s/"/""/g;
+ say "Initialize $schema";
$self->_run_with_verbosity($file);
+ say "Set session to $schema";
$self->dbh->do("ALTER SESSION SET CURRENT_SCHEMA = $schema") if $schema;
+ say "Register release in $schema";
$self->_register_release;
}
@@ -742,6 +745,7 @@ sub _script {
sub _run {
my $self = shift;
my $script = $self->_script(@_);
+ say "Run $script";
open my $fh, '<:utf8_strict', \$script;
return $self->sqitch->spool( $fh, $self->sqlplus );
}
@@ -749,6 +753,7 @@ sub _run {
sub _capture {
my $self = shift;
my $conn = $self->_script(@_);
+ say "Capture $conn";
my @out;
require IPC::Run3; |
So, this might be frustrating, but that patch does not result in any extra output. Presumably because Sqitch does not detect that schema initialization is needed? |
No output at all? Weird. What happens if you try to print the schema name in |
Okay so I dug into this a bit today and there is an extra condition required to trigger the behavior documented above. I would amend the "steps to reproduce" above as follows:
What happens is that we query the |
IIRC, it currently defaults to the current database if the |
Instead of ignoring them, record when the schema can't be added to the search path. Then use that value to avoid querying the database in `_sync_plan`. This prevents Sqitch from finding a valid project record when the search path contains a valid changes table and record for the project, which can happen when one starts using the current schema for the registry (the default on Oracle) and then tries to use a new registry. Resolves #668. To best make use of the new `_no_registry` attribute of Engine, rename the `initialized()` method to `_initialized()` and add a new `initialized()` method to check it before calling the engine-specific `_initialized()` method. Also rename the `initialize()` method to `_initialize()` and provide an `initialize()` implementation that sets `_no_registry` to false after a successful call to the engine-specific `_initialize()` method. Update the DBI `connected` callbacks to return anytime `$dbh->do` returns false, thereby always propagating errors. Previously errors were ignored in MySQL and Snowflake (and we had an invalid warehouse name in the tests that needed fixing!). For search path errors, call the new DBIEngine role `_handle_no_registry` method, which sets `_no_registry` to true and discards the error so that the DBI won't throw it once the callback function returns. Since the error handling is boolean-based, here, and the error handler is never called from inside the callback, remove the `try {}` block. It wasn't doing anything. While at it, require DBI 1.631 to ensure consistent behavior of error handling in callbacks and to eliminate a workaround for older versions in the mysql engine.
#762 should fix the issue. It detects when the registry schema does not exist at connection time, and doesn't bother to call |
This seems reasonable, but maybe there is one more case that slipped through the cracks? What if:
It seems like in this case we will check if the registry schema exists but then still end up querying the default schema instead. What do you think? |
Ugh, yeah, that's quite the edge case, but a very real possibility. The only solution I can think of offhand is to schema-qualify the |
Him, the docs suggest that |
Steps to reproduce:
Expected behavior:
Actual behavior:
The text was updated successfully, but these errors were encountered: