pg_query 1.0.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +97 -0
- data/README.md +8 -4
- data/Rakefile +3 -3
- data/ext/pg_query/extconf.rb +17 -8
- data/lib/pg_query/deparse.rb +738 -44
- data/lib/pg_query/deparse/keywords.rb +159 -0
- data/lib/pg_query/deparse/rename.rb +41 -0
- data/lib/pg_query/node_types.rb +15 -0
- data/lib/pg_query/parse.rb +3 -0
- data/lib/pg_query/version.rb +1 -1
- metadata +5 -4
@@ -0,0 +1,159 @@
|
|
1
|
+
class PgQuery
|
2
|
+
module Deparse # rubocop:disable Metrics/ModuleLength
|
3
|
+
# Keywords that need to be escaped during deparsing. This matches they keywords
|
4
|
+
# excaped by quote_identifier in Postgres ruleutils.c. You can refresh this
|
5
|
+
# list using the kwlist.h file (make sure to ignore UNRESERVED_KEYWORD entries)
|
6
|
+
KEYWORDS = %w[
|
7
|
+
ALL
|
8
|
+
ANALYSE
|
9
|
+
ANALYZE
|
10
|
+
AND
|
11
|
+
ANY
|
12
|
+
ARRAY
|
13
|
+
AS
|
14
|
+
ASC
|
15
|
+
ASYMMETRIC
|
16
|
+
AUTHORIZATION
|
17
|
+
BETWEEN
|
18
|
+
BIGINT
|
19
|
+
BINARY
|
20
|
+
BIT
|
21
|
+
BOOLEAN
|
22
|
+
BOTH
|
23
|
+
CASE
|
24
|
+
CAST
|
25
|
+
CHAR
|
26
|
+
CHARACTER
|
27
|
+
CHECK
|
28
|
+
COALESCE
|
29
|
+
COLLATE
|
30
|
+
COLLATION
|
31
|
+
COLUMN
|
32
|
+
CONCURRENTLY
|
33
|
+
CONSTRAINT
|
34
|
+
CREATE
|
35
|
+
CROSS
|
36
|
+
CURRENT_CATALOG
|
37
|
+
CURRENT_DATE
|
38
|
+
CURRENT_ROLE
|
39
|
+
CURRENT_SCHEMA
|
40
|
+
CURRENT_TIME
|
41
|
+
CURRENT_TIMESTAMP
|
42
|
+
CURRENT_USER
|
43
|
+
DEC
|
44
|
+
DECIMAL
|
45
|
+
DEFAULT
|
46
|
+
DEFERRABLE
|
47
|
+
DESC
|
48
|
+
DISTINCT
|
49
|
+
DO
|
50
|
+
ELSE
|
51
|
+
END
|
52
|
+
EXCEPT
|
53
|
+
EXISTS
|
54
|
+
EXTRACT
|
55
|
+
FALSE
|
56
|
+
FETCH
|
57
|
+
FLOAT
|
58
|
+
FOR
|
59
|
+
FOREIGN
|
60
|
+
FREEZE
|
61
|
+
FROM
|
62
|
+
FULL
|
63
|
+
GRANT
|
64
|
+
GREATEST
|
65
|
+
GROUP
|
66
|
+
GROUPING
|
67
|
+
HAVING
|
68
|
+
ILIKE
|
69
|
+
IN
|
70
|
+
INITIALLY
|
71
|
+
INNER
|
72
|
+
INOUT
|
73
|
+
INT
|
74
|
+
INTEGER
|
75
|
+
INTERSECT
|
76
|
+
INTERVAL
|
77
|
+
INTO
|
78
|
+
IS
|
79
|
+
ISNULL
|
80
|
+
JOIN
|
81
|
+
LATERAL
|
82
|
+
LEADING
|
83
|
+
LEAST
|
84
|
+
LEFT
|
85
|
+
LIKE
|
86
|
+
LIMIT
|
87
|
+
LOCALTIME
|
88
|
+
LOCALTIMESTAMP
|
89
|
+
NATIONAL
|
90
|
+
NATURAL
|
91
|
+
NCHAR
|
92
|
+
NONE
|
93
|
+
NOT
|
94
|
+
NOTNULL
|
95
|
+
NULL
|
96
|
+
NULLIF
|
97
|
+
NUMERIC
|
98
|
+
OFFSET
|
99
|
+
ON
|
100
|
+
ONLY
|
101
|
+
OR
|
102
|
+
ORDER
|
103
|
+
OUT
|
104
|
+
OUTER
|
105
|
+
OVERLAPS
|
106
|
+
OVERLAY
|
107
|
+
PLACING
|
108
|
+
POSITION
|
109
|
+
PRECISION
|
110
|
+
PRIMARY
|
111
|
+
REAL
|
112
|
+
REFERENCES
|
113
|
+
RETURNING
|
114
|
+
RIGHT
|
115
|
+
ROW
|
116
|
+
SELECT
|
117
|
+
SESSION_USER
|
118
|
+
SETOF
|
119
|
+
SIMILAR
|
120
|
+
SMALLINT
|
121
|
+
SOME
|
122
|
+
SUBSTRING
|
123
|
+
SYMMETRIC
|
124
|
+
TABLE
|
125
|
+
TABLESAMPLE
|
126
|
+
THEN
|
127
|
+
TIME
|
128
|
+
TIMESTAMP
|
129
|
+
TO
|
130
|
+
TRAILING
|
131
|
+
TREAT
|
132
|
+
TRIM
|
133
|
+
TRUE
|
134
|
+
UNION
|
135
|
+
UNIQUE
|
136
|
+
USER
|
137
|
+
USING
|
138
|
+
VALUES
|
139
|
+
VARCHAR
|
140
|
+
VARIADIC
|
141
|
+
VERBOSE
|
142
|
+
WHEN
|
143
|
+
WHERE
|
144
|
+
WINDOW
|
145
|
+
WITH
|
146
|
+
XMLATTRIBUTES
|
147
|
+
XMLCONCAT
|
148
|
+
XMLELEMENT
|
149
|
+
XMLEXISTS
|
150
|
+
XMLFOREST
|
151
|
+
XMLNAMESPACES
|
152
|
+
XMLPARSE
|
153
|
+
XMLPI
|
154
|
+
XMLROOT
|
155
|
+
XMLSERIALIZE
|
156
|
+
XMLTABLE
|
157
|
+
].freeze
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class PgQuery
|
2
|
+
module Deparse
|
3
|
+
module Rename
|
4
|
+
# relation, subname and object is the array key in the node.
|
5
|
+
# Array return five value. First is the type like a TRIGGER, TABLE, DOMAIN
|
6
|
+
# Other values may be parameter or SQL key.
|
7
|
+
#
|
8
|
+
# If node['renameType'] is the integer 13 (OBJECT_TYPE_DOMCONSTRAINT),
|
9
|
+
# then return value of this method will be:
|
10
|
+
#
|
11
|
+
# %w[DOMAIN object RENAME CONSTRAINT subname]
|
12
|
+
#
|
13
|
+
# Which will be composed into the SQL as:
|
14
|
+
#
|
15
|
+
# ALTER {type} {name} RENAME CONSTRAINT {subname} TO {newname}
|
16
|
+
#
|
17
|
+
def self.commands(node)
|
18
|
+
action = RENAME_MAPPING[node['renameType']] || raise(format("Can't deparse: %s", node.inspect))
|
19
|
+
PgQuery::Deparse.instance_exec(node, &action)
|
20
|
+
end
|
21
|
+
|
22
|
+
RENAME_MAPPING = {
|
23
|
+
OBJECT_TYPE_CONVERSION => ->(_node) { %w[CONVERSION object RENAME] },
|
24
|
+
OBJECT_TYPE_TABLE => ->(_node) { %w[TABLE relation RENAME] },
|
25
|
+
OBJECT_TYPE_TABCONSTRAINT => ->(_node) { %w[TABLE relation RENAME CONSTRAINT subname] },
|
26
|
+
OBJECT_TYPE_INDEX => ->(_node) { %w[INDEX relation RENAME] },
|
27
|
+
OBJECT_TYPE_MATVIEW => ->(_node) { ['MATERIALIZED VIEW', 'relation', 'RENAME'] },
|
28
|
+
OBJECT_TYPE_TABLESPACE => ->(_node) { %w[TABLESPACE subname RENAME] },
|
29
|
+
OBJECT_TYPE_VIEW => ->(_node) { %w[VIEW relation RENAME] },
|
30
|
+
OBJECT_TYPE_COLUMN => ->(_node) { %w[TABLE relation RENAME COLUMN subname] },
|
31
|
+
OBJECT_TYPE_COLLATION => ->(_node) { %w[COLLATION object RENAME] },
|
32
|
+
OBJECT_TYPE_TYPE => ->(_node) { %w[TYPE object RENAME] },
|
33
|
+
OBJECT_TYPE_DOMCONSTRAINT => ->(_node) { %w[DOMAIN object RENAME CONSTRAINT subname] },
|
34
|
+
OBJECT_TYPE_RULE => ->(_node) { %w[RULE subname ON relation RENAME] },
|
35
|
+
OBJECT_TYPE_TRIGGER => ->(_node) { %w[TRIGGER subname ON relation RENAME] },
|
36
|
+
OBJECT_TYPE_AGGREGATE => ->(_node) { %w[AGGREGATE object RENAME] },
|
37
|
+
OBJECT_TYPE_FUNCTION => ->(_node) { %w[FUNCTION object RENAME] }
|
38
|
+
}.freeze
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/pg_query/node_types.rb
CHANGED
@@ -20,12 +20,18 @@ class PgQuery
|
|
20
20
|
CHECK_POINT_STMT = 'CheckPointStmt'.freeze
|
21
21
|
CLOSE_PORTAL_STMT = 'ClosePortalStmt'.freeze
|
22
22
|
COALESCE_EXPR = 'CoalesceExpr'.freeze
|
23
|
+
COLLATE_CLAUSE = 'CollateClause'.freeze
|
23
24
|
COLUMN_DEF = 'ColumnDef'.freeze
|
24
25
|
COLUMN_REF = 'ColumnRef'.freeze
|
25
26
|
COMMON_TABLE_EXPR = 'CommonTableExpr'.freeze
|
27
|
+
COMPOSITE_TYPE_STMT = 'CompositeTypeStmt'.freeze
|
26
28
|
CONSTRAINT = 'Constraint'.freeze
|
27
29
|
COPY_STMT = 'CopyStmt'.freeze
|
30
|
+
CREATE_CAST_STMT = 'CreateCastStmt'.freeze
|
31
|
+
CREATE_DOMAIN_STMT = 'CreateDomainStmt'.freeze
|
32
|
+
CREATE_ENUM_STMT = 'CreateEnumStmt'.freeze
|
28
33
|
CREATE_FUNCTION_STMT = 'CreateFunctionStmt'.freeze
|
34
|
+
CREATE_RANGE_STMT = 'CreateRangeStmt'.freeze
|
29
35
|
CREATE_SCHEMA_STMT = 'CreateSchemaStmt'.freeze
|
30
36
|
CREATE_STMT = 'CreateStmt'.freeze
|
31
37
|
CREATE_TABLE_AS_STMT = 'CreateTableAsStmt'.freeze
|
@@ -33,8 +39,14 @@ class PgQuery
|
|
33
39
|
DEALLOCATE_STMT = 'DeallocateStmt'.freeze
|
34
40
|
DECLARE_CURSOR_STMT = 'DeclareCursorStmt'.freeze
|
35
41
|
DEF_ELEM = 'DefElem'.freeze
|
42
|
+
DEFINE_STMT = 'DefineStmt'.freeze
|
36
43
|
DELETE_STMT = 'DeleteStmt'.freeze
|
44
|
+
DISCARD_STMT = 'DiscardStmt'.freeze
|
45
|
+
DO_STMT = 'DoStmt'.freeze
|
37
46
|
DROP_STMT = 'DropStmt'.freeze
|
47
|
+
DROP_SUBSCRIPTION = 'DropSubscriptionStmt'.freeze
|
48
|
+
DROP_TABLESPACE = 'DropTableSpaceStmt'.freeze
|
49
|
+
DROP_ROLE = 'DropRoleStmt'.freeze
|
38
50
|
EXECUTE_STMT = 'ExecuteStmt'.freeze
|
39
51
|
EXPLAIN_STMT = 'ExplainStmt'.freeze
|
40
52
|
FETCH_STMT = 'FetchStmt'.freeze
|
@@ -54,7 +66,9 @@ class PgQuery
|
|
54
66
|
LOCKING_CLAUSE = 'LockingClause'.freeze
|
55
67
|
NULL = 'Null'.freeze
|
56
68
|
NULL_TEST = 'NullTest'.freeze
|
69
|
+
OBJECT_WITH_ARGS = 'ObjectWithArgs'.freeze
|
57
70
|
OID_LIST = 'OidList'.freeze
|
71
|
+
ON_CONFLICT_CLAUSE = 'OnConflictClause'.freeze
|
58
72
|
PARAM_REF = 'ParamRef'.freeze
|
59
73
|
PREPARE_STMT = 'PrepareStmt'.freeze
|
60
74
|
RANGE_FUNCTION = 'RangeFunction'.freeze
|
@@ -70,6 +84,7 @@ class PgQuery
|
|
70
84
|
SELECT_STMT = 'SelectStmt'.freeze
|
71
85
|
SET_TO_DEFAULT = 'SetToDefault'.freeze
|
72
86
|
SORT_BY = 'SortBy'.freeze
|
87
|
+
SQL_VALUE_FUNCTION = 'SQLValueFunction'.freeze
|
73
88
|
STRING = 'String'.freeze
|
74
89
|
SUB_LINK = 'SubLink'.freeze
|
75
90
|
TRANSACTION_STMT = 'TransactionStmt'.freeze
|
data/lib/pg_query/parse.rb
CHANGED
@@ -124,6 +124,9 @@ class PgQuery
|
|
124
124
|
if statement[CREATE_TABLE_AS_STMT]['into'] && statement[CREATE_TABLE_AS_STMT]['into'][INTO_CLAUSE]['rel']
|
125
125
|
from_clause_items << { item: statement[CREATE_TABLE_AS_STMT]['into'][INTO_CLAUSE]['rel'], type: :ddl }
|
126
126
|
end
|
127
|
+
if statement[CREATE_TABLE_AS_STMT]['query']
|
128
|
+
statements << statement[CREATE_TABLE_AS_STMT]['query']
|
129
|
+
end
|
127
130
|
when TRUNCATE_STMT
|
128
131
|
from_clause_items += statement.values[0]['relations'].map { |r| { item: r, type: :ddl } }
|
129
132
|
when VIEW_STMT
|
data/lib/pg_query/version.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: 1.0
|
4
|
+
version: 1.3.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:
|
11
|
+
date: 2020-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -88,6 +88,8 @@ files:
|
|
88
88
|
- lib/pg_query/deparse.rb
|
89
89
|
- lib/pg_query/deparse/alter_table.rb
|
90
90
|
- lib/pg_query/deparse/interval.rb
|
91
|
+
- lib/pg_query/deparse/keywords.rb
|
92
|
+
- lib/pg_query/deparse/rename.rb
|
91
93
|
- lib/pg_query/filter_columns.rb
|
92
94
|
- lib/pg_query/fingerprint.rb
|
93
95
|
- lib/pg_query/legacy_parsetree.rb
|
@@ -121,8 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
123
|
- !ruby/object:Gem::Version
|
122
124
|
version: '0'
|
123
125
|
requirements: []
|
124
|
-
|
125
|
-
rubygems_version: 2.6.13
|
126
|
+
rubygems_version: 3.0.3
|
126
127
|
signing_key:
|
127
128
|
specification_version: 4
|
128
129
|
summary: PostgreSQL query parsing and normalization library
|