pg_query 6.2.2 → 6.2.5

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.
@@ -0,0 +1,145 @@
1
+ module PgQuery
2
+ # Parses the given SQL statement and returns a summary of it.
3
+ #
4
+ # It is possible to gather the same information using PgQuery.parse and
5
+ # walking the parse tree, but summary does this work in C, and only sends
6
+ # the summarized information over protobuf. Avoiding sending the full parse
7
+ # tree over protobuf can be significantly faster for large queries.
8
+ #
9
+ # Note that truncation happens on the C side, and so the maximum length has
10
+ # to be passed in ahead of time. summary(query, truncate_limit: 100).truncated_query
11
+ # is the equivalent of parse(query).truncate(100).
12
+ def self.summary(query, truncate_limit: -1)
13
+ result, stderr = _raw_summary(query, truncate_limit)
14
+
15
+ begin
16
+ result = PgQuery::SummaryResult.decode(result)
17
+ rescue Google::Protobuf::ParseError => e
18
+ raise PgQuery::ParseError.new(format('Failed to parse summary: %s', e.message), __FILE__, __LINE__, -1)
19
+ end
20
+
21
+ warnings = []
22
+ stderr.each_line do |line|
23
+ next unless line[/^WARNING/]
24
+ warnings << line.strip
25
+ end
26
+
27
+ PgQuery::SummaryParserResult.new(query, result, warnings, truncate_limit)
28
+ end
29
+
30
+ # Result of PgQuery.summary.
31
+ #
32
+ # Where possible this is API compatible with ParserResult, with these caveats:
33
+ #
34
+ # - tables_with_details omits the location, inh and relpersistence values that
35
+ # ParserResult reports, since the summary does not carry them
36
+ # - filter_columns only covers the WHERE clause of SELECT statements, so unlike
37
+ # ParserResult#filter_columns it does not include JOIN conditions, or the WHERE
38
+ # clause of UPDATE/DELETE statements
39
+ # - functions_with_details additionally returns the schema name and the bare
40
+ # function name, which ParserResult does not provide
41
+ # - statement_types has no ParserResult equivalent, returns the statement types of
42
+ # the query, e.g. ["SelectStmt"]
43
+ # - truncated_query is offered instead of ParserResult#truncate(max_length), since
44
+ # truncation has already happened when the result is returned - it returns nil if
45
+ # no truncate_limit was passed to PgQuery.summary
46
+ #
47
+ # The underlying protobuf message is available through #protobuf.
48
+ class SummaryParserResult
49
+ attr_reader :query, :protobuf, :warnings
50
+
51
+ def initialize(query, protobuf, warnings = [], truncate_limit = -1)
52
+ @query = query
53
+ @protobuf = protobuf
54
+ @warnings = warnings
55
+ @truncate_limit = truncate_limit
56
+ end
57
+
58
+ def tables
59
+ tables_with_details.map { |t| t[:name] }.uniq
60
+ end
61
+
62
+ def select_tables
63
+ tables_with_details.select { |t| t[:type] == :select }.map { |t| t[:name] }.uniq
64
+ end
65
+
66
+ def dml_tables
67
+ tables_with_details.select { |t| t[:type] == :dml }.map { |t| t[:name] }.uniq
68
+ end
69
+
70
+ def ddl_tables
71
+ tables_with_details.select { |t| t[:type] == :ddl }.map { |t| t[:name] }.uniq
72
+ end
73
+
74
+ def functions
75
+ functions_with_details.map { |f| f[:function] }.uniq
76
+ end
77
+
78
+ def ddl_functions
79
+ functions_with_details.select { |f| f[:type] == :ddl }.map { |f| f[:function] }.uniq
80
+ end
81
+
82
+ def call_functions
83
+ functions_with_details.select { |f| f[:type] == :call }.map { |f| f[:function] }.uniq
84
+ end
85
+
86
+ def cte_names
87
+ @cte_names ||= @protobuf.cte_names.to_a.uniq
88
+ end
89
+
90
+ def aliases
91
+ @aliases ||= @protobuf.aliases.to_h
92
+ end
93
+
94
+ def tables_with_details
95
+ @tables_with_details ||= @protobuf.tables.map do |table|
96
+ {
97
+ name: table.name,
98
+ type: context_to_type(table.context),
99
+ schemaname: (table.schema_name unless table.schema_name.empty?),
100
+ relname: table.table_name
101
+ }
102
+ end.uniq
103
+ end
104
+
105
+ def functions_with_details
106
+ @functions_with_details ||= @protobuf.functions.map do |function|
107
+ {
108
+ function: function.name,
109
+ type: context_to_type(function.context),
110
+ schemaname: (function.schema_name unless function.schema_name.empty?),
111
+ funcname: function.function_name
112
+ }
113
+ end.uniq
114
+ end
115
+
116
+ def filter_columns
117
+ @filter_columns ||= @protobuf.filter_columns.map do |filter_column|
118
+ table = [filter_column.schema_name, filter_column.table_name].reject(&:empty?).join('.')
119
+ table = nil if table.empty?
120
+ [aliases[table] || table, filter_column.column]
121
+ end.uniq
122
+ end
123
+
124
+ def statement_types
125
+ @statement_types ||= @protobuf.statement_types.to_a
126
+ end
127
+
128
+ def truncated_query
129
+ @protobuf.truncated_query unless @truncate_limit == -1
130
+ end
131
+
132
+ private
133
+
134
+ CONTEXT_TYPES = {
135
+ Select: :select,
136
+ DML: :dml,
137
+ DDL: :ddl,
138
+ Call: :call
139
+ }.freeze
140
+
141
+ def context_to_type(context)
142
+ CONTEXT_TYPES[context]
143
+ end
144
+ end
145
+ end
@@ -1,3 +1,3 @@
1
1
  module PgQuery
2
- VERSION = '6.2.2'.freeze
2
+ VERSION = '6.2.5'.freeze
3
3
  end
data/lib/pg_query.rb CHANGED
@@ -17,3 +17,4 @@ require 'pg_query/truncate'
17
17
 
18
18
  require 'pg_query/scan'
19
19
  require 'pg_query/split'
20
+ require 'pg_query/summary'
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: 6.2.2
4
+ version: 6.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Fittl
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-01-27 00:00:00.000000000 Z
11
+ date: 2026-09-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.25.3
19
+ version: 4.34.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.25.3
26
+ version: 4.34.0
27
27
  description: Parses SQL queries using a copy of the PostgreSQL server query parser
28
28
  email: lukas@fittl.com
29
29
  executables: []
@@ -576,6 +576,7 @@ files:
576
576
  - lib/pg_query/pg_query_pb.rb
577
577
  - lib/pg_query/scan.rb
578
578
  - lib/pg_query/split.rb
579
+ - lib/pg_query/summary.rb
579
580
  - lib/pg_query/treewalker.rb
580
581
  - lib/pg_query/truncate.rb
581
582
  - lib/pg_query/version.rb
@@ -596,7 +597,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
596
597
  requirements:
597
598
  - - ">="
598
599
  - !ruby/object:Gem::Version
599
- version: '3.0'
600
+ version: '3.2'
600
601
  required_rubygems_version: !ruby/object:Gem::Requirement
601
602
  requirements:
602
603
  - - ">="