Skip to content

Commit

Permalink
Support repeatable read and serializable isolation level (#1695)
Browse files Browse the repository at this point in the history
Currently we do not support repeatable read and serializable isolation levels.
With this PR
BABEL repeatable read → PG repeatable read (if repeatable read escape hatch is set to pg_isolation)
BABEL serializable → PG serializable (if serializable escape hatch is set to pg_isolation)

REPEATABLE READ GUC:- 'repeatable_read_isolation'
SERIALIZABLE GUC:- 'serializable_isolation'

Issues Resolved: BABEL-4146 & BABEL-4145

Signed-off-by: Tanzeel Khan [email protected]
  • Loading branch information
tanscorpio7 authored Oct 26, 2023
1 parent b919797 commit 9fab304
Show file tree
Hide file tree
Showing 24 changed files with 1,148 additions and 21 deletions.
3 changes: 2 additions & 1 deletion contrib/babelfishpg_tsql/sql/sys_procedures.sql
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ CREATE VIEW sys.babelfish_configurations_view as
FROM pg_catalog.pg_settings
WHERE name collate "C" like 'babelfishpg_tsql.explain_%' OR
name collate "C" like 'babelfishpg_tsql.escape_hatch_%' OR
name collate "C" = 'babelfishpg_tsql.enable_pg_hint';
name collate "C" = 'babelfishpg_tsql.enable_pg_hint' OR
name collate "C" like 'babelfishpg_tsql.isolation_level_%';
GRANT SELECT on sys.babelfish_configurations_view TO PUBLIC;

CREATE OR REPLACE PROCEDURE sys.sp_babelfish_configure(IN "@option_name" varchar(128), IN "@option_value" varchar(128), IN "@option_scope" varchar(128))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3096,6 +3096,16 @@ GRANT EXECUTE ON FUNCTION sys.FORMAT(IN anyelement, IN NVARCHAR, IN VARCHAR) TO
-- Please have this be one of the last statements executed in this upgrade script.
DROP PROCEDURE sys.babelfish_drop_deprecated_object(varchar, varchar, varchar);


CREATE OR REPLACE VIEW sys.babelfish_configurations_view as
SELECT *
FROM pg_catalog.pg_settings
WHERE name collate "C" like 'babelfishpg_tsql.explain_%' OR
name collate "C" like 'babelfishpg_tsql.escape_hatch_%' OR
name collate "C" = 'babelfishpg_tsql.enable_pg_hint' OR
name collate "C" like 'babelfishpg_tsql.isolation_level_%';
GRANT SELECT on sys.babelfish_configurations_view TO PUBLIC;

-- After upgrade, always run analyze for all babelfish catalogs.
CALL sys.analyze_babelfish_catalogs();

Expand Down
29 changes: 23 additions & 6 deletions contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y
Original file line number Diff line number Diff line change
Expand Up @@ -4338,11 +4338,20 @@ tsql_IsolationLevelStr:
}
| REPEATABLE READ
{
TSQLInstrumentation(INSTR_UNSUPPORTED_TSQL_ISOLATION_LEVEL_REPEATABLE_READ);
ereport(ERROR,
if (pltsql_isolation_level_repeatable_read)
{
TSQLInstrumentation(INSTR_TSQL_ISOLATION_LEVEL_REPEATABLE_READ);
$$ = "repeatable read";
}
else
{
TSQLInstrumentation(INSTR_UNSUPPORTED_TSQL_ISOLATION_LEVEL_REPEATABLE_READ);
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("REPEATABLE READ isolation level is not supported"),
errmsg("Isolation level ‘REPEATABLE READis not currently supported in Babelfish. Please use ‘babelfishpg_tsql.isolation_level_repeatable_read’ config option to get PG repeatable read isolation level."),
parser_errposition(@1)));
}

}
| SNAPSHOT
{
Expand All @@ -4351,11 +4360,19 @@ tsql_IsolationLevelStr:
}
| SERIALIZABLE
{
TSQLInstrumentation(INSTR_UNSUPPORTED_TSQL_ISOLATION_LEVEL_SERIALIZABLE);
ereport(ERROR,
if (pltsql_isolation_level_serializable)
{
TSQLInstrumentation(INSTR_TSQL_ISOLATION_LEVEL_SERIALIZABLE);
$$ = "serializable";
}
else
{
TSQLInstrumentation(INSTR_UNSUPPORTED_TSQL_ISOLATION_LEVEL_SERIALIZABLE);
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("SERIALIZABLE isolation level is not supported"),
errmsg("Isolation level ‘SERIALIZABLE’ is not currently supported in Babelfish. Please use ‘babelfishpg_tsql.isolation_level_serializable’ config option to get PG serializable isolation level."),
parser_errposition(@1)));
}
}
;

