pg_query 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9d1df6666392e194e8ac7a87086cae2e3051644a
4
- data.tar.gz: b524259660a3489556696cf0f4b75d0c5c3c91b7
2
+ SHA256:
3
+ metadata.gz: 0db8e898d08ff3642a800ab296d7ac10dd9556e3c5a626f005bae86d35273372
4
+ data.tar.gz: a869a1faeb3ae0bed9d5031f2a4d26263843fde368bfeb096c1c9f48ea30c9f8
5
5
  SHA512:
6
- metadata.gz: 61523601794ef69a4dad8e33ba3fc9b5f35f299dce42f3b924b8ccca8726d9a11266dbcbbb7c1fc6f92c98c3443a02092d006c2c9a1484a1a9b9e0875fa9b6e3
7
- data.tar.gz: 476105d1b4a3337f9ef4266452858cb70d02278ad8b564320ad9d76169425f81f2e64fc9fff070fcc9739ce3589bde93e5ea000bf062c61a7190d5f4e38eacee
6
+ metadata.gz: e0f51970e5f268d9d9d32d791288db0d7a048c4880f706ff7d483b0efacd1a355600f5b8ca8a0b57b75a05cda8c7b207402bb6680fad0fdaeaf7809fab06c441
7
+ data.tar.gz: 6281530a32add88cd8a474a8e224e817723e288e850f9d9232aba69208b1178d89b7135d613d15800176bd611b3d6fcd0600fb48c3e8c880f6aa47f5296bae45
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0 2018-10-04
4
+
5
+ * Deparsing improvements by [@herwinw](https://github.com/herwinw)
6
+ * Add NULLS FIRST/LAST to ORDER BY [#95](https://github.com/lfittl/pg_query/pull/95)
7
+ * VACUUM [#97](https://github.com/lfittl/pg_query/pull/97)
8
+ * UPDATE with multiple columns [#99](https://github.com/lfittl/pg_query/pull/99)
9
+ * DISTINCT ON [#101](https://github.com/lfittl/pg_query/pull/101)
10
+ * CREATE TABLE AS [#102](https://github.com/lfittl/pg_query/pull/102)
11
+ * SQL value functions [#103](https://github.com/lfittl/pg_query/pull/103)
12
+ * LOCK [#105](https://github.com/lfittl/pg_query/pull/105)
13
+ * EXPLAIN [#107](https://github.com/lfittl/pg_query/pull/107)
14
+ * COPY [#108](https://github.com/lfittl/pg_query/pull/108)
15
+ * DO [#109](https://github.com/lfittl/pg_query/pull/109)
16
+ * Ignore pg_query.so in git checkout [#110](https://github.com/lfittl/pg_query/pull/110) [@herwinw](https://github.com/herwinw)
17
+ * Prefer __dir__ over File.dirname(__FILE__) [#110](https://github.com/lfittl/pg_query/pull/104) [@herwinw](https://github.com/herwinw)
18
+
19
+
3
20
  ## 1.0.2 2018-04-11
4
21
 
5
22
  * Deparsing improvements
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ task test: :spec
17
17
  task lint: :rubocop
18
18
 
19
19
  task :clean do
20
- FileUtils.rm_rf File.join(File.dirname(__FILE__), 'tmp/')
21
- FileUtils.rm_f Dir.glob(File.join(File.dirname(__FILE__), 'ext/pg_query/*.o'))
22
- FileUtils.rm_f File.join(File.dirname(__FILE__), 'lib/pg_query/pg_query.bundle')
20
+ FileUtils.rm_rf File.join(__dir__, 'tmp/')
21
+ FileUtils.rm_f Dir.glob(File.join(__dir__, 'ext/pg_query/*.o'))
22
+ FileUtils.rm_f File.join(__dir__, 'lib/pg_query/pg_query.bundle')
23
23
  end
@@ -7,7 +7,7 @@ LIB_PG_QUERY_TAG = '10-1.0.1'.freeze
7
7
 
8
8
  workdir = Dir.pwd
9
9
  libdir = File.join(workdir, 'libpg_query-' + LIB_PG_QUERY_TAG)
10
- gemdir = File.join(File.dirname(__FILE__), '../..')
10
+ gemdir = File.join(__dir__, '../..')
11
11
  libfile = libdir + '/libpg_query.a'
12
12
 
13
13
  unless File.exist?("#{workdir}/libpg_query.tar.gz")
@@ -36,7 +36,7 @@ $LOCAL_LIBS << '-lpg_query'
36
36
  $LIBPATH << libdir
37
37
  $CFLAGS << " -I #{libdir} -O3 -Wall -fno-strict-aliasing -fwrapv -g"
38
38
 
39
- SYMFILE = File.join(File.dirname(__FILE__), 'pg_query_ruby.sym')
39
+ SYMFILE = File.join(__dir__, 'pg_query_ruby.sym')
40
40
  if RUBY_PLATFORM =~ /darwin/
41
41
  $DLDFLAGS << " -Wl,-exported_symbols_list #{SYMFILE}" unless defined?(::Rubinius)
42
42
  else
@@ -86,16 +86,24 @@ class PgQuery
86
86
  deparse_cte(node)
87
87
  when CONSTRAINT
88
88
  deparse_constraint(node)
89
+ when COPY_STMT
90
+ deparse_copy(node)
89
91
  when CREATE_FUNCTION_STMT
90
92
  deparse_create_function(node)
91
93
  when CREATE_STMT
92
94
  deparse_create_table(node)
95
+ when CREATE_TABLE_AS_STMT
96
+ deparse_create_table_as(node)
97
+ when INTO_CLAUSE
98
+ deparse_into_clause(node)
93
99
  when DEF_ELEM
94
100
  deparse_defelem(node)
95
101
  when DELETE_STMT
96
102
  deparse_delete_from(node)
97
103
  when DROP_STMT
98
104
  deparse_drop(node)
105
+ when EXPLAIN_STMT
106
+ deparse_explain(node)
99
107
  when FUNC_CALL
100
108
  deparse_funccall(node)
101
109
  when FUNCTION_PARAMETER
@@ -104,6 +112,8 @@ class PgQuery
104
112
  deparse_insert_into(node)
105
113
  when JOIN_EXPR
106
114
  deparse_joinexpr(node)
115
+ when LOCK_STMT
116
+ deparse_lock(node)
107
117
  when LOCKING_CLAUSE
108
118
  deparse_lockingclause(node)
109
119
  when NULL_TEST
@@ -126,6 +136,8 @@ class PgQuery
126
136
  deparse_row(node)
127
137
  when SELECT_STMT
128
138
  deparse_select(node)
139
+ when SQL_VALUE_FUNCTION
140
+ deparse_sql_value_function(node)
129
141
  when SORT_BY
130
142
  deparse_sortby(node)
131
143
  when SUB_LINK
@@ -148,6 +160,10 @@ class PgQuery
148
160
  deparse_viewstmt(node)
149
161
  when VARIABLE_SET_STMT
150
162
  deparse_variable_set_stmt(node)
163
+ when VACUUM_STMT
164
+ deparse_vacuum_stmt(node)
165
+ when DO_STMT
166
+ deparse_do_stmt(node)
151
167
  when STRING
152
168
  if context == A_CONST
153
169
  format("'%s'", node['str'].gsub("'", "''"))
@@ -458,6 +474,14 @@ class PgQuery
458
474
  output.join(' ')
459
475
  end
460
476
 
477
+ def deparse_lock(node)
478
+ output = []
479
+ output << 'LOCK TABLE'
480
+ tables = node['relations'].map { |table| deparse_item(table) }
481
+ output << tables.join(', ')
482
+ output.join(' ')
483
+ end
484
+
461
485
  LOCK_CLAUSE_STRENGTH = {
462
486
  LCS_FORKEYSHARE => 'FOR KEY SHARE',
463
487
  LCS_FORSHARE => 'FOR SHARE',
@@ -481,6 +505,8 @@ class PgQuery
481
505
  output << deparse_item(node['node'])
482
506
  output << 'ASC' if node['sortby_dir'] == 1
483
507
  output << 'DESC' if node['sortby_dir'] == 2
508
+ output << 'NULLS FIRST' if node['sortby_nulls'] == 1
509
+ output << 'NULLS LAST' if node['sortby_nulls'] == 2
484
510
  output.join(' ')
485
511
  end
486
512
 
@@ -527,6 +553,35 @@ class PgQuery
527
553
  output.join(' ')
528
554
  end
529
555
 
556
+ def deparse_vacuum_stmt(node)
557
+ output = []
558
+ output << 'VACUUM'
559
+ output.concat(deparse_vacuum_options(node))
560
+ output << deparse_item(node['relation']) if node.key?('relation')
561
+ if node.key?('va_cols')
562
+ output << "(#{node['va_cols'].map(&method(:deparse_item)).join(', ')})"
563
+ end
564
+ output.join(' ')
565
+ end
566
+
567
+ def deparse_vacuum_options(node)
568
+ output = []
569
+ output << 'FULL' if node['options'][4] == 1
570
+ output << 'FREEZE' if node['options'][3] == 1
571
+ output << 'VERBOSE' if node['options'][2] == 1
572
+ output << 'ANALYZE' if node['options'][1] == 1
573
+ output
574
+ end
575
+
576
+ def deparse_do_stmt(node)
577
+ output = []
578
+ output << 'DO'
579
+ statement, *rest = node['args']
580
+ output << "$$#{statement['DefElem']['arg']['String']['str']}$$"
581
+ output += rest.map { |item| deparse_item(item) }
582
+ output.join(' ')
583
+ end
584
+
530
585
  def deparse_cte(node)
531
586
  output = []
532
587
  output << node['ctename']
@@ -601,6 +656,21 @@ class PgQuery
601
656
  output.join(' ')
602
657
  end
603
658
 
659
+ def deparse_copy(node)
660
+ output = ['COPY']
661
+ output << deparse_item(node['relation'])
662
+ columns = node.fetch('attlist', []).map { |column| deparse_item(column) }
663
+ output << "(#{columns.join(', ')})" unless columns.empty?
664
+ output << (node['is_from'] ? 'FROM' : 'TO')
665
+ output << 'PROGRAM' if node['is_program']
666
+ output << if node.key?('filename')
667
+ "'#{node['filename']}'"
668
+ else
669
+ node['is_from'] ? 'STDIN' : 'STDOUT'
670
+ end
671
+ output.join(' ')
672
+ end
673
+
604
674
  def deparse_create_function(node)
605
675
  output = []
606
676
  output << 'CREATE'
@@ -645,6 +715,19 @@ class PgQuery
645
715
  output.join(' ')
646
716
  end
647
717
 
718
+ def deparse_create_table_as(node)
719
+ output = []
720
+ output << 'CREATE TEMPORARY TABLE'
721
+ output << deparse_item(node['into'])
722
+ output << 'AS'
723
+ output << deparse_item(node['query'])
724
+ output.join(' ')
725
+ end
726
+
727
+ def deparse_into_clause(node)
728
+ deparse_item(node['rel'])
729
+ end
730
+
648
731
  def deparse_when(node)
649
732
  output = ['WHEN']
650
733
  output << deparse_item(node['expr'])
@@ -691,7 +774,13 @@ class PgQuery
691
774
 
692
775
  if node[TARGET_LIST_FIELD]
693
776
  output << 'SELECT'
694
- output << 'DISTINCT' if node['distinctClause']
777
+ if node['distinctClause']
778
+ output << 'DISTINCT'
779
+ unless node['distinctClause'].compact.empty?
780
+ columns = node['distinctClause'].map { |item| deparse_item(item, :select) }
781
+ output << "ON (#{columns.join(', ')})"
782
+ end
783
+ end
695
784
  output << node[TARGET_LIST_FIELD].map do |item|
696
785
  deparse_item(item, :select)
697
786
  end.join(', ')
@@ -754,6 +843,30 @@ class PgQuery
754
843
  output.join(' ')
755
844
  end
756
845
 
846
+ def deparse_sql_value_function(node)
847
+ output = []
848
+ lookup = [
849
+ 'current_date',
850
+ 'current_time',
851
+ 'current_time', # with precision
852
+ 'current_timestamp',
853
+ 'current_timestamp', # with precision
854
+ 'localtime',
855
+ 'localtime', # with precision
856
+ 'localtimestamp',
857
+ 'localtimestamp', # with precision
858
+ 'current_role',
859
+ 'current_user',
860
+ 'session_user',
861
+ 'user',
862
+ 'current_catalog',
863
+ 'current_schema'
864
+ ]
865
+ output << lookup[node['op']]
866
+ output << "(#{node['typmod']})" unless node.fetch('typmod', -1) == -1
867
+ output.join('')
868
+ end
869
+
757
870
  def deparse_insert_into(node)
758
871
  output = []
759
872
  output << deparse_item(node['withClause']) if node['withClause']
@@ -781,9 +894,10 @@ class PgQuery
781
894
 
782
895
  if node[TARGET_LIST_FIELD]
783
896
  output << 'SET'
784
- node[TARGET_LIST_FIELD].each do |item|
785
- output << deparse_item(item, :update)
897
+ columns = node[TARGET_LIST_FIELD].map do |item|
898
+ deparse_item(item, :update)
786
899
  end
900
+ output << columns.join(', ')
787
901
  end
788
902
 
789
903
  if node['whereClause']
@@ -984,6 +1098,18 @@ class PgQuery
984
1098
  output.join(' ')
985
1099
  end
986
1100
 
1101
+ def deparse_explain(node)
1102
+ output = ['EXPLAIN']
1103
+ options = node.fetch('options', []).map { |option| option['DefElem']['defname'].upcase }
1104
+ if options.size == 1
1105
+ output.concat(options)
1106
+ elsif options.size > 1
1107
+ output << "(#{options.join(', ')})"
1108
+ end
1109
+ output << deparse_item(node['query'])
1110
+ output.join(' ')
1111
+ end
1112
+
987
1113
  # The PG parser adds several pieces of view data onto the RANGEVAR
988
1114
  # that need to be printed before deparse_rangevar is called.
989
1115
  def relpersistence(rangevar)
@@ -34,6 +34,7 @@ class PgQuery
34
34
  DECLARE_CURSOR_STMT = 'DeclareCursorStmt'.freeze
35
35
  DEF_ELEM = 'DefElem'.freeze
36
36
  DELETE_STMT = 'DeleteStmt'.freeze
37
+ DO_STMT = 'DoStmt'.freeze
37
38
  DROP_STMT = 'DropStmt'.freeze
38
39
  EXECUTE_STMT = 'ExecuteStmt'.freeze
39
40
  EXPLAIN_STMT = 'ExplainStmt'.freeze
@@ -70,6 +71,7 @@ class PgQuery
70
71
  SELECT_STMT = 'SelectStmt'.freeze
71
72
  SET_TO_DEFAULT = 'SetToDefault'.freeze
72
73
  SORT_BY = 'SortBy'.freeze
74
+ SQL_VALUE_FUNCTION = 'SQLValueFunction'.freeze
73
75
  STRING = 'String'.freeze
74
76
  SUB_LINK = 'SubLink'.freeze
75
77
  TRANSACTION_STMT = 'TransactionStmt'.freeze
@@ -1,3 +1,3 @@
1
1
  class PgQuery
2
- VERSION = '1.0.2'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Fittl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-11 00:00:00.000000000 Z
11
+ date: 2018-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -122,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
122
  version: '0'
123
123
  requirements: []
124
124
  rubyforge_project:
125
- rubygems_version: 2.6.8
125
+ rubygems_version: 2.7.6
126
126
  signing_key:
127
127
  specification_version: 4
128
128
  summary: PostgreSQL query parsing and normalization library