|
| 1 | +[#ref-schema-support] |
| 2 | +=== Schema support |
| 3 | + |
| 4 | +[.since]_Jaybird 7_ + |
| 5 | +[.since]_Firebird 6.0_ |
| 6 | + |
| 7 | +Firebird 6.0 introduced schema support, and schemas are supported in Jaybird 7 and higher. |
| 8 | + |
| 9 | +This sections describes aspects of schema support that we think are relevant, or deviate from JDBC defined behaviour. |
| 10 | + |
| 11 | +[#ref-schema-support-search-path] |
| 12 | +==== Search path |
| 13 | + |
| 14 | +In Firebird 6.0 and higher, the search path is a list of schemas that Firebird searches for objects that are not fully-qualified -- for example a select statement referencing a table without a schema name. |
| 15 | + |
| 16 | +Jaybird has a connection property `searchPath` (aliases `search_path`, `isc_dpb_search_path`) to configure the initial search path of a connection. |
| 17 | +If the `SYSTEM` schema is not included, Firebird will automatically add it to the end of the search path. |
| 18 | +The configured value is also what is reverted to when executing `ALTER SESSION RESET`. |
| 19 | + |
| 20 | +The value of this connection property is a comma-separated list of schema names. |
| 21 | +For a case-sensitive or otherwise non-regular schema name, the identifier *must* be quoted. |
| 22 | + |
| 23 | +The `FirebirdConnection` interface defines the methods `setSearchPath(String)` and `setSearchPathList(List<String>)` to change the search path of the current connection. |
| 24 | +It also defines methods `String getSearchPath()` and `List<String> getSearchPathList()` to obtain the search path of the connection. |
| 25 | + |
| 26 | +[#ref-schema-support-set-schema] |
| 27 | +==== Current schema and `Connection.setSchema/getSchema` |
| 28 | + |
| 29 | +The first _valid_ (existing) schema on the search path is the _current schema_. |
| 30 | +The current schema is used to create objects if they are not fully-qualified. |
| 31 | + |
| 32 | +JDBC defines the method `setSchema` to change the current schema, and `getSchema` to retrieve the current schema. |
| 33 | + |
| 34 | +The implementation in Jaybird will do one of the following: |
| 35 | + |
| 36 | +. Prepend the schema to the existing search path. |
| 37 | ++ |
| 38 | +This is done if `setSchema` was not called before, or if Jaybird detected that the search path was changed in some other fashion. |
| 39 | +. Replace the first value of the current search path with a new value. |
| 40 | ++ |
| 41 | +This is done if the current search path is unchanged since the previous call to `setSchema`, otherwise it's prepended. |
| 42 | + |
| 43 | +The `setSchema` method will not check if the specified schema exists, nor throw an exception. |
| 44 | +In other words, the current schema -- and the value reported by `getSchema` -- might not change, or change to a different value in case 2 (replacing the first schema), if the specified schema does not exist. |
| 45 | + |
| 46 | +If a schema on the search path that previously did not exist is created, the value reported by `getSchema` may change even if the search path was not changed. |
| 47 | + |
| 48 | +[#ref-schema-support-statement] |
| 49 | +==== Non-standard statement behaviour |
| 50 | + |
| 51 | +JDBC requires that a statement object, once created, does not change the current schema it uses. |
| 52 | +That is, changes made with `Connection.setSchema` should not apply to statements created before that call. |
| 53 | +Jaybird cannot fully meet this requirement as the search path is a connection-level property, and Firebird will use the search path as it is at prepare time. |
| 54 | + |
| 55 | +- For `Statement`, Jaybird will prepare the statement text on execute, so the search path at that time is used and resolution can change between executes on the same `Statement` object. |
| 56 | +- For `PreparedStatement` (not `CallableStatement`), Jaybird will prepare the statement text at `Connection.prepareStatement` time, so it can guarantee the required behaviour. |
| 57 | +- For `CallableStatement`, Jaybird will attempt to identify the procedure at `Connection.prepareCall` time, and rewrite the statement text to use a fully-qualified reference. |
| 58 | +If it can identify the procedure, Jaybird will meet the required behaviour. |
| 59 | ++ |
| 60 | +However, actual server-side statement preparation is delayed and will be repeated during the lifetime of the `CallableStatement`. |
| 61 | +So, if Jaybird was not able to identify the procedure during `prepareCall`, the actual schema and procedure resolution can change between executes. |
| 62 | +
|
| 63 | +[TIP] |
| 64 | +==== |
| 65 | +If you need stable resolution where Jaybird doesn't guarantee it, you can fully qualify the objects (e.g. tables) in your statements: |
| 66 | +
|
| 67 | +[source,sql] |
| 68 | +---- |
| 69 | +select |
| 70 | + MY_TABLE.*, |
| 71 | + MY_SCHEMA.MY_FUNCTION(MY_COLUMN), |
| 72 | + MY_SCHEMA.MY_PACKAGE.MY_FUNCTION(MY_COLUMN) |
| 73 | +from MY_SCHEMA.MY_TABLE |
| 74 | +---- |
| 75 | +
|
| 76 | +[source] |
| 77 | +---- |
| 78 | +{call MY_SCHEMA.MY_PROCEDURE(?, ?)} |
| 79 | +-- or |
| 80 | +{call MY_SCHEMA.MY_PACKAGE.MY_PROCEDURE(?, ?)} |
| 81 | +---- |
| 82 | +==== |
0 commit comments