pg_query 1.1.0 → 2.0.1

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.
Files changed (478) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +163 -52
  3. data/README.md +80 -69
  4. data/Rakefile +82 -1
  5. data/ext/pg_query/extconf.rb +3 -31
  6. data/ext/pg_query/guc-file.c +0 -0
  7. data/ext/pg_query/include/access/amapi.h +246 -0
  8. data/ext/pg_query/include/access/attmap.h +52 -0
  9. data/ext/pg_query/include/access/attnum.h +64 -0
  10. data/ext/pg_query/include/access/clog.h +61 -0
  11. data/ext/pg_query/include/access/commit_ts.h +77 -0
  12. data/ext/pg_query/include/access/detoast.h +92 -0
  13. data/ext/pg_query/include/access/genam.h +228 -0
  14. data/ext/pg_query/include/access/gin.h +78 -0
  15. data/ext/pg_query/include/access/htup.h +89 -0
  16. data/ext/pg_query/include/access/htup_details.h +819 -0
  17. data/ext/pg_query/include/access/itup.h +161 -0
  18. data/ext/pg_query/include/access/parallel.h +82 -0
  19. data/ext/pg_query/include/access/printtup.h +35 -0
  20. data/ext/pg_query/include/access/relation.h +28 -0
  21. data/ext/pg_query/include/access/relscan.h +176 -0
  22. data/ext/pg_query/include/access/rmgr.h +35 -0
  23. data/ext/pg_query/include/access/rmgrlist.h +49 -0
  24. data/ext/pg_query/include/access/sdir.h +58 -0
  25. data/ext/pg_query/include/access/skey.h +151 -0
  26. data/ext/pg_query/include/access/stratnum.h +83 -0
  27. data/ext/pg_query/include/access/sysattr.h +29 -0
  28. data/ext/pg_query/include/access/table.h +27 -0
  29. data/ext/pg_query/include/access/tableam.h +1825 -0
  30. data/ext/pg_query/include/access/transam.h +265 -0
  31. data/ext/pg_query/include/access/tupconvert.h +51 -0
  32. data/ext/pg_query/include/access/tupdesc.h +154 -0
  33. data/ext/pg_query/include/access/tupmacs.h +247 -0
  34. data/ext/pg_query/include/access/twophase.h +61 -0
  35. data/ext/pg_query/include/access/xact.h +463 -0
  36. data/ext/pg_query/include/access/xlog.h +398 -0
  37. data/ext/pg_query/include/access/xlog_internal.h +330 -0
  38. data/ext/pg_query/include/access/xlogdefs.h +109 -0
  39. data/ext/pg_query/include/access/xloginsert.h +64 -0
  40. data/ext/pg_query/include/access/xlogreader.h +327 -0
  41. data/ext/pg_query/include/access/xlogrecord.h +227 -0
  42. data/ext/pg_query/include/bootstrap/bootstrap.h +62 -0
  43. data/ext/pg_query/include/c.h +1322 -0
  44. data/ext/pg_query/include/catalog/catalog.h +42 -0
  45. data/ext/pg_query/include/catalog/catversion.h +58 -0
  46. data/ext/pg_query/include/catalog/dependency.h +275 -0
  47. data/ext/pg_query/include/catalog/genbki.h +64 -0
  48. data/ext/pg_query/include/catalog/index.h +199 -0
  49. data/ext/pg_query/include/catalog/indexing.h +366 -0
  50. data/ext/pg_query/include/catalog/namespace.h +188 -0
  51. data/ext/pg_query/include/catalog/objectaccess.h +197 -0
  52. data/ext/pg_query/include/catalog/objectaddress.h +84 -0
  53. data/ext/pg_query/include/catalog/pg_aggregate.h +176 -0
  54. data/ext/pg_query/include/catalog/pg_aggregate_d.h +77 -0
  55. data/ext/pg_query/include/catalog/pg_am.h +60 -0
  56. data/ext/pg_query/include/catalog/pg_am_d.h +45 -0
  57. data/ext/pg_query/include/catalog/pg_attribute.h +204 -0
  58. data/ext/pg_query/include/catalog/pg_attribute_d.h +59 -0
  59. data/ext/pg_query/include/catalog/pg_authid.h +58 -0
  60. data/ext/pg_query/include/catalog/pg_authid_d.h +49 -0
  61. data/ext/pg_query/include/catalog/pg_class.h +200 -0
  62. data/ext/pg_query/include/catalog/pg_class_d.h +103 -0
  63. data/ext/pg_query/include/catalog/pg_collation.h +73 -0
  64. data/ext/pg_query/include/catalog/pg_collation_d.h +45 -0
  65. data/ext/pg_query/include/catalog/pg_constraint.h +247 -0
  66. data/ext/pg_query/include/catalog/pg_constraint_d.h +67 -0
  67. data/ext/pg_query/include/catalog/pg_control.h +250 -0
  68. data/ext/pg_query/include/catalog/pg_conversion.h +72 -0
  69. data/ext/pg_query/include/catalog/pg_conversion_d.h +35 -0
  70. data/ext/pg_query/include/catalog/pg_depend.h +73 -0
  71. data/ext/pg_query/include/catalog/pg_depend_d.h +34 -0
  72. data/ext/pg_query/include/catalog/pg_event_trigger.h +51 -0
  73. data/ext/pg_query/include/catalog/pg_event_trigger_d.h +34 -0
  74. data/ext/pg_query/include/catalog/pg_index.h +80 -0
  75. data/ext/pg_query/include/catalog/pg_index_d.h +56 -0
  76. data/ext/pg_query/include/catalog/pg_language.h +67 -0
  77. data/ext/pg_query/include/catalog/pg_language_d.h +39 -0
  78. data/ext/pg_query/include/catalog/pg_namespace.h +59 -0
  79. data/ext/pg_query/include/catalog/pg_namespace_d.h +34 -0
  80. data/ext/pg_query/include/catalog/pg_opclass.h +85 -0
  81. data/ext/pg_query/include/catalog/pg_opclass_d.h +49 -0
  82. data/ext/pg_query/include/catalog/pg_operator.h +102 -0
  83. data/ext/pg_query/include/catalog/pg_operator_d.h +106 -0
  84. data/ext/pg_query/include/catalog/pg_opfamily.h +60 -0
  85. data/ext/pg_query/include/catalog/pg_opfamily_d.h +47 -0
  86. data/ext/pg_query/include/catalog/pg_partitioned_table.h +63 -0
  87. data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +35 -0
  88. data/ext/pg_query/include/catalog/pg_proc.h +211 -0
  89. data/ext/pg_query/include/catalog/pg_proc_d.h +99 -0
  90. data/ext/pg_query/include/catalog/pg_publication.h +115 -0
  91. data/ext/pg_query/include/catalog/pg_publication_d.h +36 -0
  92. data/ext/pg_query/include/catalog/pg_replication_origin.h +57 -0
  93. data/ext/pg_query/include/catalog/pg_replication_origin_d.h +29 -0
  94. data/ext/pg_query/include/catalog/pg_statistic.h +275 -0
  95. data/ext/pg_query/include/catalog/pg_statistic_d.h +194 -0
  96. data/ext/pg_query/include/catalog/pg_statistic_ext.h +74 -0
  97. data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +40 -0
  98. data/ext/pg_query/include/catalog/pg_transform.h +45 -0
  99. data/ext/pg_query/include/catalog/pg_transform_d.h +32 -0
  100. data/ext/pg_query/include/catalog/pg_trigger.h +137 -0
  101. data/ext/pg_query/include/catalog/pg_trigger_d.h +106 -0
  102. data/ext/pg_query/include/catalog/pg_ts_config.h +50 -0
  103. data/ext/pg_query/include/catalog/pg_ts_config_d.h +32 -0
  104. data/ext/pg_query/include/catalog/pg_ts_dict.h +54 -0
  105. data/ext/pg_query/include/catalog/pg_ts_dict_d.h +33 -0
  106. data/ext/pg_query/include/catalog/pg_ts_parser.h +57 -0
  107. data/ext/pg_query/include/catalog/pg_ts_parser_d.h +35 -0
  108. data/ext/pg_query/include/catalog/pg_ts_template.h +48 -0
  109. data/ext/pg_query/include/catalog/pg_ts_template_d.h +32 -0
  110. data/ext/pg_query/include/catalog/pg_type.h +372 -0
  111. data/ext/pg_query/include/catalog/pg_type_d.h +285 -0
  112. data/ext/pg_query/include/catalog/storage.h +48 -0
  113. data/ext/pg_query/include/commands/async.h +54 -0
  114. data/ext/pg_query/include/commands/dbcommands.h +35 -0
  115. data/ext/pg_query/include/commands/defrem.h +173 -0
  116. data/ext/pg_query/include/commands/event_trigger.h +88 -0
  117. data/ext/pg_query/include/commands/explain.h +127 -0
  118. data/ext/pg_query/include/commands/prepare.h +61 -0
  119. data/ext/pg_query/include/commands/tablespace.h +67 -0
  120. data/ext/pg_query/include/commands/trigger.h +277 -0
  121. data/ext/pg_query/include/commands/user.h +37 -0
  122. data/ext/pg_query/include/commands/vacuum.h +293 -0
  123. data/ext/pg_query/include/commands/variable.h +38 -0
  124. data/ext/pg_query/include/common/file_perm.h +56 -0
  125. data/ext/pg_query/include/common/hashfn.h +104 -0
  126. data/ext/pg_query/include/common/ip.h +37 -0
  127. data/ext/pg_query/include/common/keywords.h +33 -0
  128. data/ext/pg_query/include/common/kwlookup.h +44 -0
  129. data/ext/pg_query/include/common/relpath.h +90 -0
  130. data/ext/pg_query/include/common/string.h +19 -0
  131. data/ext/pg_query/include/common/unicode_combining_table.h +196 -0
  132. data/ext/pg_query/include/datatype/timestamp.h +197 -0
  133. data/ext/pg_query/include/executor/execdesc.h +70 -0
  134. data/ext/pg_query/include/executor/executor.h +614 -0
  135. data/ext/pg_query/include/executor/functions.h +41 -0
  136. data/ext/pg_query/include/executor/instrument.h +101 -0
  137. data/ext/pg_query/include/executor/spi.h +175 -0
  138. data/ext/pg_query/include/executor/tablefunc.h +67 -0
  139. data/ext/pg_query/include/executor/tuptable.h +487 -0
  140. data/ext/pg_query/include/fmgr.h +775 -0
  141. data/ext/pg_query/include/funcapi.h +348 -0
  142. data/ext/pg_query/include/getaddrinfo.h +162 -0
  143. data/ext/pg_query/include/jit/jit.h +105 -0
  144. data/ext/pg_query/include/kwlist_d.h +1072 -0
  145. data/ext/pg_query/include/lib/ilist.h +727 -0
  146. data/ext/pg_query/include/lib/pairingheap.h +102 -0
  147. data/ext/pg_query/include/lib/simplehash.h +1059 -0
  148. data/ext/pg_query/include/lib/stringinfo.h +161 -0
  149. data/ext/pg_query/include/libpq/auth.h +29 -0
  150. data/ext/pg_query/include/libpq/crypt.h +46 -0
  151. data/ext/pg_query/include/libpq/hba.h +140 -0
  152. data/ext/pg_query/include/libpq/libpq-be.h +326 -0
  153. data/ext/pg_query/include/libpq/libpq.h +133 -0
  154. data/ext/pg_query/include/libpq/pqcomm.h +208 -0
  155. data/ext/pg_query/include/libpq/pqformat.h +210 -0
  156. data/ext/pg_query/include/libpq/pqsignal.h +42 -0
  157. data/ext/pg_query/include/mb/pg_wchar.h +672 -0
  158. data/ext/pg_query/include/mb/stringinfo_mb.h +24 -0
  159. data/ext/pg_query/include/miscadmin.h +476 -0
  160. data/ext/pg_query/include/nodes/bitmapset.h +122 -0
  161. data/ext/pg_query/include/nodes/execnodes.h +2520 -0
  162. data/ext/pg_query/include/nodes/extensible.h +160 -0
  163. data/ext/pg_query/include/nodes/lockoptions.h +61 -0
  164. data/ext/pg_query/include/nodes/makefuncs.h +108 -0
  165. data/ext/pg_query/include/nodes/memnodes.h +108 -0
  166. data/ext/pg_query/include/nodes/nodeFuncs.h +162 -0
  167. data/ext/pg_query/include/nodes/nodes.h +842 -0
  168. data/ext/pg_query/include/nodes/params.h +170 -0
  169. data/ext/pg_query/include/nodes/parsenodes.h +3579 -0
  170. data/ext/pg_query/include/nodes/pathnodes.h +2556 -0
  171. data/ext/pg_query/include/nodes/pg_list.h +605 -0
  172. data/ext/pg_query/include/nodes/plannodes.h +1251 -0
  173. data/ext/pg_query/include/nodes/primnodes.h +1541 -0
  174. data/ext/pg_query/include/nodes/print.h +34 -0
  175. data/ext/pg_query/include/nodes/tidbitmap.h +75 -0
  176. data/ext/pg_query/include/nodes/value.h +61 -0
  177. data/ext/pg_query/include/optimizer/cost.h +206 -0
  178. data/ext/pg_query/include/optimizer/geqo.h +88 -0
  179. data/ext/pg_query/include/optimizer/geqo_gene.h +45 -0
  180. data/ext/pg_query/include/optimizer/optimizer.h +199 -0
  181. data/ext/pg_query/include/optimizer/paths.h +249 -0
  182. data/ext/pg_query/include/optimizer/planmain.h +119 -0
  183. data/ext/pg_query/include/parser/analyze.h +49 -0
  184. data/ext/pg_query/include/parser/gram.h +1067 -0
  185. data/ext/pg_query/include/parser/gramparse.h +75 -0
  186. data/ext/pg_query/include/parser/kwlist.h +477 -0
  187. data/ext/pg_query/include/parser/parse_agg.h +68 -0
  188. data/ext/pg_query/include/parser/parse_clause.h +54 -0
  189. data/ext/pg_query/include/parser/parse_coerce.h +97 -0
  190. data/ext/pg_query/include/parser/parse_collate.h +27 -0
  191. data/ext/pg_query/include/parser/parse_expr.h +26 -0
  192. data/ext/pg_query/include/parser/parse_func.h +73 -0
  193. data/ext/pg_query/include/parser/parse_node.h +327 -0
  194. data/ext/pg_query/include/parser/parse_oper.h +67 -0
  195. data/ext/pg_query/include/parser/parse_relation.h +123 -0
  196. data/ext/pg_query/include/parser/parse_target.h +46 -0
  197. data/ext/pg_query/include/parser/parse_type.h +60 -0
  198. data/ext/pg_query/include/parser/parser.h +41 -0
  199. data/ext/pg_query/include/parser/parsetree.h +61 -0
  200. data/ext/pg_query/include/parser/scanner.h +152 -0
  201. data/ext/pg_query/include/parser/scansup.h +30 -0
  202. data/ext/pg_query/include/partitioning/partdefs.h +26 -0
  203. data/ext/pg_query/include/pg_config.h +988 -0
  204. data/ext/pg_query/include/pg_config_ext.h +8 -0
  205. data/ext/pg_query/include/pg_config_manual.h +350 -0
  206. data/ext/pg_query/include/pg_config_os.h +8 -0
  207. data/ext/pg_query/include/pg_getopt.h +56 -0
  208. data/ext/pg_query/include/pg_query.h +121 -0
  209. data/ext/pg_query/include/pg_query_enum_defs.c +2454 -0
  210. data/ext/pg_query/include/pg_query_fingerprint_conds.c +875 -0
  211. data/ext/pg_query/include/pg_query_fingerprint_defs.c +12413 -0
  212. data/ext/pg_query/include/pg_query_json_helper.c +61 -0
  213. data/ext/pg_query/include/pg_query_outfuncs_conds.c +686 -0
  214. data/ext/pg_query/include/pg_query_outfuncs_defs.c +2437 -0
  215. data/ext/pg_query/include/pg_query_readfuncs_conds.c +222 -0
  216. data/ext/pg_query/include/pg_query_readfuncs_defs.c +2878 -0
  217. data/ext/pg_query/include/pg_trace.h +17 -0
  218. data/ext/pg_query/include/pgstat.h +1487 -0
  219. data/ext/pg_query/include/pgtime.h +84 -0
  220. data/ext/pg_query/include/pl_gram.h +385 -0
  221. data/ext/pg_query/include/pl_reserved_kwlist.h +52 -0
  222. data/ext/pg_query/include/pl_reserved_kwlist_d.h +114 -0
  223. data/ext/pg_query/include/pl_unreserved_kwlist.h +112 -0
  224. data/ext/pg_query/include/pl_unreserved_kwlist_d.h +246 -0
  225. data/ext/pg_query/include/plerrcodes.h +990 -0
  226. data/ext/pg_query/include/plpgsql.h +1347 -0
  227. data/ext/pg_query/include/port.h +524 -0
  228. data/ext/pg_query/include/port/atomics.h +524 -0
  229. data/ext/pg_query/include/port/atomics/arch-arm.h +26 -0
  230. data/ext/pg_query/include/port/atomics/arch-ppc.h +254 -0
  231. data/ext/pg_query/include/port/atomics/arch-x86.h +252 -0
  232. data/ext/pg_query/include/port/atomics/fallback.h +170 -0
  233. data/ext/pg_query/include/port/atomics/generic-gcc.h +286 -0
  234. data/ext/pg_query/include/port/atomics/generic.h +401 -0
  235. data/ext/pg_query/include/port/pg_bitutils.h +226 -0
  236. data/ext/pg_query/include/port/pg_bswap.h +161 -0
  237. data/ext/pg_query/include/port/pg_crc32c.h +101 -0
  238. data/ext/pg_query/include/portability/instr_time.h +256 -0
  239. data/ext/pg_query/include/postgres.h +764 -0
  240. data/ext/pg_query/include/postgres_ext.h +74 -0
  241. data/ext/pg_query/include/postmaster/autovacuum.h +83 -0
  242. data/ext/pg_query/include/postmaster/bgworker.h +161 -0
  243. data/ext/pg_query/include/postmaster/bgworker_internals.h +64 -0
  244. data/ext/pg_query/include/postmaster/bgwriter.h +45 -0
  245. data/ext/pg_query/include/postmaster/fork_process.h +17 -0
  246. data/ext/pg_query/include/postmaster/interrupt.h +32 -0
  247. data/ext/pg_query/include/postmaster/pgarch.h +39 -0
  248. data/ext/pg_query/include/postmaster/postmaster.h +77 -0
  249. data/ext/pg_query/include/postmaster/syslogger.h +98 -0
  250. data/ext/pg_query/include/postmaster/walwriter.h +21 -0
  251. data/ext/pg_query/include/protobuf-c.h +1106 -0
  252. data/ext/pg_query/include/protobuf-c/protobuf-c.h +1106 -0
  253. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +10846 -0
  254. data/ext/pg_query/include/protobuf/pg_query.pb.h +124718 -0
  255. data/ext/pg_query/include/regex/regex.h +184 -0
  256. data/ext/pg_query/include/replication/logicallauncher.h +31 -0
  257. data/ext/pg_query/include/replication/logicalproto.h +110 -0
  258. data/ext/pg_query/include/replication/logicalworker.h +19 -0
  259. data/ext/pg_query/include/replication/origin.h +73 -0
  260. data/ext/pg_query/include/replication/reorderbuffer.h +467 -0
  261. data/ext/pg_query/include/replication/slot.h +219 -0
  262. data/ext/pg_query/include/replication/syncrep.h +115 -0
  263. data/ext/pg_query/include/replication/walreceiver.h +340 -0
  264. data/ext/pg_query/include/replication/walsender.h +74 -0
  265. data/ext/pg_query/include/rewrite/prs2lock.h +46 -0
  266. data/ext/pg_query/include/rewrite/rewriteHandler.h +40 -0
  267. data/ext/pg_query/include/rewrite/rewriteManip.h +87 -0
  268. data/ext/pg_query/include/rewrite/rewriteSupport.h +26 -0
  269. data/ext/pg_query/include/storage/backendid.h +37 -0
  270. data/ext/pg_query/include/storage/block.h +121 -0
  271. data/ext/pg_query/include/storage/buf.h +46 -0
  272. data/ext/pg_query/include/storage/bufmgr.h +292 -0
  273. data/ext/pg_query/include/storage/bufpage.h +459 -0
  274. data/ext/pg_query/include/storage/condition_variable.h +62 -0
  275. data/ext/pg_query/include/storage/dsm.h +61 -0
  276. data/ext/pg_query/include/storage/dsm_impl.h +75 -0
  277. data/ext/pg_query/include/storage/fd.h +168 -0
  278. data/ext/pg_query/include/storage/ipc.h +81 -0
  279. data/ext/pg_query/include/storage/item.h +19 -0
  280. data/ext/pg_query/include/storage/itemid.h +184 -0
  281. data/ext/pg_query/include/storage/itemptr.h +206 -0
  282. data/ext/pg_query/include/storage/large_object.h +100 -0
  283. data/ext/pg_query/include/storage/latch.h +190 -0
  284. data/ext/pg_query/include/storage/lmgr.h +114 -0
  285. data/ext/pg_query/include/storage/lock.h +612 -0
  286. data/ext/pg_query/include/storage/lockdefs.h +59 -0
  287. data/ext/pg_query/include/storage/lwlock.h +232 -0
  288. data/ext/pg_query/include/storage/lwlocknames.h +51 -0
  289. data/ext/pg_query/include/storage/off.h +57 -0
  290. data/ext/pg_query/include/storage/pg_sema.h +61 -0
  291. data/ext/pg_query/include/storage/pg_shmem.h +90 -0
  292. data/ext/pg_query/include/storage/pmsignal.h +94 -0
  293. data/ext/pg_query/include/storage/predicate.h +87 -0
  294. data/ext/pg_query/include/storage/proc.h +333 -0
  295. data/ext/pg_query/include/storage/proclist_types.h +51 -0
  296. data/ext/pg_query/include/storage/procsignal.h +75 -0
  297. data/ext/pg_query/include/storage/relfilenode.h +99 -0
  298. data/ext/pg_query/include/storage/s_lock.h +1047 -0
  299. data/ext/pg_query/include/storage/sharedfileset.h +45 -0
  300. data/ext/pg_query/include/storage/shm_mq.h +85 -0
  301. data/ext/pg_query/include/storage/shm_toc.h +58 -0
  302. data/ext/pg_query/include/storage/shmem.h +81 -0
  303. data/ext/pg_query/include/storage/sinval.h +153 -0
  304. data/ext/pg_query/include/storage/sinvaladt.h +43 -0
  305. data/ext/pg_query/include/storage/smgr.h +109 -0
  306. data/ext/pg_query/include/storage/spin.h +77 -0
  307. data/ext/pg_query/include/storage/standby.h +91 -0
  308. data/ext/pg_query/include/storage/standbydefs.h +74 -0
  309. data/ext/pg_query/include/storage/sync.h +62 -0
  310. data/ext/pg_query/include/tcop/cmdtag.h +58 -0
  311. data/ext/pg_query/include/tcop/cmdtaglist.h +217 -0
  312. data/ext/pg_query/include/tcop/deparse_utility.h +108 -0
  313. data/ext/pg_query/include/tcop/dest.h +149 -0
  314. data/ext/pg_query/include/tcop/fastpath.h +21 -0
  315. data/ext/pg_query/include/tcop/pquery.h +45 -0
  316. data/ext/pg_query/include/tcop/tcopprot.h +89 -0
  317. data/ext/pg_query/include/tcop/utility.h +108 -0
  318. data/ext/pg_query/include/tsearch/ts_cache.h +98 -0
  319. data/ext/pg_query/include/utils/acl.h +312 -0
  320. data/ext/pg_query/include/utils/aclchk_internal.h +45 -0
  321. data/ext/pg_query/include/utils/array.h +458 -0
  322. data/ext/pg_query/include/utils/builtins.h +127 -0
  323. data/ext/pg_query/include/utils/bytea.h +27 -0
  324. data/ext/pg_query/include/utils/catcache.h +231 -0
  325. data/ext/pg_query/include/utils/date.h +90 -0
  326. data/ext/pg_query/include/utils/datetime.h +343 -0
  327. data/ext/pg_query/include/utils/datum.h +68 -0
  328. data/ext/pg_query/include/utils/dsa.h +123 -0
  329. data/ext/pg_query/include/utils/dynahash.h +19 -0
  330. data/ext/pg_query/include/utils/elog.h +439 -0
  331. data/ext/pg_query/include/utils/errcodes.h +352 -0
  332. data/ext/pg_query/include/utils/expandeddatum.h +159 -0
  333. data/ext/pg_query/include/utils/expandedrecord.h +231 -0
  334. data/ext/pg_query/include/utils/float.h +356 -0
  335. data/ext/pg_query/include/utils/fmgroids.h +2657 -0
  336. data/ext/pg_query/include/utils/fmgrprotos.h +2646 -0
  337. data/ext/pg_query/include/utils/fmgrtab.h +48 -0
  338. data/ext/pg_query/include/utils/guc.h +443 -0
  339. data/ext/pg_query/include/utils/guc_tables.h +272 -0
  340. data/ext/pg_query/include/utils/hsearch.h +149 -0
  341. data/ext/pg_query/include/utils/inval.h +64 -0
  342. data/ext/pg_query/include/utils/lsyscache.h +197 -0
  343. data/ext/pg_query/include/utils/memdebug.h +82 -0
  344. data/ext/pg_query/include/utils/memutils.h +225 -0
  345. data/ext/pg_query/include/utils/numeric.h +76 -0
  346. data/ext/pg_query/include/utils/palloc.h +136 -0
  347. data/ext/pg_query/include/utils/partcache.h +102 -0
  348. data/ext/pg_query/include/utils/pg_locale.h +119 -0
  349. data/ext/pg_query/include/utils/pg_lsn.h +29 -0
  350. data/ext/pg_query/include/utils/pidfile.h +56 -0
  351. data/ext/pg_query/include/utils/plancache.h +235 -0
  352. data/ext/pg_query/include/utils/portal.h +241 -0
  353. data/ext/pg_query/include/utils/probes.h +114 -0
  354. data/ext/pg_query/include/utils/ps_status.h +25 -0
  355. data/ext/pg_query/include/utils/queryenvironment.h +74 -0
  356. data/ext/pg_query/include/utils/regproc.h +28 -0
  357. data/ext/pg_query/include/utils/rel.h +644 -0
  358. data/ext/pg_query/include/utils/relcache.h +151 -0
  359. data/ext/pg_query/include/utils/reltrigger.h +81 -0
  360. data/ext/pg_query/include/utils/resowner.h +86 -0
  361. data/ext/pg_query/include/utils/rls.h +50 -0
  362. data/ext/pg_query/include/utils/ruleutils.h +44 -0
  363. data/ext/pg_query/include/utils/sharedtuplestore.h +61 -0
  364. data/ext/pg_query/include/utils/snapmgr.h +158 -0
  365. data/ext/pg_query/include/utils/snapshot.h +206 -0
  366. data/ext/pg_query/include/utils/sortsupport.h +276 -0
  367. data/ext/pg_query/include/utils/syscache.h +219 -0
  368. data/ext/pg_query/include/utils/timeout.h +88 -0
  369. data/ext/pg_query/include/utils/timestamp.h +116 -0
  370. data/ext/pg_query/include/utils/tuplesort.h +277 -0
  371. data/ext/pg_query/include/utils/tuplestore.h +91 -0
  372. data/ext/pg_query/include/utils/typcache.h +202 -0
  373. data/ext/pg_query/include/utils/tzparser.h +39 -0
  374. data/ext/pg_query/include/utils/varlena.h +39 -0
  375. data/ext/pg_query/include/utils/xml.h +84 -0
  376. data/ext/pg_query/include/xxhash.h +5445 -0
  377. data/ext/pg_query/include/xxhash/xxhash.h +5445 -0
  378. data/ext/pg_query/pg_query.c +104 -0
  379. data/ext/pg_query/pg_query.pb-c.c +37628 -0
  380. data/ext/pg_query/pg_query_deparse.c +9953 -0
  381. data/ext/pg_query/pg_query_fingerprint.c +292 -0
  382. data/ext/pg_query/pg_query_fingerprint.h +8 -0
  383. data/ext/pg_query/pg_query_internal.h +24 -0
  384. data/ext/pg_query/pg_query_json_plpgsql.c +738 -0
  385. data/ext/pg_query/pg_query_json_plpgsql.h +9 -0
  386. data/ext/pg_query/pg_query_normalize.c +437 -0
  387. data/ext/pg_query/pg_query_outfuncs.h +10 -0
  388. data/ext/pg_query/pg_query_outfuncs_json.c +297 -0
  389. data/ext/pg_query/pg_query_outfuncs_protobuf.c +237 -0
  390. data/ext/pg_query/pg_query_parse.c +148 -0
  391. data/ext/pg_query/pg_query_parse_plpgsql.c +460 -0
  392. data/ext/pg_query/pg_query_readfuncs.h +11 -0
  393. data/ext/pg_query/pg_query_readfuncs_protobuf.c +142 -0
  394. data/ext/pg_query/pg_query_ruby.c +108 -12
  395. data/ext/pg_query/pg_query_scan.c +173 -0
  396. data/ext/pg_query/pg_query_split.c +221 -0
  397. data/ext/pg_query/protobuf-c.c +3660 -0
  398. data/ext/pg_query/src_backend_catalog_namespace.c +1051 -0
  399. data/ext/pg_query/src_backend_catalog_pg_proc.c +142 -0
  400. data/ext/pg_query/src_backend_commands_define.c +117 -0
  401. data/ext/pg_query/src_backend_libpq_pqcomm.c +651 -0
  402. data/ext/pg_query/src_backend_nodes_bitmapset.c +513 -0
  403. data/ext/pg_query/src_backend_nodes_copyfuncs.c +6013 -0
  404. data/ext/pg_query/src_backend_nodes_equalfuncs.c +4003 -0
  405. data/ext/pg_query/src_backend_nodes_extensible.c +99 -0
  406. data/ext/pg_query/src_backend_nodes_list.c +922 -0
  407. data/ext/pg_query/src_backend_nodes_makefuncs.c +417 -0
  408. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +1363 -0
  409. data/ext/pg_query/src_backend_nodes_value.c +84 -0
  410. data/ext/pg_query/src_backend_parser_gram.c +47456 -0
  411. data/ext/pg_query/src_backend_parser_parse_expr.c +313 -0
  412. data/ext/pg_query/src_backend_parser_parser.c +497 -0
  413. data/ext/pg_query/src_backend_parser_scan.c +7091 -0
  414. data/ext/pg_query/src_backend_parser_scansup.c +160 -0
  415. data/ext/pg_query/src_backend_postmaster_postmaster.c +2230 -0
  416. data/ext/pg_query/src_backend_storage_ipc_ipc.c +192 -0
  417. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +370 -0
  418. data/ext/pg_query/src_backend_tcop_postgres.c +776 -0
  419. data/ext/pg_query/src_backend_utils_adt_datum.c +326 -0
  420. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +98 -0
  421. data/ext/pg_query/src_backend_utils_adt_format_type.c +136 -0
  422. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +1683 -0
  423. data/ext/pg_query/src_backend_utils_error_assert.c +74 -0
  424. data/ext/pg_query/src_backend_utils_error_elog.c +1748 -0
  425. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +570 -0
  426. data/ext/pg_query/src_backend_utils_hash_dynahash.c +1086 -0
  427. data/ext/pg_query/src_backend_utils_init_globals.c +168 -0
  428. data/ext/pg_query/src_backend_utils_mb_mbutils.c +839 -0
  429. data/ext/pg_query/src_backend_utils_misc_guc.c +1831 -0
  430. data/ext/pg_query/src_backend_utils_mmgr_aset.c +1560 -0
  431. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +1006 -0
  432. data/ext/pg_query/src_common_encnames.c +158 -0
  433. data/ext/pg_query/src_common_keywords.c +39 -0
  434. data/ext/pg_query/src_common_kwlist_d.h +1081 -0
  435. data/ext/pg_query/src_common_kwlookup.c +91 -0
  436. data/ext/pg_query/src_common_psprintf.c +158 -0
  437. data/ext/pg_query/src_common_string.c +86 -0
  438. data/ext/pg_query/src_common_stringinfo.c +336 -0
  439. data/ext/pg_query/src_common_wchar.c +1651 -0
  440. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +1133 -0
  441. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +877 -0
  442. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +6533 -0
  443. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +107 -0
  444. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +123 -0
  445. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +671 -0
  446. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +255 -0
  447. data/ext/pg_query/src_port_erand48.c +127 -0
  448. data/ext/pg_query/src_port_pg_bitutils.c +246 -0
  449. data/ext/pg_query/src_port_pgsleep.c +69 -0
  450. data/ext/pg_query/src_port_pgstrcasecmp.c +83 -0
  451. data/ext/pg_query/src_port_qsort.c +240 -0
  452. data/ext/pg_query/src_port_random.c +31 -0
  453. data/ext/pg_query/src_port_snprintf.c +1449 -0
  454. data/ext/pg_query/src_port_strerror.c +324 -0
  455. data/ext/pg_query/src_port_strnlen.c +39 -0
  456. data/ext/pg_query/xxhash.c +43 -0
  457. data/lib/pg_query.rb +7 -4
  458. data/lib/pg_query/constants.rb +21 -0
  459. data/lib/pg_query/deparse.rb +16 -1117
  460. data/lib/pg_query/filter_columns.rb +86 -85
  461. data/lib/pg_query/fingerprint.rb +122 -87
  462. data/lib/pg_query/json_field_names.rb +1402 -0
  463. data/lib/pg_query/node.rb +31 -0
  464. data/lib/pg_query/param_refs.rb +42 -37
  465. data/lib/pg_query/parse.rb +220 -200
  466. data/lib/pg_query/parse_error.rb +1 -1
  467. data/lib/pg_query/pg_query_pb.rb +3211 -0
  468. data/lib/pg_query/scan.rb +23 -0
  469. data/lib/pg_query/treewalker.rb +24 -40
  470. data/lib/pg_query/truncate.rb +64 -43
  471. data/lib/pg_query/version.rb +2 -2
  472. metadata +473 -11
  473. data/ext/pg_query/pg_query_ruby.h +0 -10
  474. data/lib/pg_query/deep_dup.rb +0 -16
  475. data/lib/pg_query/deparse/alter_table.rb +0 -42
  476. data/lib/pg_query/deparse/interval.rb +0 -105
  477. data/lib/pg_query/legacy_parsetree.rb +0 -109
  478. data/lib/pg_query/node_types.rb +0 -284