Expand Down
30 changes: 30 additions & 0 deletions contrib/babelfishpg_tsql/src/guc.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ static const struct config_enum_entry escape_hatch_options[] = {
{NULL, EH_NULL, false},
};

static const struct config_enum_entry bbf_isolation_options[] = {
{"off", ISOLATION_OFF, false},
{"pg_isolation", PG_ISOLATION, false},
{NULL, ISOLATION_OFF, false},
};

static bool
check_ansi_null_dflt_on(bool *newval, void **extra, GucSource source)
{
Expand Down Expand Up @@ -1207,6 +1213,8 @@ int escape_hatch_rowversion = EH_STRICT;
int escape_hatch_showplan_all = EH_STRICT;
int escape_hatch_checkpoint = EH_IGNORE;
int escape_hatch_set_transaction_isolation_level = EH_STRICT;
int pltsql_isolation_level_repeatable_read = ISOLATION_OFF;
int pltsql_isolation_level_serializable = ISOLATION_OFF;

void
define_escape_hatch_variables(void)
Expand Down Expand Up @@ -1557,6 +1565,28 @@ define_escape_hatch_variables(void)
PGC_USERSET,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_DISALLOW_IN_AUTO_FILE,
NULL, NULL, NULL);

/* REPEATABLE READ MAPPING */
DefineCustomEnumVariable("babelfishpg_tsql.isolation_level_repeatable_read",
gettext_noop("Select mapping for isolation level reapeatable read"),
NULL,
&pltsql_isolation_level_repeatable_read,
ISOLATION_OFF,
bbf_isolation_options,
PGC_USERSET,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_DISALLOW_IN_AUTO_FILE,
NULL, NULL, NULL);

/* SERIALIZABLE MAPPING */
DefineCustomEnumVariable("babelfishpg_tsql.isolation_level_serializable",
gettext_noop("Select mapping for isolation level serializable"),
NULL,
&pltsql_isolation_level_serializable,
ISOLATION_OFF,
bbf_isolation_options,
PGC_USERSET,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_DISALLOW_IN_AUTO_FILE,
NULL, NULL, NULL);
}

void
Expand Down
7 changes: 7 additions & 0 deletions contrib/babelfishpg_tsql/src/guc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ typedef enum EscapeHatchOption
EH_STRICT, EH_IGNORE, EH_NULL
} EscapeHatchOption;

typedef enum IsolationOptions
{
ISOLATION_OFF, PG_ISOLATION
} IsolationOptions;

extern bool pltsql_fmtonly;
extern bool pltsql_enable_create_alter_view_from_pg;
extern bool pltsql_enable_linked_servers;
extern bool pltsql_allow_windows_login;
extern char *pltsql_psql_logical_babelfish_db_name;
extern int pltsql_isolation_level_repeatable_read;
extern int pltsql_isolation_level_serializable;

extern void define_custom_variables(void);
extern void pltsql_validate_set_config_function(char *name, char *value);
Expand Down
2 changes: 2 additions & 0 deletions contrib/babelfishpg_tsql/src/pltsql_instr.h
Original file line number Diff line number Diff line change
Expand Up @@ -632,8 +632,10 @@ typedef enum PgTsqlInstrMetricType

INSTR_TSQL_ISOLATION_LEVEL_READ_UNCOMMITTED,
INSTR_TSQL_ISOLATION_LEVEL_READ_COMMITTED,
INSTR_TSQL_ISOLATION_LEVEL_REPEATABLE_READ,
INSTR_UNSUPPORTED_TSQL_ISOLATION_LEVEL_REPEATABLE_READ,
INSTR_TSQL_ISOLATION_LEVEL_SNAPSHOT,
INSTR_TSQL_ISOLATION_LEVEL_SERIALIZABLE,
INSTR_UNSUPPORTED_TSQL_ISOLATION_LEVEL_SERIALIZABLE,

INSTR_UNSUPPORTED_TSQL_SELECT_COL_ALIAS,
Expand Down
93 changes: 91 additions & 2 deletions test/JDBC/expected/BABEL-3214.out
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
GO
~~ERROR (Code: 33557097)~~

~~ERROR (Message: REPEATABLE READ isolation level is not supported)~~
~~ERROR (Message: Isolation level ‘REPEATABLE READis not currently supported in Babelfish. Please use ‘babelfishpg_tsql.isolation_level_repeatable_read’ config option to get PG repeatable read isolation level.)~~

SELECT CAST(current_setting('transaction_isolation') AS VARCHAR);
SELECT transaction_isolation_level from sys.dm_exec_sessions WHERE session_id = @@SPID;
Expand All @@ -65,7 +65,7 @@ SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
~~ERROR (Code: 33557097)~~

