DBTIMEZONE
1. Purpose
This document explains the purpose of the DBTIMEZONE function in IvorySQL, which implements Oracle-style database-level time zone querying.
Oracle provides two time-zone-related built-in functions: SESSIONTIMEZONE returns the time zone of the current session (changed via ALTER SESSION SET TIME_ZONE), and DBTIMEZONE returns a fixed database-level time zone (determined at CREATE DATABASE / ALTER DATABASE SET TIME_ZONE time, independent of the session). IvorySQL has already implemented SESSIONTIMEZONE; this feature completes DBTIMEZONE.
2. Feature Description
2.1. Basic Syntax
SELECT dbtimezone() FROM dual;
Returns a text-typed time zone value in UTC offset format ([+-]HH:MI), with a default value of '+00:00'.
2.2. Core Characteristics
-
Database-level, not session-level: The return value is fixed by
ALTER DATABASE … SET ivorysql.dbtimezone = …, and is not affected by the current session’sSET timezone, in contrast toSESSIONTIMEZONE(session-level) -
Can only be modified via
ALTER DATABASE … SET: SettingSET ivorysql.dbtimezone = …directly within a session, and any form ofALTER ROLE … SET ivorysql.dbtimezone = …(ALTER ROLE rolename SET,ALTER ROLE rolename IN DATABASE dbname SET,ALTER ROLE ALL SET), will raise an error directly at the command level rather than being silently accepted; onlyALTER DATABASE dbname SET ivorysql.dbtimezone = …takes effect, and only on the next connection to that database -
Only superusers can set it by default: An ordinary user cannot execute
ALTER DATABASE … SET ivorysql.dbtimezone = …even if they are the owner of a database they created themselves; a superuser can explicitly grant a non-superuser role permission to manage this setting viaGRANT SET ON PARAMETER ivorysql.dbtimezone TO <role>; -
All roles in the same database see the same value:
DBTIMEZONEis a pure database property and does not support "different roles seeing different values within the same database" — anyALTER ROLE … SETattempting to differentiate by role is rejected directly at the command level (exceptALTER ROLE … RESET, which is used to clean up stale legacy records) -
Value format validation: Accepts a UTC offset in the form
[+-]HH:MI, in the range-12:59to+14:00(consistent with Oracle), or a valid IANA time zone region name
3. Syntax Examples
3.2. Comparison with SESSIONTIMEZONE: Unaffected by the Session Time Zone
SET timezone = 'Asia/Hong_Kong';
SELECT sessiontimezone() FROM dual;
-- sessiontimezone
-- -----------------
-- Asia/Hong_Kong
SELECT dbtimezone() FROM dual;
-- Still the fixed database value, unaffected by the SET timezone above
-- dbtimezone
-- ------------
-- +00:00
3.3. Fixing the Time Zone of a Database via ALTER DATABASE
ALTER DATABASE mydb SET ivorysql.dbtimezone = '+08:00';
-- Takes effect only after disconnecting and reconnecting (a new session)
\c mydb
SELECT dbtimezone() FROM dual; -- +08:00
3.4. Granting a Non-Superuser Permission to Manage DBTIMEZONE for Their Own Database
-- The superuser performs a one-time grant:
GRANT SET ON PARAMETER ivorysql.dbtimezone TO app_owner;
-- app_owner can then set it for a database they own:
\c app_db app_owner
ALTER DATABASE app_db SET ivorysql.dbtimezone = '+05:30';
\c app_db app_owner
SELECT dbtimezone() FROM dual; -- +05:30
4. Error Handling
4.1. Direct SET Within a Session Is Rejected
SET ivorysql.dbtimezone = '+08:00';
-- ERROR: parameter "ivorysql.dbtimezone" cannot be set
-- DETAIL: "ivorysql.dbtimezone" can only be set with ALTER DATABASE ... SET, not within a session or per-role.
4.2. ALTER ROLE … SET Is Rejected Directly at the Command Level
ALTER ROLE myrole IN DATABASE mydb SET ivorysql.dbtimezone = '+09:00';
-- ERROR: parameter "ivorysql.dbtimezone" cannot be set
-- DETAIL: "ivorysql.dbtimezone" can only be set with ALTER DATABASE ... SET, not within a session or per-role.
-- HINT: Use ALTER DATABASE ... SET ivorysql.dbtimezone instead, or ALTER ROLE ... RESET ivorysql.dbtimezone to remove a stale per-role override.
ALTER ROLE myrole SET ivorysql.dbtimezone = '+09:00'; -- Also errors
ALTER ROLE ALL SET ivorysql.dbtimezone = '+09:00'; -- Also errors
-- RESET / RESET ALL are unaffected and can still be used to clean up stale legacy records:
ALTER ROLE myrole IN DATABASE mydb RESET ivorysql.dbtimezone; -- OK
4.3. Invalid Value / Out-of-Range Offset
ALTER DATABASE mydb SET ivorysql.dbtimezone = 'not_a_zone';
-- ERROR: invalid value for parameter "ivorysql.dbtimezone": "not_a_zone"
-- DETAIL: "not_a_zone" is not a valid UTC offset (+/-HH:MI) or time zone name.
ALTER DATABASE mydb SET ivorysql.dbtimezone = '+15:00';
-- ERROR: invalid value for parameter "ivorysql.dbtimezone": "+15:00"
-- DETAIL: time zone offset "+15:00" is out of range for DBTIMEZONE (-12:59 to +14:00)
4.4. An Unauthorized Ordinary User Executing ALTER DATABASE
-- normal_user is the owner of mydb, but has not been granted permission via GRANT SET ON PARAMETER
\c mydb normal_user
ALTER DATABASE mydb SET ivorysql.dbtimezone = '+08:00';
-- ERROR: permission denied to set parameter "ivorysql.dbtimezone"
Owning or creating a database does not imply permission to set every GUC parameter for that database — database-level permission (whether you can ALTER this database) and GUC-parameter-level permission (whether you can "set" this parameter) are two independent checks.
|