@@ -1,1123 +1,22 @@
1
- require_relative 'deparse/interval'
2
- require_relative 'deparse/alter_table'
3
- class PgQuery
4
- # Reconstruct all of the parsed queries into their original form
5
- def deparse(tree = @tree)
6
- tree.map do |item|
7
- Deparse.from(item)
8
- end.join('; ')
9
- end
10
-
11
- # rubocop:disable Metrics/ModuleLength
12
- module Deparse
13
- extend self
14
-
15
- # Given one element of the PgQuery#parsetree reconstruct it back into the
16
- # original query.
17
- def from(item)
18
- deparse_item(item)
19
- end
20
-
21
- private
22
-
23
- def deparse_item(item, context = nil) # rubocop:disable Metrics/CyclomaticComplexity
24
- return if item.nil?
25
- return item if item.is_a?(Integer)
26
-
27
- type = item.keys[0]
28
- node = item.values[0]
29
-
30
- case type
31
- when A_EXPR
32
- case node['kind']
33
- when AEXPR_OP
34
- deparse_aexpr(node, context)
35
- when AEXPR_OP_ANY
36
- deparse_aexpr_any(node)
37
- when AEXPR_IN
38
- deparse_aexpr_in(node)
39
- when CONSTR_TYPE_FOREIGN
40
- deparse_aexpr_like(node)
41
- when AEXPR_BETWEEN, AEXPR_NOT_BETWEEN, AEXPR_BETWEEN_SYM, AEXPR_NOT_BETWEEN_SYM
42
- deparse_aexpr_between(node)
43
- when AEXPR_NULLIF
44
- deparse_aexpr_nullif(node)
45
- else
46
- raise format("Can't deparse: %s: %s", type, node.inspect)
47
- end
48
- when ALIAS
49
- deparse_alias(node)
50
- when ALTER_TABLE_STMT
51
- deparse_alter_table(node)
52
- when ALTER_TABLE_CMD
53
- deparse_alter_table_cmd(node)
54
- when A_ARRAY_EXPR
55
- deparse_a_arrayexp(node)
56
- when A_CONST
57
- deparse_a_const(node)
58
- when A_INDICES
59
- deparse_a_indices(node)
60
- when A_INDIRECTION
61
- deparse_a_indirection(node)
62
- when A_STAR
63
- deparse_a_star(node)
64
- when A_TRUNCATED
65
- '...' # pg_query internal
66
- when BOOL_EXPR
67
- case node['boolop']
68
- when BOOL_EXPR_AND
69
- deparse_bool_expr_and(node)
70
- when BOOL_EXPR_OR
71
- deparse_bool_expr_or(node)
72
- when BOOL_EXPR_NOT
73
- deparse_bool_expr_not(node)
74
- end
75
- when BOOLEAN_TEST
76
- deparse_boolean_test(node)
77
- when CASE_EXPR
78
- deparse_case(node)
79
- when COALESCE_EXPR
80
- deparse_coalesce(node)
81
- when COLUMN_DEF
82
- deparse_columndef(node)
83
- when COLUMN_REF
84
- deparse_columnref(node)
85
- when COMMON_TABLE_EXPR
86
- deparse_cte(node)
87
- when CONSTRAINT
88
- deparse_constraint(node)
89
- when COPY_STMT
90
- deparse_copy(node)
91
- when CREATE_FUNCTION_STMT
92
- deparse_create_function(node)
93
- when CREATE_STMT
94
- deparse_create_table(node)
95
- when CREATE_TABLE_AS_STMT
96
- deparse_create_table_as(node)
97
- when INTO_CLAUSE
98
- deparse_into_clause(node)
99
- when DEF_ELEM
100
- deparse_defelem(node)
101
- when DELETE_STMT
102
- deparse_delete_from(node)
103
- when DROP_STMT
104
- deparse_drop(node)
105
- when EXPLAIN_STMT
106
- deparse_explain(node)
107
- when FUNC_CALL
108
- deparse_funccall(node)
109
- when FUNCTION_PARAMETER
110
- deparse_functionparameter(node)
111
- when INSERT_STMT
112
- deparse_insert_into(node)
113
- when JOIN_EXPR
114
- deparse_joinexpr(node)
115
- when LOCK_STMT
116
- deparse_lock(node)
117
- when LOCKING_CLAUSE
118
- deparse_lockingclause(node)
119
- when NULL_TEST
120
- deparse_nulltest(node)
121
- when PARAM_REF
122
- deparse_paramref(node)
123
- when RANGE_FUNCTION
124
- deparse_range_function(node)
125
- when RANGE_SUBSELECT
126
- deparse_rangesubselect(node)
127
- when RANGE_VAR
128
- deparse_rangevar(node)
129
- when RAW_STMT
130
- deparse_raw_stmt(node)
131
- when RENAME_STMT
132
- deparse_renamestmt(node)
133
- when RES_TARGET
134
- deparse_restarget(node, context)
135
- when ROW_EXPR
136
- deparse_row(node)
137
- when SELECT_STMT
138
- deparse_select(node)
139
- when SQL_VALUE_FUNCTION
140
- deparse_sql_value_function(node)
141
- when SORT_BY
142
- deparse_sortby(node)
143
- when SUB_LINK
144
- deparse_sublink(node)
145
- when TRANSACTION_STMT
146
- deparse_transaction(node)
147
- when TYPE_CAST
148
- deparse_typecast(node)
149
- when TYPE_NAME
150
- deparse_typename(node)
151
- when UPDATE_STMT
152
- deparse_update(node)
153
- when CASE_WHEN
154
- deparse_when(node)
155
- when WINDOW_DEF
156
- deparse_windowdef(node)
157
- when WITH_CLAUSE
158
- deparse_with_clause(node)
159
- when VIEW_STMT
160
- deparse_viewstmt(node)
161
- when VARIABLE_SET_STMT
162
- deparse_variable_set_stmt(node)
163
- when VACUUM_STMT
164
- deparse_vacuum_stmt(node)
165
- when DO_STMT
166
- deparse_do_stmt(node)
167
- when STRING
168
- if context == A_CONST
169
- format("'%s'", node['str'].gsub("'", "''"))
170
- elsif [FUNC_CALL, TYPE_NAME, :operator, :defname_as].include?(context)
171
- node['str']
172
- else
173
- format('"%s"', node['str'].gsub('"', '""'))
174
- end
175
- when INTEGER
176
- node['ival'].to_s
177
- when FLOAT
178
- node['str']
179
- when NULL
180
- 'NULL'
181
- else
182
- raise format("Can't deparse: %s: %s", type, node.inspect)
183
- end
184
- end
185
-
186
- def deparse_item_list(nodes, context = nil)
187
- nodes.map { |n| deparse_item(n, context) }
188
- end
189
-
190
- def deparse_rangevar(node)
191
- output = []
192
- output << 'ONLY' unless node['inh']
193
- schema = node['schemaname'] ? '"' + node['schemaname'] + '".' : ''
194
- output << schema + '"' + node['relname'] + '"'
195
- output << deparse_item(node['alias']) if node['alias']
196
- output.join(' ')
197
- end
198
-
199
- def deparse_raw_stmt(node)
200
- deparse_item(node[STMT_FIELD])
201
- end
202
-
203
- def deparse_renamestmt(node)
204
- output = []
205
-
206
- case node['renameType']
207
- when OBJECT_TYPE_TABLE
208
- output << 'ALTER TABLE'
209
- output << deparse_item(node['relation'])
210
- output << 'RENAME TO'
211
- output << node['newname']
212
- else
213
- raise format("Can't deparse: %s", node.inspect)
214
- end
215
-
216
- output.join(' ')
217
- end
218
-
219
- def deparse_columnref(node)
220
- node['fields'].map do |field|
221
- field.is_a?(String) ? '"' + field + '"' : deparse_item(field)
222
- end.join('.')
223
- end
224
-
225
- def deparse_a_arrayexp(node)
226
- 'ARRAY[' + node['elements'].map do |element|
227
- deparse_item(element)
228
- end.join(', ') + ']'
229
- end
230
-
231
- def deparse_a_const(node)
232
- deparse_item(node['val'], A_CONST)
233
- end
234
-
235
- def deparse_a_star(_node)
236
- '*'
237
- end
238
-
239
- def deparse_a_indirection(node)
240
- output = [deparse_item(node['arg'])]
241
- node['indirection'].each do |subnode|
242
- output << deparse_item(subnode)
243
- end
244
- output.join
245
- end
246
-
247
- def deparse_a_indices(node)
248
- format('[%s]', deparse_item(node['uidx']))
249
- end
250
-
251
- def deparse_alias(node)
252
- name = node['aliasname']
253
- if node['colnames']
254
- name + '(' + deparse_item_list(node['colnames']).join(', ') + ')'
255
- else
256
- name
257
- end
258
- end
259
-
260
- def deparse_alter_table(node)
261
- output = []
262
- output << 'ALTER TABLE'
263
-
264
- output << deparse_item(node['relation'])
265
-
266
- output << node['cmds'].map do |item|
267
- deparse_item(item)
268
- end.join(', ')
269
-
270
- output.join(' ')
271
- end
272
-
273
- def deparse_alter_table_cmd(node)
274
- command, options = AlterTable.commands(node)
275
-
276
- output = []
277
- output << command if command
278
- output << 'IF EXISTS' if node['missing_ok']
279
- output << node['name']
280
- output << options if options
281
- output << deparse_item(node['def']) if node['def']
282
- output << 'CASCADE' if node['behavior'] == 1
283
-
284
- output.compact.join(' ')
285
- end
286
-
287
- def deparse_paramref(node)
288
- if node['number'].nil?
289
- '?'
290
- else
291
- format('$%d', node['number'])
292
- end
293
- end
294
-
295
- def deparse_restarget(node, context)
296
- if context == :select
297
- [deparse_item(node['val']), node['name']].compact.join(' AS ')
298
- elsif context == :update
299
- [node['name'], deparse_item(node['val'])].compact.join(' = ')
300
- elsif node['val'].nil?
301
- node['name']
302
- else
303
- raise format("Can't deparse %s in context %s", node.inspect, context)
304
- end
305
- end
306
-
307
- def deparse_funccall(node)
308
- output = []
309
-
310
- # SUM(a, b)
311
- args = Array(node['args']).map { |arg| deparse_item(arg) }
312
- # COUNT(*)
313
- args << '*' if node['agg_star']
314
-
315
- name = (node['funcname'].map { |n| deparse_item(n, FUNC_CALL) } - ['pg_catalog']).join('.')
316
- distinct = node['agg_distinct'] ? 'DISTINCT ' : ''
317
- output << format('%s(%s%s)', name, distinct, args.join(', '))
318
- output << format('OVER (%s)', deparse_item(node['over'])) if node['over']
319
-
320
- output.join(' ')
321
- end
322
-
323
- def deparse_windowdef(node)
324
- output = []
325
-
326
- if node['partitionClause']
327
- output << 'PARTITION BY'
328
- output << node['partitionClause'].map do |item|
329
- deparse_item(item)
330
- end.join(', ')
331
- end
332
-
333
- if node['orderClause']
334
- output << 'ORDER BY'
335
- output << node['orderClause'].map do |item|
336
- deparse_item(item)
337
- end.join(', ')
338
- end
339
-
340
- output.join(' ')
341
- end
342
-
343
- def deparse_functionparameter(node)
344
- deparse_item(node['argType'])
345
- end
346
-
347
- def deparse_aexpr_in(node)
348
- rexpr = Array(node['rexpr']).map { |arg| deparse_item(arg) }
349
- operator = node['name'].map { |n| deparse_item(n, :operator) } == ['='] ? 'IN' : 'NOT IN'
350
- format('%s %s (%s)', deparse_item(node['lexpr']), operator, rexpr.join(', '))
351
- end
352
-
353
- def deparse_aexpr_like(node)
354
- value = deparse_item(node['rexpr'])
355
- operator = node['name'].map { |n| deparse_item(n, :operator) } == ['~~'] ? 'LIKE' : 'NOT LIKE'
356
- format('%s %s %s', deparse_item(node['lexpr']), operator, value)
357
- end
358
-
359
- def deparse_bool_expr_not(node)
360
- format('NOT %s', deparse_item(node['args'][0]))
361
- end
362
-
363
- BOOLEAN_TEST_TYPE_TO_STRING = {
364
- BOOLEAN_TEST_TRUE => ' IS TRUE',
365
- BOOLEAN_TEST_NOT_TRUE => ' IS NOT TRUE',
366
- BOOLEAN_TEST_FALSE => ' IS FALSE',
367
- BOOLEAN_TEST_NOT_FALSE => ' IS NOT FALSE',
368
- BOOLEAN_TEST_UNKNOWN => ' IS UNKNOWN',
369
- BOOLEAN_TEST_NOT_UNKNOWN => ' IS NOT UNKNOWN'
370
- }.freeze
371
- def deparse_boolean_test(node)
372
- deparse_item(node['arg']) + BOOLEAN_TEST_TYPE_TO_STRING[node['booltesttype']]
373
- end
374
-
375
- def deparse_range_function(node)
376
- output = []
377
- output << 'LATERAL' if node['lateral']
378
- output << deparse_item(node['functions'][0][0]) # FIXME: Needs more test cases
379
- output << deparse_item(node['alias']) if node['alias']
380
- output << "#{node['alias'] ? '' : 'AS '}(#{deparse_item_list(node['coldeflist']).join(', ')})" if node['coldeflist']
381
- output.join(' ')
382
- end
383
-
384
- def deparse_aexpr(node, context = false)
385
- output = []
386
- output << deparse_item(node['lexpr'], context || true)
387
- output << deparse_item(node['rexpr'], context || true)
388
- output = output.join(' ' + deparse_item(node['name'][0], :operator) + ' ')
389
- if context
390
- # This is a nested expression, add parentheses.
391
- output = '(' + output + ')'
392
- end
393
- output
394
- end
395
-
396
- def deparse_bool_expr_and(node)
397
- # Only put parantheses around OR nodes that are inside this one
398
- node['args'].map do |arg|
399
- if [BOOL_EXPR_OR].include?(arg.values[0]['boolop'])
400
- format('(%s)', deparse_item(arg))
401
- else
402
- deparse_item(arg)
403
- end
404
- end.join(' AND ')
405
- end
406
-
407
- def deparse_bool_expr_or(node)
408
- # Put parantheses around AND + OR nodes that are inside
409
- node['args'].map do |arg|
410
- if [BOOL_EXPR_AND, BOOL_EXPR_OR].include?(arg.values[0]['boolop'])
411
- format('(%s)', deparse_item(arg))
412
- else
413
- deparse_item(arg)
414
- end
415
- end.join(' OR ')
416
- end
417
-
418
- def deparse_aexpr_any(node)
419
- output = []
420
- output << deparse_item(node['lexpr'])
421
- output << format('ANY(%s)', deparse_item(node['rexpr']))
422
- output.join(' ' + deparse_item(node['name'][0], :operator) + ' ')
423
- end
424
-
425
- def deparse_aexpr_between(node)
426
- between = case node['kind']
427
- when AEXPR_BETWEEN
428
- ' BETWEEN '
429
- when AEXPR_NOT_BETWEEN
430
- ' NOT BETWEEN '
431
- when AEXPR_BETWEEN_SYM
432
- ' BETWEEN SYMMETRIC '
433
- when AEXPR_NOT_BETWEEN_SYM
434
- ' NOT BETWEEN SYMMETRIC '
435
- end
436
- name = deparse_item(node['lexpr'])
437
- output = node['rexpr'].map { |n| deparse_item(n) }
438
- name << between << output.join(' AND ')
439
- end
440
-
441
- def deparse_aexpr_nullif(node)
442
- lexpr = deparse_item(node['lexpr'])
443
- rexpr = deparse_item(node['rexpr'])
444
- format('NULLIF(%s, %s)', lexpr, rexpr)
445
- end
446
-
447
- def deparse_joinexpr(node) # rubocop:disable Metrics/CyclomaticComplexity
448
- output = []
449
- output << deparse_item(node['larg'])
450
- case node['jointype']
451
- when 0
452
- if node['isNatural']
453
- output << 'NATURAL'
454
- elsif node['quals'].nil? && node['usingClause'].nil?
455
- output << 'CROSS'
456
- end
457
- when 1
458
- output << 'LEFT'
459
- when 2
460
- output << 'FULL'
461
- when 3
462
- output << 'RIGHT'
463
- end
464
- output << 'JOIN'
465
- output << deparse_item(node['rarg'])
466
-
467
- if node['quals']
468
- output << 'ON'
469
- output << deparse_item(node['quals'])
470
- end
471
-
472
- output << format('USING (%s)', node['usingClause'].map { |n| deparse_item(n) }.join(', ')) if node['usingClause']
473
-
474
- output.join(' ')
475
- end
476
-
477
- def deparse_lock(node)
478
- output = []
479
- output << 'LOCK TABLE'
480
- tables = node['relations'].map { |table| deparse_item(table) }
481
- output << tables.join(', ')
482
- output.join(' ')
483
- end
484
-
485
- LOCK_CLAUSE_STRENGTH = {
486
- LCS_FORKEYSHARE => 'FOR KEY SHARE',
487
- LCS_FORSHARE => 'FOR SHARE',
488
- LCS_FORNOKEYUPDATE => 'FOR NO KEY UPDATE',
489
- LCS_FORUPDATE => 'FOR UPDATE'
490
- }.freeze
491
- def deparse_lockingclause(node)
492
- output = []
493
- output << LOCK_CLAUSE_STRENGTH[node['strength']]
494
- if node['lockedRels']
495
- output << 'OF'
496
- output << node['lockedRels'].map do |item|
497
- deparse_item(item)
498
- end.join(', ')
499
- end
500
- output.join(' ')
501
- end
502
-
503
- def deparse_sortby(node)
504
- output = []
505
- output << deparse_item(node['node'])
506
- output << 'ASC' if node['sortby_dir'] == 1
507
- output << 'DESC' if node['sortby_dir'] == 2
508
- output << 'NULLS FIRST' if node['sortby_nulls'] == 1
509
- output << 'NULLS LAST' if node['sortby_nulls'] == 2
510
- output.join(' ')
511
- end
512
-
513
- def deparse_with_clause(node)
514
- output = ['WITH']
515
- output << 'RECURSIVE' if node['recursive']
516
- output << node['ctes'].map do |cte|
517
- deparse_item(cte)
518
- end.join(', ')
519
- output.join(' ')
520
- end
521
-
522
- def deparse_viewstmt(node)
523
- output = []
524
- output << 'CREATE'
525
- output << 'OR REPLACE' if node['replace']
526
-
527
- persistence = relpersistence(node['view'])
528
- output << persistence if persistence
529
-
530
- output << 'VIEW'
531
- output << node['view'][RANGE_VAR]['relname']
532
- output << format('(%s)', deparse_item_list(node['aliases']).join(', ')) if node['aliases']
533
-
534
- output << 'AS'
535
- output << deparse_item(node['query'])
536
-
537
- case node['withCheckOption']
538
- when 1
539
- output << 'WITH CHECK OPTION'
540
- when 2
541
- output << 'WITH CASCADED CHECK OPTION'
542
- end
543
- output.join(' ')
544
- end
545
-
546
- def deparse_variable_set_stmt(node)
547
- output = []
548
- output << 'SET'
549
- output << 'LOCAL' if node['is_local']
550
- output << node['name']
551
- output << 'TO'
552
- output << node['args'].map { |arg| deparse_item(arg) }.join(', ')
553
- output.join(' ')
554
- end
555
-
556
- def deparse_vacuum_stmt(node)
557
- output = []
558
- output << 'VACUUM'
559
- output.concat(deparse_vacuum_options(node))
560
- output << deparse_item(node['relation']) if node.key?('relation')
561
- if node.key?('va_cols')
562
- output << "(#{node['va_cols'].map(&method(:deparse_item)).join(', ')})"
563
- end
564
- output.join(' ')
565
- end
566
-
567
- def deparse_vacuum_options(node)
568
- output = []
569
- output << 'FULL' if node['options'][4] == 1
570
- output << 'FREEZE' if node['options'][3] == 1
571
- output << 'VERBOSE' if node['options'][2] == 1
572
- output << 'ANALYZE' if node['options'][1] == 1
573
- output
574
- end
575
-
576
- def deparse_do_stmt(node)
577
- output = []
578
- output << 'DO'
579
- statement, *rest = node['args']
580
- output << "$$#{statement['DefElem']['arg']['String']['str']}$$"
581
- output += rest.map { |item| deparse_item(item) }
582
- output.join(' ')
583
- end
584
-
585
- def deparse_cte(node)
586
- output = []
587
- output << node['ctename']
588
- output << format('(%s)', node['aliascolnames'].map { |n| deparse_item(n) }.join(', ')) if node['aliascolnames']
589
- output << format('AS (%s)', deparse_item(node['ctequery']))
590
- output.join(' ')
1
+ module PgQuery
2
+ class ParserResult
3
+ def deparse
4
+ PgQuery.deparse(@tree)
591
5
  end
