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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +54 -1
- data/README.md +25 -2
- data/Rakefile +2 -2
- data/ext/pg_query/include/pg_query_fingerprint_defs.c +8 -0
- data/ext/pg_query/include/pg_query_outfuncs_defs.c +4 -0
- data/ext/pg_query/include/pg_query_readfuncs_defs.c +4 -0
- data/ext/pg_query/include/postgres/copyfuncs.funcs.c +4 -0
- data/ext/pg_query/include/postgres/equalfuncs.funcs.c +4 -0
- data/ext/pg_query/include/postgres/nodes/parsenodes.h +8 -0
- data/ext/pg_query/include/protobuf/pg_query.pb-c.h +282 -278
- data/ext/pg_query/pg_query.pb-c.c +64 -12
- data/ext/pg_query/pg_query_normalize.c +45 -47
- data/ext/pg_query/pg_query_readfuncs_protobuf.c +8 -5
- data/ext/pg_query/pg_query_ruby.c +41 -0
- data/ext/pg_query/postgres_deparse.c +234 -13
- data/ext/pg_query/src_backend_nodes_makefuncs.c +2 -0
- data/ext/pg_query/src_backend_parser_gram.c +30322 -30090
- data/lib/pg_query/fingerprint.rb +6 -0
- data/lib/pg_query/parse.rb +95 -1
- data/lib/pg_query/pg_query_pb.rb +1 -1
- data/lib/pg_query/summary.rb +145 -0
- data/lib/pg_query/version.rb +1 -1
- data/lib/pg_query.rb +1 -0
- metadata +6 -5
|
@@ -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
|
data/lib/pg_query/version.rb
CHANGED
data/lib/pg_query.rb
CHANGED
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.
|
|
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-
|
|
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:
|
|
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:
|
|
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.
|
|
600
|
+
version: '3.2'
|
|
600
601
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
601
602
|
requirements:
|
|
602
603
|
- - ">="
|