pg_query 0.10.0 → 0.11.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
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