6
+ end
592
7
 
593
- def deparse_case(node)
594
- output = ['CASE']
595
- output << deparse_item(node['arg']) if node['arg']
596
- output += node['args'].map { |arg| deparse_item(arg) }
597
- if node['defresult']
598
- output << 'ELSE'
599
- output << deparse_item(node['defresult'])
600
- end
601
- output << 'END'
602
- output.join(' ')
603
- end
604
-
605
- def deparse_columndef(node)
606
- output = [node['colname']]
607
- output << deparse_item(node['typeName'])
608
- if node['raw_default']
609
- output << 'USING'
610
- output << deparse_item(node['raw_default'])
611
- end
612
- if node['constraints']
613
- output += node['constraints'].map do |item|
614
- deparse_item(item)
615
- end
616
- end
617
- output.compact.join(' ')
618
- end
619
-
620
- def deparse_constraint(node) # rubocop:disable Metrics/CyclomaticComplexity
621
- output = []
622
- if node['conname']
623
- output << 'CONSTRAINT'
624
- output << node['conname']
625
- end
626
- case node['contype']
627
- when CONSTR_TYPE_NULL
628
- output << 'NULL'
629
- when CONSTR_TYPE_NOTNULL
630
- output << 'NOT NULL'
631
- when CONSTR_TYPE_DEFAULT
632
- output << 'DEFAULT'
633
- when CONSTR_TYPE_CHECK
634
- output << 'CHECK'
635
- when CONSTR_TYPE_PRIMARY
636
- output << 'PRIMARY KEY'
637
- when CONSTR_TYPE_UNIQUE
638
- output << 'UNIQUE'
639
- when CONSTR_TYPE_EXCLUSION
640
- output << 'EXCLUSION'
641
- when CONSTR_TYPE_FOREIGN
642
- output << 'FOREIGN KEY'
643
- end
644
-
645
- if node['raw_expr']
646
- expression = deparse_item(node['raw_expr'])
647
- # Unless it's simple, put parentheses around it
648
- expression = '(' + expression + ')' if node['raw_expr'][A_EXPR] && node['raw_expr'][A_EXPR]['kind'] == AEXPR_OP
649
- output << expression
650
- end
651
- output << '(' + deparse_item_list(node['keys']).join(', ') + ')' if node['keys']
652
- output << '(' + deparse_item_list(node['fk_attrs']).join(', ') + ')' if node['fk_attrs']
653
- output << 'REFERENCES ' + deparse_item(node['pktable']) + ' (' + deparse_item_list(node['pk_attrs']).join(', ') + ')' if node['pktable']
654
- output << 'NOT VALID' if node['skip_validation']
655
- output << "USING INDEX #{node['indexname']}" if node['indexname']
656
- output.join(' ')
657
- end
658
-
659
- def deparse_copy(node)
660
- output = ['COPY']
661
- output << deparse_item(node['relation'])
662
- columns = node.fetch('attlist', []).map { |column| deparse_item(column) }
663
- output << "(#{columns.join(', ')})" unless columns.empty?
664
- output << (node['is_from'] ? 'FROM' : 'TO')
665
- output << 'PROGRAM' if node['is_program']
666
- output << if node.key?('filename')
667
- "'#{node['filename']}'"
668
- else
669
- node['is_from'] ? 'STDIN' : 'STDOUT'
670
- end
671
- output.join(' ')
672
- end
673
-
674
- def deparse_create_function(node)
675
- output = []
676
- output << 'CREATE'
677
- output << 'OR REPLACE' if node['replace']
678
- output << 'FUNCTION'
679
-
680
- arguments = deparse_item_list(node['parameters']).join(', ')
681
-
682
- output << deparse_item_list(node['funcname']).join('.') + '(' + arguments + ')'
683
-
684
- output << 'RETURNS'
685
- output << deparse_item(node['returnType'])
686
- output += node['options'].map { |item| deparse_item(item) }
687
-
688
- output.join(' ')
689
- end
690
-
691
- def deparse_create_table(node)
692
- output = []
693
- output << 'CREATE'
694
-
695
- persistence = relpersistence(node['relation'])
696
- output << persistence if persistence
697
-
698
- output << 'TABLE'
699
-
700
- output << 'IF NOT EXISTS' if node['if_not_exists']
701
-
702
- output << deparse_item(node['relation'])
703
-
704
- output << '(' + node['tableElts'].map do |item|
705
- deparse_item(item)
706
- end.join(', ') + ')'
707
-
708
- if node['inhRelations']
709
- output << 'INHERITS'
710
- output << '(' + node['inhRelations'].map do |relation|
711
- deparse_item(relation)
712
- end.join(', ') + ')'
713
- end
714
-
715
- output.join(' ')
716
- end
717
-
718
- def deparse_create_table_as(node)
719
- output = []
720
- output << 'CREATE TEMPORARY TABLE'
721
- output << deparse_item(node['into'])
722
- output << 'AS'
723
- output << deparse_item(node['query'])
724
- output.join(' ')
725
- end
726
-
727
- def deparse_into_clause(node)
728
- deparse_item(node['rel'])
729
- end
730
-
731
- def deparse_when(node)
732
- output = ['WHEN']
733
- output << deparse_item(node['expr'])
734
- output << 'THEN'
735
- output << deparse_item(node['result'])
736
- output.join(' ')
737
- end
738
-
739
- def deparse_sublink(node)
740
- if node['subLinkType'] == SUBLINK_TYPE_ANY
741
- format('%s IN (%s)', deparse_item(node['testexpr']), deparse_item(node['subselect']))
742
- elsif node['subLinkType'] == SUBLINK_TYPE_EXISTS
743
- format('EXISTS(%s)', deparse_item(node['subselect']))
744
- else
745
- format('(%s)', deparse_item(node['subselect']))
746
- end
747
- end
748
-
749
- def deparse_rangesubselect(node)
750
- output = '(' + deparse_item(node['subquery']) + ')'
751
- if node['alias']
752
- output + ' ' + deparse_item(node['alias'])
753
- else
754
- output
755
- end
756
- end
757
-
758
- def deparse_row(node)
759
- 'ROW(' + node['args'].map { |arg| deparse_item(arg) }.join(', ') + ')'
760
- end
761
-
762
- def deparse_select(node) # rubocop:disable Metrics/CyclomaticComplexity
763
- output = []
764
-
765
- if node['op'] == 1
766
- output << deparse_item(node['larg'])
767
- output << 'UNION'
768
- output << 'ALL' if node['all']
769
- output << deparse_item(node['rarg'])
770
- return output.join(' ')
771
- end
772
-
773
- output << deparse_item(node['withClause']) if node['withClause']
774
-
775
- if node[TARGET_LIST_FIELD]
776
- output << 'SELECT'
777
- if node['distinctClause']
778
- output << 'DISTINCT'
779
- unless node['distinctClause'].compact.empty?
780
- columns = node['distinctClause'].map { |item| deparse_item(item, :select) }
781
- output << "ON (#{columns.join(', ')})"
782
- end
783
- end
784
- output << node[TARGET_LIST_FIELD].map do |item|
785
- deparse_item(item, :select)
786
- end.join(', ')
787
- end
788
-
789
- if node[FROM_CLAUSE_FIELD]
790
- output << 'FROM'
791
- output << node[FROM_CLAUSE_FIELD].map do |item|
792
- deparse_item(item)
793
- end.join(', ')
794
- end
795
-
796
- if node['whereClause']
797
- output << 'WHERE'
798
- output << deparse_item(node['whereClause'])
799
- end
800
-
801
- if node['valuesLists']
802
- output << 'VALUES'
803
- output << node['valuesLists'].map do |value_list|
804
- '(' + value_list.map { |v| deparse_item(v) }.join(', ') + ')'
805
- end.join(', ')
806
- end
807
-
808
- if node['groupClause']
809
- output << 'GROUP BY'
810
- output << node['groupClause'].map do |item|
811
- deparse_item(item)
812
- end.join(', ')
813
- end
814
-
815
- if node['havingClause']
816
- output << 'HAVING'
817
- output << deparse_item(node['havingClause'])
818
- end
819
-
820
- if node['sortClause']
821
- output << 'ORDER BY'
822
- output << node['sortClause'].map do |item|
823
- deparse_item(item)
824
- end.join(', ')
825
- end
826
-
827
- if node['limitCount']
828
- output << 'LIMIT'
829
- output << deparse_item(node['limitCount'])
830
- end
831
-
832
- if node['limitOffset']
833
- output << 'OFFSET'
834
- output << deparse_item(node['limitOffset'])
835
- end
836
-
837
- if node['lockingClause']
838
- node['lockingClause'].map do |item|
839
- output << deparse_item(item)
840
- end
841
- end
842
-
843
- output.join(' ')
844
- end
845
-
846
- def deparse_sql_value_function(node)
847
- output = []
848
- lookup = [
849
- 'current_date',
850
- 'current_time',
851
- 'current_time', # with precision
852
- 'current_timestamp',
853
- 'current_timestamp', # with precision
854
- 'localtime',
855
- 'localtime', # with precision
856
- 'localtimestamp',
857
- 'localtimestamp', # with precision
858
- 'current_role',
859
- 'current_user',
860
- 'session_user',
861
- 'user',
862
- 'current_catalog',
863
- 'current_schema'
864
- ]
865
- output << lookup[node['op']]
866
- output << "(#{node['typmod']})" unless node.fetch('typmod', -1) == -1
867
- output.join('')
868
- end
869
-
870
- def deparse_insert_into(node)
871
- output = []
872
- output << deparse_item(node['withClause']) if node['withClause']
873
-
874
- output << 'INSERT INTO'
875
- output << deparse_item(node['relation'])
876
-
877
- if node['cols']
878
- output << '(' + node['cols'].map do |column|
879
- deparse_item(column)
880
- end.join(', ') + ')'
881
- end
882
-
883
- output << deparse_item(node['selectStmt'])
884
-
885
- output.join(' ')
886
- end
887
-
888
- def deparse_update(node)
889
- output = []
890
- output << deparse_item(node['withClause']) if node['withClause']
891
-
892
- output << 'UPDATE'
893
- output << deparse_item(node['relation'])
894
-
895
- if node[TARGET_LIST_FIELD]
896
- output << 'SET'
897
- columns = node[TARGET_LIST_FIELD].map do |item|
898
- deparse_item(item, :update)
899
- end
900
- output << columns.join(', ')
901
- end
902
-
903
- if node['whereClause']
904
- output << 'WHERE'
905
- output << deparse_item(node['whereClause'])
906
- end
907
-
908
- if node['returningList']
909
- output << 'RETURNING'
910
- output << node['returningList'].map do |item|
911
- # RETURNING is formatted like a SELECT
912
- deparse_item(item, :select)
913
- end.join(', ')
914
- end
915
-
916
- output.join(' ')
917
- end
918
-
919
- def deparse_typecast(node)
920
- if deparse_item(node['typeName']) == 'boolean'
921
- deparse_item(node['arg']) == "'t'" ? 'true' : 'false'
922
- else
923
- deparse_item(node['arg']) + '::' + deparse_typename(node['typeName'][TYPE_NAME])
924
- end
925
- end
926
-
927
- def deparse_typename(node)
928
- names = node['names'].map { |n| deparse_item(n, TYPE_NAME) }
929
-
930
- # Intervals are tricky and should be handled in a separate method because
931
- # they require performing some bitmask operations.
932
- return deparse_interval_type(node) if names == %w[pg_catalog interval]
933
-
934
- output = []
935
- output << 'SETOF' if node['setof']
936
-
937
- if node['typmods']
938
- arguments = node['typmods'].map do |item|
939
- deparse_item(item)
940
- end.join(', ')
941
- end
942
- output << deparse_typename_cast(names, arguments)
943
- output.last << '[]' if node['arrayBounds']
944
-
945
- output.join(' ')
946
- end
947
-
948
- def deparse_typename_cast(names, arguments) # rubocop:disable Metrics/CyclomaticComplexity
949
- catalog, type = names
950
- # Just pass along any custom types.
951
- # (The pg_catalog types are built-in Postgres system types and are
952
- # handled in the case statement below)
953
- return names.join('.') if catalog != 'pg_catalog'
954
-
955
- case type
956
- when 'bpchar'
957
- # char(2) or char(9)
958
- "char(#{arguments})"
959
- when 'varchar'
960
- arguments.nil? ? 'varchar' : "varchar(#{arguments})"
961
- when 'numeric'
962
- # numeric(3, 5)
963
- arguments.nil? ? 'numeric' : "numeric(#{arguments})"
964
- when 'bool'
965
- 'boolean'
966
- when 'int2'
967
- 'smallint'
968
- when 'int4'
969
- 'int'
970
- when 'int8'
971
- 'bigint'
972
- when 'real', 'float4'
973
- 'real'
974
- when 'float8'
975
- 'double'
976
- when 'time'
977
- 'time'
978
- when 'timetz'
979
- 'time with time zone'
980
- when 'timestamp'
981
- 'timestamp'
982
- when 'timestamptz'
983
- 'timestamp with time zone'
984
- else
985
- raise format("Can't deparse type: %s", type)
986
- end
987
- end
988
-
989
- # Deparses interval type expressions like `interval year to month` or
990
- # `interval hour to second(5)`
991
- def deparse_interval_type(node)
992
- type = ['interval']
993
-
994
- if node['typmods']
995
- typmods = node['typmods'].map { |typmod| deparse_item(typmod) }
996
- type << Interval.from_int(typmods.first.to_i).map do |part|
997
- # only the `second` type can take an argument.
998
- if part == 'second' && typmods.size == 2
999
- "second(#{typmods.last})"
1000
- else
1001
- part
1002
- end.downcase
1003
- end.join(' to ')
1004
- end
1005
-
1006
- type.join(' ')
1007
- end
1008
-
1009
- def deparse_nulltest(node)
1010
- output = [deparse_item(node['arg'])]
1011
- case node['nulltesttype']
1012
- when 0
1013
- output << 'IS NULL'
1014
- when 1
1015
- output << 'IS NOT NULL'
1016
- end
1017
- output.join(' ')
1018
- end
1019
-
1020
- TRANSACTION_CMDS = {
1021
- TRANS_STMT_BEGIN => 'BEGIN',
1022
- TRANS_STMT_COMMIT => 'COMMIT',
1023
- TRANS_STMT_ROLLBACK => 'ROLLBACK',
1024
- TRANS_STMT_SAVEPOINT => 'SAVEPOINT',
1025
- TRANS_STMT_RELEASE => 'RELEASE',
1026
- TRANS_STMT_ROLLBACK_TO => 'ROLLBACK TO SAVEPOINT'
1027
- }.freeze
1028
- def deparse_transaction(node)
1029
- output = []
1030
- output << TRANSACTION_CMDS[node['kind']] || raise(format("Can't deparse TRANSACTION %s", node.inspect))
1031
-
1032
- if node['options']
1033
- output += node['options'].map { |item| deparse_item(item) }
1034
- end
1035
-
1036
- output.join(' ')
1037
- end
1038
-
1039
- def deparse_coalesce(node)
1040
- format('COALESCE(%s)', node['args'].map { |a| deparse_item(a) }.join(', '))
1041
- end
1042
-
1043
- def deparse_defelem(node)
1044
- case node['defname']
1045
- when 'as'
1046
- "AS $$#{deparse_item_list(node['arg'], :defname_as).join("\n")}$$"
1047
- when 'language'
1048
- "language #{deparse_item(node['arg'])}"
1049
- when 'volatility'
1050
- node['arg']['String']['str'].upcase # volatility does not need to be quoted
1051
- when 'strict'
1052
- deparse_item(node['arg']) == '1' ? 'RETURNS NULL ON NULL INPUT' : 'CALLED ON NULL INPUT'
1053
- else
1054
- deparse_item(node['arg'])
1055
- end
1056
- end
1057
-
1058
- def deparse_delete_from(node)
1059
- output = []
1060
- output << deparse_item(node['withClause']) if node['withClause']
1061
-
1062
- output << 'DELETE FROM'
1063
- output << deparse_item(node['relation'])
1064
-
1065
- if node['usingClause']
1066
- output << 'USING'
1067
- output << node['usingClause'].map do |item|
1068
- deparse_item(item)
1069
- end.join(', ')
1070
- end
1071
-
1072
- if node['whereClause']
1073
- output << 'WHERE'
1074
- output << deparse_item(node['whereClause'])
1075
- end
1076
-
1077
- if node['returningList']
1078
- output << 'RETURNING'
1079
- output << node['returningList'].map do |item|
1080
- # RETURNING is formatted like a SELECT
1081
- deparse_item(item, :select)
1082
- end.join(', ')
1083
- end
1084
-
1085
- output.join(' ')
1086
- end
1087
-
1088
- def deparse_drop(node)
1089
- output = ['DROP']
1090
- output << 'TABLE' if node['removeType'] == OBJECT_TYPE_TABLE
1091
- output << 'CONCURRENTLY' if node['concurrent']
1092
- output << 'IF EXISTS' if node['missing_ok']
1093
-
1094
- output << node['objects'].map { |list| list.map { |object| deparse_item(object) } }.join(', ')
1095
-
1096
- output << 'CASCADE' if node['behavior'] == 1
1097
-
1098
- output.join(' ')
1099
- end
8
+ # Reconstruct all of the parsed queries into their original form
9
+ def self.deparse(tree)
10
+ PgQuery.deparse_protobuf(PgQuery::ParseResult.encode(tree)).force_encoding('UTF-8')
11
+ end
1100
12
 
