From 71c5b9ede4094f9a4fd46efe6579175d5d452325 Mon Sep 17 00:00:00 2001 From: mehmet emin karakas Date: Mon, 1 Jul 2019 14:26:38 +0300 Subject: [PATCH 1/4] Add support for CREATE DOMAIN CREATE DOMAIN us_postal_code AS TEXT CHECK( VALUE ~ '^\d{5}$' OR VALUE ~ '^\d{5}-\d{4}$' ); --- lib/pg_query/deparse.rb | 15 +++++++++++++++ lib/pg_query/node_types.rb | 1 + spec/lib/pg_query/deparse_spec.rb | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/lib/pg_query/deparse.rb b/lib/pg_query/deparse.rb index 024ccf8a..3e4cc143 100644 --- a/lib/pg_query/deparse.rb +++ b/lib/pg_query/deparse.rb @@ -102,6 +102,8 @@ def deparse_item(item, context = nil) # rubocop:disable Metrics/CyclomaticComple deparse_copy(node) when CREATE_CAST_STMT deparse_create_cast(node) + when CREATE_DOMAIN_STMT + deparse_create_domain(node) when CREATE_ENUM_STMT deparse_create_enum(node) when CREATE_FUNCTION_STMT @@ -801,6 +803,7 @@ def deparse_constraint(node) # rubocop:disable Metrics/CyclomaticComplexity if node['raw_expr'] expression = deparse_item(node['raw_expr']) # Unless it's simple, put parentheses around it + expression = '(' + expression + ')' if node['raw_expr'][BOOL_EXPR] expression = '(' + expression + ')' if node['raw_expr'][A_EXPR] && node['raw_expr'][A_EXPR]['kind'] == AEXPR_OP output << expression end @@ -862,6 +865,18 @@ def deparse_create_cast(node) output.join(' ') end + def deparse_create_domain(node) + output = [] + output << 'CREATE' + output << 'DOMAIN' + output << deparse_item_list(node['domainname']).join('.') + output << 'AS' + output << deparse_item(node['typeName']) if node['typeName'] + output << deparse_item(node['collClause']) if node['collClause'] + output << deparse_item_list(node['constraints']) + output.join(' ') + end + def deparse_create_function(node) output = [] output << 'CREATE' diff --git a/lib/pg_query/node_types.rb b/lib/pg_query/node_types.rb index 5e1cb7ff..733f5ef9 100644 --- a/lib/pg_query/node_types.rb +++ b/lib/pg_query/node_types.rb @@ -28,6 +28,7 @@ class PgQuery CONSTRAINT = 'Constraint'.freeze COPY_STMT = 'CopyStmt'.freeze CREATE_CAST_STMT = 'CreateCastStmt'.freeze + CREATE_DOMAIN_STMT = 'CreateDomainStmt'.freeze CREATE_ENUM_STMT = 'CreateEnumStmt'.freeze CREATE_FUNCTION_STMT = 'CreateFunctionStmt'.freeze CREATE_RANGE_STMT = 'CreateRangeStmt'.freeze diff --git a/spec/lib/pg_query/deparse_spec.rb b/spec/lib/pg_query/deparse_spec.rb index 05d49971..db0b321b 100644 --- a/spec/lib/pg_query/deparse_spec.rb +++ b/spec/lib/pg_query/deparse_spec.rb @@ -745,6 +745,22 @@ end end + context 'CREATE DOMAIN' do + context 'with check' do + let(:query) do + """ + CREATE DOMAIN \"us_postal_code\" AS text + CHECK ( + \"VALUE\" ~ '^\d{5}$' + OR \"VALUE\" ~ '^\d{5}-\d{4}$' + ); + """.strip + end + + it { is_expected.to eq oneline_query } + end + end + context 'CREATE FUNCTION' do # Taken from http://www.postgresql.org/docs/8.3/static/queries-table-expressions.html context 'with inline function definition' do From 5d8eb86bf655129e9b02218c12e4f28c2bcf70d9 Mon Sep 17 00:00:00 2001 From: mehmet emin karakas Date: Sun, 7 Jul 2019 16:26:41 +0300 Subject: [PATCH 2/4] Fix create table as problem. Support without TEMP. CREATE TABLE films_recent AS SELECT * FROM films WHERE date_prod >= '2002-01-01' CREATE TEMP TABLE films_recent AS SELECT * FROM films WHERE date_prod >= '2002-01-01' --- lib/pg_query/deparse.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/pg_query/deparse.rb b/lib/pg_query/deparse.rb index 3e4cc143..dd5053ec 100644 --- a/lib/pg_query/deparse.rb +++ b/lib/pg_query/deparse.rb @@ -947,7 +947,13 @@ def deparse_create_table(node) def deparse_create_table_as(node) output = [] - output << 'CREATE TEMPORARY TABLE' + output << 'CREATE' + + persistence = relpersistence(node['into']['IntoClause']['rel']) + output << persistence if persistence + + output << 'TABLE' + output << deparse_item(node['into']) output << 'AS' output << deparse_item(node['query']) From 9e7887dc92434e3b3ea123913ed716e1a34cd5bc Mon Sep 17 00:00:00 2001 From: mehmet emin karakas Date: Sun, 7 Jul 2019 16:45:25 +0300 Subject: [PATCH 3/4] Added ON COMMIT part ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } --- lib/pg_query/deparse.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/pg_query/deparse.rb b/lib/pg_query/deparse.rb index dd5053ec..ee29aae7 100644 --- a/lib/pg_query/deparse.rb +++ b/lib/pg_query/deparse.rb @@ -949,12 +949,20 @@ def deparse_create_table_as(node) output = [] output << 'CREATE' - persistence = relpersistence(node['into']['IntoClause']['rel']) + into = node['into']['IntoClause'] + persistence = relpersistence(into['rel']) output << persistence if persistence output << 'TABLE' output << deparse_item(node['into']) + + if into['onCommit'] > 0 + output << 'ON COMMIT' + output << 'DELETE ROWS' if into['onCommit'] == 2 + output << 'DROP' if into['onCommit'] == 3 + end + output << 'AS' output << deparse_item(node['query']) output.join(' ') From ed0c8a8678070cfc6811664e9d2a4238ebb72116 Mon Sep 17 00:00:00 2001 From: emin100 Date: Mon, 11 Nov 2019 11:36:57 +0300 Subject: [PATCH 4/4] added test CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS SELECT * FROM films WHERE date_prod > $1; CREATE TABLE films2 AS TABLE films; --- spec/lib/pg_query/deparse_spec.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/spec/lib/pg_query/deparse_spec.rb b/spec/lib/pg_query/deparse_spec.rb index 52de52dd..0d837cba 100644 --- a/spec/lib/pg_query/deparse_spec.rb +++ b/spec/lib/pg_query/deparse_spec.rb @@ -995,6 +995,18 @@ it { is_expected.to eq oneline_query } end + + context 'create table as' do + let(:query) { 'CREATE TABLE "films2" AS SELECT * FROM "films"' } + + it { is_expected.to eq oneline_query } + end + + context 'create table ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP }' do + let(:query) { 'CREATE TEMPORARY TABLE "films_recent" ON COMMIT DROP AS SELECT * FROM "films" WHERE "date_prod" > $1' } + + it { is_expected.to eq oneline_query } + end end context 'DROP TABLE' do