pg_query 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2d7e7317e7c022454158d1f8d78a32e2b38fcd6b
4
- data.tar.gz: b123e3e645343e4749520ba80a0efd55f67d9c40
3
+ metadata.gz: 80111a507d64911a62b77017e55feb80a4dad56b
4
+ data.tar.gz: 06887ee5734b6290a5763b942ba1dde1b21fc1b2
5
5
  SHA512:
6
- metadata.gz: c010e9fd04c3546c6351576dea74a18706070a2441e3c550d69a32df2e5c070e287d8ffa2d13e8b06c8e779cb480f55a803327fa3fed9339b4f55d98bbf4b446
7
- data.tar.gz: 092abe2df76fd405523a4bfe5638b5d7b8bb03106cae55ae2b7afacae8e4508b8b4c32a5e7ad90e0c51eaa6c37ef6b804771f7bc9854aa6178d32b681de1bb29
6
+ metadata.gz: cb42f31b99f44ccf66df76cb43d9e82f40a2cd87f5dce4d41d392d4920d00ba4c5d240cb25f7550988e1715e2ccd91dcedc5be8787d0cbc305a3412bd7d9a1c9
7
+ data.tar.gz: bd6c058613222acb36071f847d04afbaba2dbee6c685d52aa914fba1c12e0e86561ea226c75890f16193134426f3ee484d2a984a6fa1a3f9f9183b1db17134de
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.11.0 2016-06-22
4
+
5
+ * Improved table name analysis (#tables method)
6
+ * Don't include CTE names, make them accessible as #cte_names instead [#52](https://github.com/lfittl/pg_query/issues/52)
7
+ * Include table names in target list sub selects [#38](https://github.com/lfittl/pg_query/issues/38)
8
+ * Add support for ORDER/GROUP BY, HAVING, and booleans in WHERE [#53](https://github.com/lfittl/pg_query/pull/53) [@jcoleman](https://github.com/jcoleman)
9
+ * Fix parsing of DROP TYPE statements
10
+
11
+
3
12
  ## 0.10.0 2016-05-31
4
13
 
5
14
  * Based on PostgreSQL 9.5.3
data/README.md CHANGED
@@ -4,7 +4,7 @@ This Ruby extension uses the actual PostgreSQL server source to parse SQL querie
4
4
 
5
5
  In addition the extension allows you to normalize queries (replacing constant values with ?) and parse these normalized queries into a parsetree again.
6
6
 
7
- When you build this extension, it fetches a copy of the PostgreSQL server source and builds parts of it, and then statically links it into this extension.
7
+ When you build this extension, it builds parts of the PostgreSQL server source (see [libpg_query](https://github.com/lfittl/libpg_query)), and then statically links it into this extension.
8
8
 
9
9
  This is slightly crazy, but is the only reliable way of parsing all valid PostgreSQL queries.
10
10
 
@@ -526,6 +526,9 @@ class PgQuery
526
526
  output << expression
527
527
  end
528
528
  output << '(' + deparse_item_list(node['keys']).join(', ') + ')' if node['keys']
529
+ output << '(' + deparse_item_list(node['fk_attrs']).join(', ') + ')' if node['fk_attrs']
530
+ output << 'REFERENCES ' + deparse_item(node['pktable']) + ' (' + deparse_item_list(node['pk_attrs']).join(', ') + ')' if node['pktable']
531
+ output << 'NOT VALID' if node['skip_validation']
529
532
  output << "USING INDEX #{node['indexname']}" if node['indexname']
530
533
  output.join(' ')
531
534
  end
@@ -34,6 +34,11 @@ class PgQuery
34
34
  @tables
35
35
  end
36
36
 
37
+ def cte_names
38
+ load_tables_and_aliases! if @cte_names.nil?
39
+ @cte_names
40
+ end
41
+
37
42
  def aliases
38
43
  load_tables_and_aliases! if @aliases.nil?
39
44
  @aliases
@@ -43,11 +48,12 @@ class PgQuery
43
48
 
44
49
  def load_tables_and_aliases! # rubocop:disable Metrics/CyclomaticComplexity
45
50
  @tables = []
51
+ @cte_names = []
46
52
  @aliases = {}
47
53
 
48
54
  statements = @tree.dup
49
55
  from_clause_items = []
50
- where_clause_items = []
56
+ subselect_items = []
51
57
 
52
58
  loop do
53
59
  statement = statements.shift
@@ -64,9 +70,12 @@ class PgQuery
64
70
  end
65
71
 
66
72
  # CTEs
67
- if statement[SELECT_STMT]['withClause']
68
- statement[SELECT_STMT]['withClause'][WITH_CLAUSE]['ctes'].each do |item|
69
- statements << item[COMMON_TABLE_EXPR]['ctequery'] if item[COMMON_TABLE_EXPR]
73
+ with_clause = statement[SELECT_STMT]['withClause']
74
+ if with_clause
75
+ with_clause[WITH_CLAUSE]['ctes'].each do |item|
76
+ next unless item[COMMON_TABLE_EXPR]
77
+ @cte_names << item[COMMON_TABLE_EXPR]['ctename']
78
+ statements << item[COMMON_TABLE_EXPR]['ctequery']
70
79
  end
71
80
  end
72
81
  elsif statement[SELECT_STMT]['op'] == 1
@@ -99,7 +108,7 @@ class PgQuery
99
108
  # FIXME
100
109
  end
101
110
  when DROP_STMT
102
- objects = statement[DROP_STMT]['objects'].map { |list| list.map { |obj| obj['String']['str'] } }
111
+ objects = statement[DROP_STMT]['objects'].map { |list| list.map { |obj| obj['String'] && obj['String']['str'] } }
103
112
  case statement[DROP_STMT]['removeType']
104
113
  when OBJECT_TYPE_TABLE
105
114
  @tables += objects.map { |r| r.join('.') }
@@ -108,11 +117,17 @@ class PgQuery
108
117
  end
109
118
  end
110
119
 
111
- where_clause_items << statement.values[0]['whereClause'] if !statement.empty? && statement.values[0]['whereClause']
120
+ statement_value = statement.values[0]
121
+ unless statement.empty?
122
+ subselect_items.concat(statement_value['targetList']) if statement_value['targetList']
123
+ subselect_items << statement_value['whereClause'] if statement_value['whereClause']
124
+ subselect_items.concat(statement_value['sortClause'].collect { |h| h[SORT_BY]['node'] }) if statement_value['sortClause']
125
+ subselect_items.concat(statement_value['groupClause']) if statement_value['groupClause']
126
+ subselect_items << statement_value['havingClause'] if statement_value['havingClause']
127
+ end
112
128
  end
113
129
 
114
- # Find subselects in WHERE clause
115
- next_item = where_clause_items.shift
130
+ next_item = subselect_items.shift
116
131
  if next_item
117
132
  case next_item.keys[0]
118
133
  when A_EXPR
@@ -120,17 +135,21 @@ class PgQuery
120
135
  elem = next_item.values[0][side]
121
136
  next unless elem
122
137
  if elem.is_a?(Array)
123
- where_clause_items += elem
138
+ subselect_items += elem
124
139
  else
125
- where_clause_items << elem
140
+ subselect_items << elem
126
141
  end
127
142
  end
143
+ when BOOL_EXPR
144
+ subselect_items.concat(next_item.values[0]['args'])
145
+ when RES_TARGET
146
+ subselect_items << next_item[RES_TARGET]['val']
128
147
  when SUB_LINK
129
148
  statements << next_item[SUB_LINK]['subselect']
130
149
  end
131
150
  end
132
151
 
133
- break if where_clause_items.empty? && statements.empty?
152
+ break if subselect_items.empty? && statements.empty?
134
153
  end
135
154
 
136
155
  loop do
@@ -146,6 +165,8 @@ class PgQuery
146
165
  from_clause_items += next_item[ROW_EXPR]['args']
147
166
  when RANGE_VAR
148
167
  rangevar = next_item[RANGE_VAR]
168
+ next if !rangevar['schemaname'] && @cte_names.include?(rangevar['relname'])
169
+
149
170
  table = [rangevar['schemaname'], rangevar['relname']].compact.join('.')
150
171
  @tables << table
151
172
  @aliases[rangevar['alias'][ALIAS]['aliasname']] = table if rangevar['alias']
@@ -1,3 +1,3 @@
1
1
  class PgQuery
2
- VERSION = '0.10.0'
2
+ VERSION = '0.11.0'
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: 0.10.0
4
+ version: 0.11.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: 2016-06-01 00:00:00.000000000 Z
11
+ date: 2016-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
136
  version: '0'
137
137
  requirements: []
138
138
  rubyforge_project:
139
- rubygems_version: 2.5.1
139
+ rubygems_version: 2.4.5.1
140
140
  signing_key:
141
141
  specification_version: 4
142
142
  summary: PostgreSQL query parsing and normalization library