1101
- def deparse_explain(node)
1102
- output = ['EXPLAIN']
1103
- options = node.fetch('options', []).map { |option| option['DefElem']['defname'].upcase }
1104
- if options.size == 1
1105
- output.concat(options)
1106
- elsif options.size > 1
1107
- output << "(#{options.join(', ')})"
1108
- end
1109
- output << deparse_item(node['query'])
1110
- output.join(' ')
1111
- end
13
+ # Convenience method for deparsing a statement of a specific type
14
+ def self.deparse_stmt(stmt)
15
+ deparse(PgQuery::ParseResult.new(version: PG_VERSION_NUM, stmts: [PgQuery::RawStmt.new(stmt: PgQuery::Node.from(stmt))]))
16
+ end
1112
17
 
1113
- # The PG parser adds several pieces of view data onto the RANGEVAR
1114
- # that need to be printed before deparse_rangevar is called.
1115
- def relpersistence(rangevar)
1116
- if rangevar[RANGE_VAR]['relpersistence'] == 't'
1117
- 'TEMPORARY'
1118
- elsif rangevar[RANGE_VAR]['relpersistence'] == 'u'
1119
- 'UNLOGGED'
1120
- end
1121
- end
18
+ # Convenience method for deparsing an expression
19
+ def self.deparse_expr(expr)
20
+ deparse_stmt(PgQuery::SelectStmt.new(where_clause: expr, op: :SETOP_NONE)).gsub('SELECT WHERE ', '')
1122
21
  end
1123
22
  end