Skip to content

Commit

Permalink
Add support for SET TRANSACTION statements.
Browse files Browse the repository at this point in the history
  • Loading branch information
jellelicht committed May 12, 2022
1 parent 3f88e57 commit 961f222
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 1 deletion.
20 changes: 20 additions & 0 deletions src/ast-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ export interface IAstPartialMapper {
createSequence?(seq: a.CreateSequenceStatement): a.Statement | nil
alterSequence?(seq: a.AlterSequenceStatement): a.Statement | nil
begin?(begin: a.BeginStatement): a.Statement | nil
setTransactionSnapshot?(snapshot: a.SetTransactionSnapshot): a.Statement | nil
setTransaction?(transaction: a.SetTransactionMode): a.Statement | nil
setSession?(session: a.SetTransactionMode): a.Statement | nil
}

export type IAstFullMapper = {
Expand Down Expand Up @@ -247,6 +250,12 @@ export class AstDefaultMapper implements IAstMapper {
return this.setGlobal(val);
case 'set timezone':
return this.setTimezone(val);
case 'set transaction snapshot':
return this.setTransactionSnapshot(val);
case 'set transaction':
return this.setTransaction(val);
case 'set session characteristics as transaction':
return this.setSession(val);
case 'create sequence':
return this.createSequence(val);
case 'alter sequence':
Expand Down Expand Up @@ -437,6 +446,17 @@ export class AstDefaultMapper implements IAstMapper {
return val;
}

setTransactionSnapshot?(snapshot: a.SetTransactionSnapshot): a.Statement | nil {
return snapshot;
}

setTransaction?(transaction: a.SetTransactionMode): a.Statement | nil {
return transaction;
}

setSession?(session: a.SetTransactionMode): a.Statement | nil {
return session;
}

update(val: a.UpdateStatement): a.Statement | nil {
if (!val) {
Expand Down
12 changes: 12 additions & 0 deletions src/syntax/ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ export interface BeginStatement extends PGNode {
deferrable?: boolean;
}

export interface SetTransactionSnapshot extends PGNode {
type: 'set transaction snapshot';
snapshotId: Name;
}

export interface SetTransactionMode extends PGNode {
type: 'set transaction' | 'set session characteristics as transaction';
isolationLevel: 'serializable' | 'repeatable read' | 'read committed' | 'read uncommitted';
writeable?: 'read write' | 'read only';
deferrable?: boolean;
}

export interface DoStatement extends PGNode {
type: 'do';
language?: Name;
Expand Down
3 changes: 3 additions & 0 deletions src/syntax/base.ne
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ kw_filter -> %word {% notReservedKw('filter') %}
kw_commit -> %word {% notReservedKw('commit') %}
kw_tablespace -> %word {% notReservedKw('tablespace') %}
kw_transaction -> %word {% notReservedKw('transaction') %}
kw_snapshot -> %word {% notReservedKw('snapshot') %}
kw_session -> %word {% notReservedKw('session') %}
kw_characteristics -> %word {% notReservedKw('characteristics') %}
kw_work -> %word {% notReservedKw('work') %}
kw_read -> %word {% notReservedKw('read') %}
kw_write -> %word {% notReservedKw('write') %}
Expand Down
27 changes: 26 additions & 1 deletion src/syntax/simple-statements.ne
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ simplestatements_tablespace -> kw_tablespace word {% x => track(x, {
}) %}


simplestatements_set -> kw_set (simplestatements_set_simple | simplestatements_set_timezone) {% last %}
simplestatements_set -> kw_set (simplestatements_set_simple
| simplestatements_set_timezone
| simplestatements_set_session
| simplestatements_set_transaction_snapshot
| simplestatements_set_transaction) {% last %}

simplestatements_set_timezone -> kw_time kw_zone simplestatements_set_timezone_val {% x => track(x, { type: 'set timezone', to: x[2] }) %}

Expand Down Expand Up @@ -65,6 +69,27 @@ simplestatements_set_val_raw

simplestatements_show -> kw_show ident {% x => track(x, { type: 'show', variable: asName(x[1]) }) %}

# https://www.postgresql.org/docs/current/sql-set-transaction.html
simplestatements_set_transaction_snapshot
-> kw_transaction kw_snapshot ident {% x => track(x, { type: 'set transaction snapshot', snapshotId: asName(x[2]) }) %}

simplestatements_set_session
-> kw_session kw_characteristics %kw_as kw_transaction
(simplestatements_begin_isol | simplestatements_begin_writ | simplestatements_begin_def):* {%
x => track(x, {
type: 'set session characteristics as transaction',
...x[4].reduce((a: any, b: any) => ({...unwrap(a), ...unwrap(b)}), {}),
})
%}

simplestatements_set_transaction
-> kw_transaction (simplestatements_begin_isol | simplestatements_begin_writ | simplestatements_begin_def):* {%
x => track(x, {
type: 'set transaction',
...x[1].reduce((a: any, b: any) => ({...unwrap(a), ...unwrap(b)}), {}),
})
%}


# https://www.postgresql.org/docs/current/sql-createschema.html
create_schema -> (%kw_create kw_schema) kw_ifnotexists:? ident {% x => track(x, {
Expand Down
20 changes: 20 additions & 0 deletions src/syntax/simple-statements.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,26 @@ describe('Simple statements', () => {
})


checkStatement(`set transaction SNAPSHOT mysnapshot`, {
type: 'set transaction snapshot',
snapshotId: { name: 'mysnapshot' },
});

checkStatement(`set transaction isolation level repeatable read read only not deferrable`, {
type: 'set transaction',
isolationLevel: 'repeatable read',
writeable: 'read only',
deferrable: false,
});

checkStatement(`set session characteristics as transaction isolation level read uncommitted deferrable read write`, {
type: 'set session characteristics as transaction',
isolationLevel: 'read uncommitted',
writeable: 'read write',
deferrable: true,
});


checkStatement(`select * from (select a from mytable) myalias(col_renamed)`, {
type: 'select',
columns: [{ expr: { type: 'ref', name: '*' } }],
Expand Down
37 changes: 37 additions & 0 deletions src/to-sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,43 @@ const visitor = astVisitor<IAstFullVisitor>(m => ({
}
},

setTransactionSnapshot: s => {
ret.push('SET TRANSACTION SNAPSHOT ');
ret.push(name(s.snapshotId));
},

setTransaction: tx => {
ret.push('SET TRANSACTION ');
if (tx.isolationLevel) {
ret.push('ISOLATION LEVEL ', tx.isolationLevel.toUpperCase(), ' ');
}
if (tx.writeable) {
ret.push(tx.writeable.toUpperCase(), ' ');
}
if (typeof tx.deferrable === 'boolean') {
if (!tx.deferrable) {
ret.push('NOT ');
}
ret.push('DEFERRABLE ');
}
},

setSession: s => {
ret.push('SET SESSION CHARACTERISTICS AS TRANSACTION ');
if (s.isolationLevel) {
ret.push('ISOLATION LEVEL ', s.isolationLevel.toUpperCase(), ' ');
}
if (s.writeable) {
ret.push(s.writeable.toUpperCase(), ' ');
}
if (typeof s.deferrable === 'boolean') {
if (!s.deferrable) {
ret.push('NOT ');
}
ret.push('DEFERRABLE ');
}
},

begin: beg => {
ret.push('BEGIN ');
if (beg.isolationLevel) {
Expand Down

0 comments on commit 961f222

Please sign in to comment.