~~ERROR (Message: SERIALIZABLE isolation level is not supported)~~
~~ERROR (Message: Isolation level ‘SERIALIZABLE’ is not currently supported in Babelfish. Please use ‘babelfishpg_tsql.isolation_level_serializable’ config option to get PG serializable isolation level.)~~

SELECT CAST(current_setting('transaction_isolation') AS VARCHAR);
SELECT transaction_isolation_level from sys.dm_exec_sessions WHERE session_id = @@SPID;
Expand Down Expand Up @@ -98,3 +98,92 @@ smallint
5
~~END~~


SELECT set_config('babelfishpg_tsql.isolation_level_repeatable_read','pg_isolation',false);
SELECT set_config('babelfishpg_tsql.isolation_level_serializable','pg_isolation',false);
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT CAST(current_setting('transaction_isolation') AS VARCHAR);
SELECT transaction_isolation_level from sys.dm_exec_sessions WHERE session_id = @@SPID;
GO
~~START~~
text
pg_isolation
~~END~~

~~START~~
text
pg_isolation
~~END~~

~~START~~
varchar
read uncommitted
~~END~~

~~START~~
smallint
1
~~END~~


SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT CAST(current_setting('transaction_isolation') AS VARCHAR);
SELECT transaction_isolation_level from sys.dm_exec_sessions WHERE session_id = @@SPID;
GO
~~START~~
varchar
read committed
~~END~~

~~START~~
smallint
2
~~END~~


SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
GO
SELECT CAST(current_setting('transaction_isolation') AS VARCHAR);
SELECT transaction_isolation_level from sys.dm_exec_sessions WHERE session_id = @@SPID;
GO
~~START~~
varchar
repeatable read
~~END~~

~~START~~
smallint
5
~~END~~


SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
GO
SELECT CAST(current_setting('transaction_isolation') AS VARCHAR);
SELECT transaction_isolation_level from sys.dm_exec_sessions WHERE session_id = @@SPID;
GO
~~START~~
varchar
serializable
~~END~~

~~START~~
smallint
4
~~END~~


SET TRANSACTION ISOLATION LEVEL SNAPSHOT;
SELECT CAST(current_setting('transaction_isolation') AS VARCHAR);
SELECT transaction_isolation_level from sys.dm_exec_sessions WHERE session_id = @@SPID;
GO
~~START~~
varchar
repeatable read
~~END~~

~~START~~
smallint
5
~~END~~

6 changes: 6 additions & 0 deletions test/JDBC/expected/BABEL-UNSUPPORTED.out
Original file line number Diff line number Diff line change
Expand Up @@ -2035,6 +2035,8 @@ babelfishpg_tsql.explain_summary#!#on#!#Include summary information (e.g., total
babelfishpg_tsql.explain_timing#!#on#!#Include actual startup time and time spent in each node in the output
babelfishpg_tsql.explain_verbose#!#off#!#Display additional information regarding the plan
babelfishpg_tsql.explain_wal#!#off#!#Include information on WAL record generation
babelfishpg_tsql.isolation_level_repeatable_read#!#off#!#Select mapping for isolation level reapeatable read
babelfishpg_tsql.isolation_level_serializable#!#off#!#Select mapping for isolation level serializable
~~END~~


Expand Down Expand Up @@ -2101,6 +2103,8 @@ babelfishpg_tsql.explain_summary#!#on#!#Include summary information (e.g., total
babelfishpg_tsql.explain_timing#!#on#!#Include actual startup time and time spent in each node in the output
babelfishpg_tsql.explain_verbose#!#off#!#Display additional information regarding the plan
babelfishpg_tsql.explain_wal#!#off#!#Include information on WAL record generation
babelfishpg_tsql.isolation_level_repeatable_read#!#off#!#Select mapping for isolation level reapeatable read
babelfishpg_tsql.isolation_level_serializable#!#off#!#Select mapping for isolation level serializable
~~END~~


Expand Down Expand Up @@ -2148,6 +2152,8 @@ babelfishpg_tsql.explain_summary#!#on#!#Include summary information (e.g., total
babelfishpg_tsql.explain_timing#!#on#!#Include actual startup time and time spent in each node in the output
babelfishpg_tsql.explain_verbose#!#off#!#Display additional information regarding the plan
babelfishpg_tsql.explain_wal#!#off#!#Include information on WAL record generation
babelfishpg_tsql.isolation_level_repeatable_read#!#off#!#Select mapping for isolation level reapeatable read
babelfishpg_tsql.isolation_level_serializable#!#off#!#Select mapping for isolation level serializable
~~END~~


Expand Down
Loading

0 comments on commit 9fab304

Please sign in to comment.