pg_query 1.1.1 → 2.0.2

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 (480) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +216 -99
  3. data/README.md +80 -69
  4. data/Rakefile +85 -5
  5. data/ext/pg_query/extconf.rb +4 -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 +989 -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 +9955 -0
  381. data/ext/pg_query/pg_query_fingerprint.c +295 -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 +15 -1478
  460. data/lib/pg_query/filter_columns.rb +88 -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 -12
  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/deparse/keywords.rb +0 -760
  478. data/lib/pg_query/deparse/rename.rb +0 -41
  479. data/lib/pg_query/legacy_parsetree.rb +0 -109
  480. data/lib/pg_query/node_types.rb +0 -293
@@ -1,1485 +1,22 @@
1
- require_relative 'deparse/alter_table'
2
- require_relative 'deparse/rename'
3
- require_relative 'deparse/interval'
4
- require_relative 'deparse/keywords'
1
+ module PgQuery
2
+ class ParserResult
3
+ def deparse
4
+ PgQuery.deparse(@tree)
5
+ end
6
+ end
5
7
 
6
- class PgQuery
7
8
  # Reconstruct all of the parsed queries into their original form
8
- def deparse(tree = @tree)
9
- tree.map do |item|
10
- Deparse.from(item)
11
- end.join('; ')
9
+ def self.deparse(tree)
10
+ PgQuery.deparse_protobuf(PgQuery::ParseResult.encode(tree)).force_encoding('UTF-8')
12
11
  end
13
12
 
14
- # rubocop:disable Metrics/ModuleLength
15
- module Deparse
16
- extend self
17
-
18
- # Given one element of the PgQuery#parsetree reconstruct it back into the
19
- # original query.
20
- def from(item)
21
- deparse_item(item)
22
- end
23
-
24
- private
25
-
26
- def deparse_item(item, context = nil) # rubocop:disable Metrics/CyclomaticComplexity
27
- return if item.nil?
28
- return item if item.is_a?(Integer)
29
-
30
- type = item.keys[0]
31
- node = item.values[0]
32
-
33
- case type
34
- when A_EXPR
35
- case node['kind']
36
- when AEXPR_OP
37
- deparse_aexpr(node, context)
38
- when AEXPR_OP_ALL
39
- deparse_aexpr_all(node)
40
- when AEXPR_OP_ANY
41
- deparse_aexpr_any(node)
42
- when AEXPR_IN
43
- deparse_aexpr_in(node)
44
- when AEXPR_ILIKE
45
- deparse_aexpr_ilike(node)
46
- when CONSTR_TYPE_FOREIGN
47
- deparse_aexpr_like(node)
48
- when AEXPR_BETWEEN, AEXPR_NOT_BETWEEN, AEXPR_BETWEEN_SYM, AEXPR_NOT_BETWEEN_SYM
49
- deparse_aexpr_between(node)
50
- when AEXPR_NULLIF
51
- deparse_aexpr_nullif(node)
52
- else
53
- raise format("Can't deparse: %s: %s", type, node.inspect)
54
- end
55
- when ACCESS_PRIV
56
- deparse_access_priv(node)
57
- when ALIAS
58
- deparse_alias(node)
59
- when ALTER_TABLE_STMT
60
- deparse_alter_table(node)
61
- when ALTER_TABLE_CMD
62
- deparse_alter_table_cmd(node)
63
- when A_ARRAY_EXPR
64
- deparse_a_arrayexp(node)
65
- when A_CONST
66
- deparse_a_const(node)
67
- when A_INDICES
68
- deparse_a_indices(node)
69
- when A_INDIRECTION
70
- deparse_a_indirection(node)
71
- when A_STAR
72
- deparse_a_star(node)
73
- when A_TRUNCATED
74
- '...' # pg_query internal
75
- when BOOL_EXPR
76
- case node['boolop']
77
- when BOOL_EXPR_AND
78
- deparse_bool_expr_and(node)
79
- when BOOL_EXPR_OR
80
- deparse_bool_expr_or(node)
81
- when BOOL_EXPR_NOT
82
- deparse_bool_expr_not(node)
83
- end
84
- when BOOLEAN_TEST
85
- deparse_boolean_test(node)
86
- when CASE_EXPR
87
- deparse_case(node)
88
- when COALESCE_EXPR
89
- deparse_coalesce(node)
90
- when COLLATE_CLAUSE
91
- deparse_collate(node)
92
- when COLUMN_DEF
93
- deparse_columndef(node)
94
- when COLUMN_REF
95
- deparse_columnref(node)
96
- when COMMON_TABLE_EXPR
97
- deparse_cte(node)
98
- when COMPOSITE_TYPE_STMT
99
- deparse_composite_type(node)
100
- when CONSTRAINT
101
- deparse_constraint(node)
102
- when COPY_STMT
103
- deparse_copy(node)
104
- when CREATE_CAST_STMT
105
- deparse_create_cast(node)
106
- when CREATE_DOMAIN_STMT
107
- deparse_create_domain(node)
108
- when CREATE_ENUM_STMT
109
- deparse_create_enum(node)
110
- when CREATE_FUNCTION_STMT
111
- deparse_create_function(node)
112
- when CREATE_RANGE_STMT
113
- deparse_create_range(node)
114
- when CREATE_SCHEMA_STMT
115
- deparse_create_schema(node)
116
- when CREATE_STMT
117
- deparse_create_table(node)
118
- when CREATE_TABLE_AS_STMT
119
- deparse_create_table_as(node)
120
- when INTO_CLAUSE
121
- deparse_into_clause(node)
122
- when DEF_ELEM
123
- deparse_defelem(node)
124
- when DEFINE_STMT
125
- deparse_define_stmt(node)
126
- when DELETE_STMT
127
- deparse_delete_from(node)
128
- when DISCARD_STMT
129
- deparse_discard(node)
130
- when DROP_STMT
131
- deparse_drop(node)
132
- when EXPLAIN_STMT
133
- deparse_explain(node)
134
- when EXECUTE_STMT
135
- deparse_execute(node)
136
- when FUNC_CALL
137
- deparse_funccall(node)
138
- when FUNCTION_PARAMETER
139
- deparse_functionparameter(node)
140
- when GRANT_ROLE_STMT
141
- deparse_grant_role(node)
142
- when GRANT_STMT
143
- deparse_grant(node)
144
- when INSERT_STMT
145
- deparse_insert_into(node)
146
- when JOIN_EXPR
147
- deparse_joinexpr(node)
148
- when LOCK_STMT
149
- deparse_lock(node)
150
- when LOCKING_CLAUSE
151
- deparse_lockingclause(node)
152
- when NULL_TEST
153
- deparse_nulltest(node)
154
- when OBJECT_WITH_ARGS
155
- deparse_object_with_args(node)
156
- when PARAM_REF
157
- deparse_paramref(node)
158
- when PREPARE_STMT
159
- deparse_prepare(node)
160
- when RANGE_FUNCTION
161
- deparse_range_function(node)
162
- when RANGE_SUBSELECT
163
- deparse_rangesubselect(node)
164
- when RANGE_VAR
165
- deparse_rangevar(node)
166
- when RAW_STMT
167
- deparse_raw_stmt(node)
168
- when RENAME_STMT
169
- deparse_renamestmt(node)
170
- when RES_TARGET
171
- deparse_restarget(node, context)
172
- when ROLE_SPEC
173
- deparse_role_spec(node)
174
- when ROW_EXPR
175
- deparse_row(node)
176
- when SELECT_STMT
177
- deparse_select(node)
178
- when SQL_VALUE_FUNCTION
179
- deparse_sql_value_function(node)
180
- when SORT_BY
181
- deparse_sortby(node)
182
- when SUB_LINK
183
- deparse_sublink(node)
184
- when TRANSACTION_STMT
185
- deparse_transaction(node)
186
- when TYPE_CAST
187
- deparse_typecast(node)
188
- when TYPE_NAME
189
- deparse_typename(node)
190
- when UPDATE_STMT
191
- deparse_update(node)
192
- when CASE_WHEN
193
- deparse_when(node)
194
- when WINDOW_DEF
195
- deparse_windowdef(node)
196
- when WITH_CLAUSE
197
- deparse_with_clause(node)
198
- when VIEW_STMT
199
- deparse_viewstmt(node)
200
- when VARIABLE_SET_STMT
201
- deparse_variable_set_stmt(node)
202
- when VACUUM_STMT
203
- deparse_vacuum_stmt(node)
204
- when DO_STMT
205
- deparse_do_stmt(node)
206
- when SET_TO_DEFAULT
207
- 'DEFAULT'
208
- when STRING
209
- if context == A_CONST
210
- format("'%s'", node['str'].gsub("'", "''"))
211
- elsif [FUNC_CALL, TYPE_NAME, :operator, :defname_as].include?(context)
212
- node['str']
213
- else
214
- deparse_identifier(node['str'], escape_always: true)
215
- end
216
- when INTEGER
217
- node['ival'].to_s
218
- when FLOAT
219
- node['str']
220
- when NULL
221
- 'NULL'
222
- else
223
- raise format("Can't deparse: %s: %s", type, node.inspect)
224
- end
225
- end
226
-
227
- def deparse_item_list(nodes, context = nil)
228
- nodes.map { |n| deparse_item(n, context) }
229
- end
230
-
231
- def deparse_identifier(ident, escape_always: false)
232
- return if ident.nil?
233
- if escape_always || !ident[/^\w+$/] || KEYWORDS.include?(ident.upcase)
234
- format('"%s"', ident.gsub('"', '""'))
235
- else
236
- ident
237
- end
238
- end
239
-
240
- def deparse_rangevar(node)
241
- output = []
242
- output << 'ONLY' unless node['inh']
243
- schema = node['schemaname'] ? '"' + node['schemaname'] + '".' : ''
244
- output << schema + '"' + node['relname'] + '"'
245
- output << deparse_item(node['alias']) if node['alias']
246
- output.join(' ')
247
- end
248
-
249
- def deparse_raw_stmt(node)
250
- deparse_item(node[STMT_FIELD])
251
- end
252
-
253
- def deparse_renamestmt_decision(node, type)
254
- if node[type]
255
- if node[type].is_a?(String)
256
- deparse_identifier(node[type])
257
- elsif node[type].is_a?(Array)
258
- deparse_item_list(node[type])
259
- elsif node[type].is_a?(Object)
260
- deparse_item(node[type])
261
- end
262
- else
263
- type
264
- end
265
- end
266
-
267
- def deparse_renamestmt(node)
268
- output = []
269
- output << 'ALTER'
270
- command, type, options, type2, options2 = Rename.commands(node)
271
-
272
- output << command if command
273
- output << deparse_renamestmt_decision(node, type)
274
- output << options if options
275
- output << deparse_renamestmt_decision(node, type2) if type2
276
- output << deparse_renamestmt_decision(node, options2) if options2
277
- output << 'TO'
278
- output << deparse_identifier(node['newname'], escape_always: true)
279
- output.join(' ')
280
- end
281
-
282
- def deparse_columnref(node)
283
- node['fields'].map do |field|
284
- field.is_a?(String) ? '"' + field + '"' : deparse_item(field)
285
- end.join('.')
286
- end
287
-
288
- def deparse_a_arrayexp(node)
289
- 'ARRAY[' + (node['elements'] || []).map do |element|
290
- deparse_item(element)
291
- end.join(', ') + ']'
292
- end
293
-
294
- def deparse_a_const(node)
295
- deparse_item(node['val'], A_CONST)
296
- end
297
-
298
- def deparse_a_star(_node)
299
- '*'
300
- end
301
-
302
- def deparse_a_indirection(node)
303
- output = []
304
- arg = deparse_item(node['arg'])
305
- output << if node['arg'].key?(FUNC_CALL) || node['arg'].key?(SUB_LINK)
306
- "(#{arg})."
307
- else
308
- arg
309
- end
310
- node['indirection'].each do |subnode|
311
- output << deparse_item(subnode)
312
- end
313
- output.join
314
- end
315
-
316
- def deparse_a_indices(node)
317
- format('[%s]', deparse_item(node['uidx']))
318
- end
319
-
320
- def deparse_alias(node)
321
- name = node['aliasname']
322
- if node['colnames']
323
- name + '(' + deparse_item_list(node['colnames']).join(', ') + ')'
324
- else
325
- deparse_identifier(name)
326
- end
327
- end
328
-
329
- def deparse_alter_table(node)
330
- output = []
331
- output << 'ALTER'
332
-
333
- output << 'TABLE' if node['relkind'] == OBJECT_TYPE_TABLE
334
- output << 'VIEW' if node['relkind'] == OBJECT_TYPE_VIEW
335
-
336
- output << deparse_item(node['relation'])
337
-
338
- output << node['cmds'].map do |item|
339
- deparse_item(item)
340
- end.join(', ')
341
-
342
- output.join(' ')
343
- end
344
-
345
- def deparse_alter_table_cmd(node)
346
- command, options = AlterTable.commands(node)
347
-
348
- output = []
349
- output << command if command
350
- output << 'IF EXISTS' if node['missing_ok']
351
- output << node['name']
352
- output << options if options
353
- output << deparse_item(node['def']) if node['def']
354
- output << 'CASCADE' if node['behavior'] == 1
355
-
356
- output.compact.join(' ')
357
- end
358
-
359
- def deparse_object_with_args(node)
360
- output = []
361
- output += node['objname'].map(&method(:deparse_item))
362
- unless node['args_unspecified']
363
- args = node.fetch('objargs', []).map(&method(:deparse_item)).join(', ')
364
- output << "(#{args})"
365
- end
366
- output.join('')
367
- end
368
-
369
- def deparse_paramref(node)
370
- if node['number'].nil?
371
- '?'
372
- else
373
- format('$%d', node['number'])
374
- end
375
- end
376
-
377
- def deparse_prepare(node)
378
- output = ['PREPARE']
379
- output << deparse_identifier(node['name'])
380
- output << "(#{deparse_item_list(node['argtypes']).join(', ')})" if node['argtypes']
381
- output << 'AS'
382
- output << deparse_item(node['query'])
383
- output.join(' ')
384
- end
385
-
386
- def deparse_restarget(node, context)
387
- if context == :select
388
- [deparse_item(node['val']), deparse_identifier(node['name'])].compact.join(' AS ')
389
- elsif context == :update
390
- [node['name'], deparse_item(node['val'])].compact.join(' = ')
391
- elsif node['val'].nil?
392
- node['name']
393
- else
394
- raise format("Can't deparse %s in context %s", node.inspect, context)
395
- end
396
- end
397
-
398
- def deparse_funccall(node)
399
- output = []
400
-
401
- # SUM(a, b)
402
- args = Array(node['args']).map { |arg| deparse_item(arg) }
403
- # COUNT(*)
404
- args << '*' if node['agg_star']
405
-
406
- name = (node['funcname'].map { |n| deparse_item(n, FUNC_CALL) } - ['pg_catalog']).join('.')
407
- distinct = node['agg_distinct'] ? 'DISTINCT ' : ''
408
- output << format('%s(%s%s)', name, distinct, args.join(', '))
409
- output << format('OVER %s', deparse_item(node['over'])) if node['over']
410
-
411
- output.join(' ')
412
- end
413
-
414
- def deparse_windowdef(node)
415
- return deparse_identifier(node['name']) if node['name']
416
-
417
- output = []
418
-
419
- if node['partitionClause']
420
- output << 'PARTITION BY'
421
- output << node['partitionClause'].map do |item|
422
- deparse_item(item)
423
- end.join(', ')
424
- end
425
-
426
- if node['orderClause']
427
- output << 'ORDER BY'
428
- output << node['orderClause'].map do |item|
429
- deparse_item(item)
430
- end.join(', ')
431
- end
432
-
433
- format('(%s)', output.join(' '))
434
- end
435
-
436
- def deparse_functionparameter(node)
437
- deparse_item(node['argType'])
438
- end
439
-
440
- def deparse_grant_role(node)
441
- output = []
442
- output << ['GRANT'] if node['is_grant']
443
- output << ['REVOKE'] unless node['is_grant']
444
- output << node['granted_roles'].map(&method(:deparse_item)).join(', ')
445
- output << ['TO'] if node['is_grant']
446
- output << ['FROM'] unless node['is_grant']
447
- output << node['grantee_roles'].map(&method(:deparse_item)).join(', ')
448
- output << 'WITH ADMIN OPTION' if node['admin_opt']
449
- output.join(' ')
450
- end
451
-
452
- def deparse_grant(node) # rubocop:disable Metrics/CyclomaticComplexity
453
- objtype, allow_all = deparse_grant_objtype(node)
454
- output = []
455
- output << ['GRANT'] if node['is_grant']
456
- output << ['REVOKE'] unless node['is_grant']
457
- output << if node.key?('privileges')
458
- node['privileges'].map(&method(:deparse_item)).join(', ')
459
- else
460
- 'ALL'
461
- end
462
- output << 'ON'
463
- objects = node['objects']
464
- objects = objects[0] if %w[DOMAIN TYPE].include?(objtype)
465
- objects = objects.map do |object|
466
- deparsed = deparse_item(object)
467
- if object.key?(RANGE_VAR) || object.key?(OBJECT_WITH_ARGS) || !allow_all
468
- objtype == 'TABLE' ? deparsed : "#{objtype} #{deparsed}"
469
- else
470
- "ALL #{objtype}S IN SCHEMA #{deparsed}"
471
- end
472
- end
473
- output << objects.join(', ')
474
- output << ['TO'] if node['is_grant']
475
- output << ['FROM'] unless node['is_grant']
476
- output << node['grantees'].map(&method(:deparse_item)).join(', ')
477
- output << 'WITH GRANT OPTION' if node['grant_option']
478
- output.join(' ')
479
- end
480
-
481
- def deparse_grant_objtype(node)
482
- {
483
- 1 => ['TABLE', true],
484
- 2 => ['SEQUENCE', true],
485
- 3 => ['DATABASE', false],
486
- 4 => ['DOMAIN', false],
487
- 5 => ['FOREIGN DATA WRAPPER', false],
488
- 6 => ['FOREIGN SERVER', false],
489
- 7 => ['FUNCTION', true],
490
- 8 => ['LANGUAGE', false],
491
- 9 => ['LARGE OBJECT', false],
492
- 10 => ['SCHEMA', false],
493
- 11 => ['TABLESPACE', false],
494
- 12 => ['TYPE', false]
495
- }.fetch(node['objtype'])
496
- end
497
-
498
- def deparse_access_priv(node)
499
- output = [node['priv_name']]
500
- output << "(#{node['cols'].map(&method(:deparse_item)).join(', ')})" if node.key?('cols')
501
- output.join(' ')
502
- end
503
-
504
- def deparse_role_spec(node)
505
- return 'CURRENT_USER' if node['roletype'] == 1
506
- return 'SESSION_USER' if node['roletype'] == 2
507
- return 'PUBLIC' if node['roletype'] == 3
508
- deparse_identifier(node['rolename'], escape_always: true)
509
- end
510
-
511
- def deparse_aexpr_in(node)
512
- rexpr = Array(node['rexpr']).map { |arg| deparse_item(arg) }
513
- operator = node['name'].map { |n| deparse_item(n, :operator) } == ['='] ? 'IN' : 'NOT IN'
514
- format('%s %s (%s)', deparse_item(node['lexpr']), operator, rexpr.join(', '))
515
- end
516
-
517
- def deparse_aexpr_like(node)
518
- value = deparse_item(node['rexpr'])
519
- operator = node['name'].map { |n| deparse_item(n, :operator) } == ['~~'] ? 'LIKE' : 'NOT LIKE'
520
- format('%s %s %s', deparse_item(node['lexpr']), operator, value)
521
- end
522
-
523
- def deparse_aexpr_ilike(node)
524
- value = deparse_item(node['rexpr'])
525
- operator = node['name'][0]['String']['str'] == '~~*' ? 'ILIKE' : 'NOT ILIKE'
526
- format('%s %s %s', deparse_item(node['lexpr']), operator, value)
527
- end
528
-
529
- def deparse_bool_expr_not(node)
530
- format('NOT %s', deparse_item(node['args'][0]))
531
- end
532
-
533
- BOOLEAN_TEST_TYPE_TO_STRING = {
534
- BOOLEAN_TEST_TRUE => ' IS TRUE',
535
- BOOLEAN_TEST_NOT_TRUE => ' IS NOT TRUE',
536
- BOOLEAN_TEST_FALSE => ' IS FALSE',
537
- BOOLEAN_TEST_NOT_FALSE => ' IS NOT FALSE',
538
- BOOLEAN_TEST_UNKNOWN => ' IS UNKNOWN',
539
- BOOLEAN_TEST_NOT_UNKNOWN => ' IS NOT UNKNOWN'
540
- }.freeze
541
- def deparse_boolean_test(node)
542
- deparse_item(node['arg']) + BOOLEAN_TEST_TYPE_TO_STRING[node['booltesttype']]
543
- end
544
-
545
- def deparse_range_function(node)
546
- output = []
547
- output << 'LATERAL' if node['lateral']
548
- output << deparse_item(node['functions'][0][0]) # FIXME: Needs more test cases
549
- output << deparse_item(node['alias']) if node['alias']
550
- output << "#{node['alias'] ? '' : 'AS '}(#{deparse_item_list(node['coldeflist']).join(', ')})" if node['coldeflist']
551
- output.join(' ')
552
- end
553
-
554
- def deparse_aexpr(node, context = false)
555
- output = []
556
- output << deparse_item(node['lexpr'], context || true)
557
- output << deparse_item(node['rexpr'], context || true)
558
- output = output.join(' ' + deparse_item(node['name'][0], :operator) + ' ')
559
- if context
560
- # This is a nested expression, add parentheses.
561
- output = '(' + output + ')'
562
- end
563
- output
564
- end
565
-
566
- def deparse_bool_expr_and(node)
567
- # Only put parantheses around OR nodes that are inside this one
568
- node['args'].map do |arg|
569
- if [BOOL_EXPR_OR].include?(arg.values[0]['boolop'])
570
- format('(%s)', deparse_item(arg))
571
- else
572
- deparse_item(arg)
573
- end
574
- end.join(' AND ')
575
- end
576
-
577
- def deparse_bool_expr_or(node)
578
- # Put parantheses around AND + OR nodes that are inside
579
- node['args'].map do |arg|
580
- if [BOOL_EXPR_AND, BOOL_EXPR_OR].include?(arg.values[0]['boolop'])
581
- format('(%s)', deparse_item(arg))
582
- else
583
- deparse_item(arg)
584
- end
585
- end.join(' OR ')
586
- end
587
-
588
- def deparse_aexpr_any(node)
589
- output = []
590
- output << deparse_item(node['lexpr'])
591
- output << format('ANY(%s)', deparse_item(node['rexpr']))
592
- output.join(' ' + deparse_item(node['name'][0], :operator) + ' ')
593
- end
594
-
595
- def deparse_aexpr_all(node)
596
- output = []
597
- output << deparse_item(node['lexpr'])
598
- output << format('ALL(%s)', deparse_item(node['rexpr']))
599
- output.join(' ' + deparse_item(node['name'][0], :operator) + ' ')
600
- end
601
-
602
- def deparse_aexpr_between(node)
603
- between = case node['kind']
604
- when AEXPR_BETWEEN
605
- ' BETWEEN '
606
- when AEXPR_NOT_BETWEEN
607
- ' NOT BETWEEN '
608
- when AEXPR_BETWEEN_SYM
609
- ' BETWEEN SYMMETRIC '
610
- when AEXPR_NOT_BETWEEN_SYM
611
- ' NOT BETWEEN SYMMETRIC '
612
- end
613
- name = deparse_item(node['lexpr'])
614
- output = node['rexpr'].map { |n| deparse_item(n) }
615
- name << between << output.join(' AND ')
616
- end
617
-
618
- def deparse_aexpr_nullif(node)
619
- lexpr = deparse_item(node['lexpr'])
620
- rexpr = deparse_item(node['rexpr'])
621
- format('NULLIF(%s, %s)', lexpr, rexpr)
622
- end
623
-
624
- def deparse_joinexpr(node) # rubocop:disable Metrics/CyclomaticComplexity
625
- output = []
626
- output << deparse_item(node['larg'])
627
- case node['jointype']
628
- when 0
629
- if node['isNatural']
630
- output << 'NATURAL'
631
- elsif node['quals'].nil? && node['usingClause'].nil?
632
- output << 'CROSS'
633
- end
634
- when 1
635
- output << 'LEFT'
636
- when 2
637
- output << 'FULL'
638
- when 3
639
- output << 'RIGHT'
640
- end
641
- output << 'JOIN'
642
- output << deparse_item(node['rarg'])
643
-
644
- if node['quals']
645
- output << 'ON'
646
- output << deparse_item(node['quals'])
647
- end
648
-
649
- output << format('USING (%s)', node['usingClause'].map { |n| deparse_item(n) }.join(', ')) if node['usingClause']
650
-
651
- output.join(' ')
652
- end
653
-
654
- def deparse_lock(node)
655
- output = []
656
- output << 'LOCK TABLE'
657
- tables = node['relations'].map { |table| deparse_item(table) }
658
- output << tables.join(', ')
659
- output.join(' ')
660
- end
661
-
662
- LOCK_CLAUSE_STRENGTH = {
663
- LCS_FORKEYSHARE => 'FOR KEY SHARE',
664
- LCS_FORSHARE => 'FOR SHARE',
665
- LCS_FORNOKEYUPDATE => 'FOR NO KEY UPDATE',
666
- LCS_FORUPDATE => 'FOR UPDATE'
667
- }.freeze
668
- def deparse_lockingclause(node)
669
- output = []
670
- output << LOCK_CLAUSE_STRENGTH[node['strength']]
671
- if node['lockedRels']
672
- output << 'OF'
673
- output << node['lockedRels'].map do |item|
674
- deparse_item(item)
675
- end.join(', ')
676
- end
677
- output.join(' ')
678
- end
679
-
680
- def deparse_sortby(node)
681
- output = []
682
- output << deparse_item(node['node'])
683
- output << 'ASC' if node['sortby_dir'] == 1
684
- output << 'DESC' if node['sortby_dir'] == 2
685
- output << 'NULLS FIRST' if node['sortby_nulls'] == 1
686
- output << 'NULLS LAST' if node['sortby_nulls'] == 2
687
- output.join(' ')
688
- end
689
-
690
- def deparse_collate(node)
691
- output = []
692
- output << deparse_item(node['arg'])
693
- output << 'COLLATE'
694
- output << deparse_item_list(node['collname'])
695
- output.join(' ')
696
- end
697
-
698
- def deparse_with_clause(node)
699
- output = ['WITH']
700
- output << 'RECURSIVE' if node['recursive']
701
- output << node['ctes'].map do |cte|
702
- deparse_item(cte)
703
- end.join(', ')
704
- output.join(' ')
705
- end
706
-
707
- def deparse_viewstmt(node)
708
- output = []
709
- output << 'CREATE'
710
- output << 'OR REPLACE' if node['replace']
711
-
712
- persistence = relpersistence(node['view'])
713
- output << persistence if persistence
714
-
715
- output << 'VIEW'
716
- output << node['view'][RANGE_VAR]['relname']
717
- output << format('(%s)', deparse_item_list(node['aliases']).join(', ')) if node['aliases']
718
-
719
- output << 'AS'
720
- output << deparse_item(node['query'])
721
-
722
- case node['withCheckOption']
723
- when 1
724
- output << 'WITH CHECK OPTION'
725
- when 2
726
- output << 'WITH CASCADED CHECK OPTION'
727
- end
728
- output.join(' ')
729
- end
730
-
731
- def deparse_variable_set_stmt(node)
732
- output = []
733
- output << 'SET'
734
- output << 'LOCAL' if node['is_local']
735
- output << node['name']
736
- output << 'TO'
737
- output << node['args'].map { |arg| deparse_item(arg) }.join(', ')
738
- output.join(' ')
739
- end
740
-
741
- def deparse_vacuum_stmt(node)
742
- output = []
743
- output << 'VACUUM'
744
- output.concat(deparse_vacuum_options(node))
745
- output << deparse_item(node['relation']) if node.key?('relation')
746
- if node.key?('va_cols')
747
- output << "(#{node['va_cols'].map(&method(:deparse_item)).join(', ')})"
748
- end
749
- output.join(' ')
750
- end
751
-
752
- def deparse_vacuum_options(node)
753
- output = []
754
- output << 'FULL' if node['options'][4] == 1
755
- output << 'FREEZE' if node['options'][3] == 1
756
- output << 'VERBOSE' if node['options'][2] == 1
757
- output << 'ANALYZE' if node['options'][1] == 1
758
- output
759
- end
760
-
761
- def deparse_do_stmt(node)
762
- output = []
763
- output << 'DO'
764
- statement, *rest = node['args']
765
- output << "$$#{statement['DefElem']['arg']['String']['str']}$$"
766
- output += rest.map { |item| deparse_item(item) }
767
- output.join(' ')
768
- end
769
-
770
- def deparse_cte(node)
771
- output = []
772
- output << node['ctename']
773
- output << format('(%s)', node['aliascolnames'].map { |n| deparse_item(n) }.join(', ')) if node['aliascolnames']
774
- output << format('AS (%s)', deparse_item(node['ctequery']))
775
- output.join(' ')
776
- end
777
-
778
- def deparse_case(node)
779
- output = ['CASE']
780
- output << deparse_item(node['arg']) if node['arg']
781
- output += node['args'].map { |arg| deparse_item(arg) }
782
- if node['defresult']
783
- output << 'ELSE'
784
- output << deparse_item(node['defresult'])
785
- end
786
- output << 'END'
787
- output.join(' ')
788
- end
789
-
790
- def deparse_columndef(node)
791
- output = [node['colname']]
792
- output << deparse_item(node['typeName'])
793
- if node['raw_default']
794
- output << 'USING'
795
- output << deparse_item(node['raw_default'])
796
- end
797
- if node['constraints']
798
- output += node['constraints'].map do |item|
799
- deparse_item(item)
800
- end
801
- end
802
- if node['collClause']
803
- output << 'COLLATE'
804
- output += node['collClause']['CollateClause']['collname'].map(&method(:deparse_item))
805
- end
806
- output.compact.join(' ')
807
- end
808
-
809
- def deparse_composite_type(node)
810
- output = ['CREATE TYPE']
811
- output << deparse_rangevar(node['typevar'][RANGE_VAR].merge('inh' => true))
812
- output << 'AS'
813
- coldeflist = node['coldeflist'].map(&method(:deparse_item))
814
- output << "(#{coldeflist.join(', ')})"
815
- output.join(' ')
816
- end
817
-
818
- def deparse_constraint(node) # rubocop:disable Metrics/CyclomaticComplexity
819
- output = []
820
- if node['conname']
821
- output << 'CONSTRAINT'
822
- output << node['conname']
823
- end
824
- case node['contype']
825
- when CONSTR_TYPE_NULL
826
- output << 'NULL'
827
- when CONSTR_TYPE_NOTNULL
828
- output << 'NOT NULL'
829
- when CONSTR_TYPE_DEFAULT
830
- output << 'DEFAULT'
831
- when CONSTR_TYPE_CHECK
832
- output << 'CHECK'
833
- when CONSTR_TYPE_PRIMARY
834
- output << 'PRIMARY KEY'
835
- when CONSTR_TYPE_UNIQUE
836
- output << 'UNIQUE'
837
- when CONSTR_TYPE_EXCLUSION
838
- output << 'EXCLUSION'
839
- when CONSTR_TYPE_FOREIGN
840
- output << 'FOREIGN KEY'
841
- end
842
-
843
- if node['raw_expr']
844
- expression = deparse_item(node['raw_expr'])
845
- # Unless it's simple, put parentheses around it
846
- expression = '(' + expression + ')' if node['raw_expr'][BOOL_EXPR]
847
- expression = '(' + expression + ')' if node['raw_expr'][A_EXPR] && node['raw_expr'][A_EXPR]['kind'] == AEXPR_OP
848
- output << expression
849
- end
850
- output << '(' + deparse_item_list(node['keys']).join(', ') + ')' if node['keys']
851
- output << '(' + deparse_item_list(node['fk_attrs']).join(', ') + ')' if node['fk_attrs']
852
- output << 'REFERENCES ' + deparse_item(node['pktable']) + ' (' + deparse_item_list(node['pk_attrs']).join(', ') + ')' if node['pktable']
853
- output << 'NOT VALID' if node['skip_validation']
854
- output << "USING INDEX #{node['indexname']}" if node['indexname']
855
- output.join(' ')
856
- end
857
-
858
- def deparse_copy(node)
859
- output = ['COPY']
860
- if node.key?('relation')
861
- output << deparse_item(node['relation'])
862
- elsif node.key?('query')
863
- output << "(#{deparse_item(node['query'])})"
864
- end
865
- columns = node.fetch('attlist', []).map { |column| deparse_item(column) }
866
- output << "(#{columns.join(', ')})" unless columns.empty?
867
- output << (node['is_from'] ? 'FROM' : 'TO')
868
- output << 'PROGRAM' if node['is_program']
869
- output << deparse_copy_output(node)
870
- output.join(' ')
871
- end
872
-
873
- def deparse_copy_output(node)
874
- return "'#{node['filename']}'" if node.key?('filename')
875
- return 'STDIN' if node['is_from']
876
- 'STDOUT'
877
- end
878
-
879
- def deparse_create_enum(node)
880
- output = ['CREATE TYPE']
881
- output << deparse_item(node['typeName'][0])
882
- output << 'AS ENUM'
883
- vals = node['vals'].map { |val| deparse_item(val, A_CONST) }
884
- output << "(#{vals.join(', ')})"
885
- output.join(' ')
886
- end
887
-
888
- def deparse_create_cast(node)
889
- output = []
890
- output << 'CREATE'
891
- output << 'CAST'
892
- output << format('(%s AS %s)', deparse_item(node['sourcetype']), deparse_item(node['targettype']))
893
- output << if node['func']
894
- function = node['func']['ObjectWithArgs']
895
- name = deparse_item_list(function['objname']).join('.')
896
- arguments = deparse_item_list(function['objargs']).join(', ')
897
- format('WITH FUNCTION %s(%s)', name, arguments)
898
- elsif node['inout']
899
- 'WITH INOUT'
900
- else
901
- 'WITHOUT FUNCTION'
902
- end
903
- output << 'AS IMPLICIT' if (node['context']).zero?
904
- output << 'AS ASSIGNMENT' if node['context'] == 1
905
- output.join(' ')
906
- end
907
-
908
- def deparse_create_domain(node)
909
- output = []
910
- output << 'CREATE'
911
- output << 'DOMAIN'
912
- output << deparse_item_list(node['domainname']).join('.')
913
- output << 'AS'
914
- output << deparse_item(node['typeName']) if node['typeName']
915
- output << deparse_item(node['collClause']) if node['collClause']
916
- output << deparse_item_list(node['constraints'])
917
- output.join(' ')
918
- end
919
-
920
- def deparse_create_function(node)
921
- output = []
922
- output << 'CREATE'
923
- output << 'OR REPLACE' if node['replace']
924
- output << 'FUNCTION'
925
-
926
- arguments = deparse_item_list(node.fetch('parameters', [])).join(', ')
927
-
928
- output << deparse_item_list(node['funcname']).join('.') + '(' + arguments + ')'
929
-
930
- output << 'RETURNS'
931
- output << deparse_item(node['returnType'])
932
- output += node['options'].map { |item| deparse_item(item) }
933
-
934
- output.join(' ')
935
- end
936
-
937
- def deparse_create_range(node)
938
- output = ['CREATE TYPE']
939
- output << deparse_item(node['typeName'][0])
940
- output << 'AS RANGE'
941
- params = node['params'].map do |param|
942
- param_out = [param['DefElem']['defname']]
943
- if param['DefElem'].key?('arg')
944
- param_out << deparse_item(param['DefElem']['arg'])
945
- end
946
- param_out.join('=')
947
- end
948
- output << "(#{params.join(', ')})"
949
- output.join(' ')
950
- end
951
-
952
- def deparse_create_schema(node)
953
- output = ['CREATE SCHEMA']
954
- output << 'IF NOT EXISTS' if node['if_not_exists']
955
- output << deparse_identifier(node['schemaname']) if node.key?('schemaname')
956
- output << format('AUTHORIZATION %s', deparse_item(node['authrole'])) if node.key?('authrole')
957
- output << deparse_item_list(node['schemaElts']) if node.key?('schemaElts')
958
- output.join(' ')
959
- end
960
-
961
- def deparse_create_table(node)
962
- output = []
963
- output << 'CREATE'
964
-
965
- persistence = relpersistence(node['relation'])
966
- output << persistence if persistence
967
-
968
- output << 'TABLE'
969
-
970
- output << 'IF NOT EXISTS' if node['if_not_exists']
971
-
972
- output << deparse_item(node['relation'])
973
-
974
- output << '(' + node['tableElts'].map do |item|
975
- deparse_item(item)
976
- end.join(', ') + ')'
977
-
978
- if node['inhRelations']
979
- output << 'INHERITS'
980
- output << '(' + node['inhRelations'].map do |relation|
981
- deparse_item(relation)
982
- end.join(', ') + ')'
983
- end
984
-
985
- output.join(' ')
986
- end
987
-
988
- def deparse_create_table_as(node)
989
- output = []
990
- output << 'CREATE TEMPORARY TABLE'
991
- output << deparse_item(node['into'])
992
- output << 'AS'
993
- output << deparse_item(node['query'])
994
- output.join(' ')
995
- end
996
-
997
- def deparse_execute(node)
998
- output = ['EXECUTE']
999
- output << deparse_identifier(node['name'])
1000
- output << "(#{deparse_item_list(node['params']).join(', ')})" if node['params']
1001
- output.join(' ')
1002
- end
1003
-
1004
- def deparse_into_clause(node)
1005
- deparse_item(node['rel'])
1006
- end
1007
-
1008
- def deparse_when(node)
1009
- output = ['WHEN']
1010
- output << deparse_item(node['expr'])
1011
- output << 'THEN'
1012
- output << deparse_item(node['result'])
1013
- output.join(' ')
1014
- end
1015
-
1016
- def deparse_sublink(node)
1017
- if node['subLinkType'] == SUBLINK_TYPE_ANY
1018
- format('%s IN (%s)', deparse_item(node['testexpr']), deparse_item(node['subselect']))
1019
- elsif node['subLinkType'] == SUBLINK_TYPE_ALL
1020
- format('%s %s ALL (%s)', deparse_item(node['testexpr']), deparse_item(node['operName'][0], :operator), deparse_item(node['subselect']))
1021
- elsif node['subLinkType'] == SUBLINK_TYPE_EXISTS
1022
- format('EXISTS(%s)', deparse_item(node['subselect']))
1023
- else
1024
- format('(%s)', deparse_item(node['subselect']))
1025
- end
1026
- end
1027
-
1028
- def deparse_rangesubselect(node)
1029
- output = '(' + deparse_item(node['subquery']) + ')'
1030
- if node['alias']
1031
- output + ' ' + deparse_item(node['alias'])
1032
- else
1033
- output
1034
- end
1035
- end
1036
-
1037
- def deparse_row(node)
1038
- 'ROW(' + node['args'].map { |arg| deparse_item(arg) }.join(', ') + ')'
1039
- end
1040
-
1041
- def deparse_select(node) # rubocop:disable Metrics/CyclomaticComplexity
1042
- output = []
1043
-
1044
- output << deparse_item(node['withClause']) if node['withClause']
1045
-
1046
- if node['op'] == 1
1047
- output << deparse_item(node['larg'])
1048
- output << 'UNION'
1049
- output << 'ALL' if node['all']
1050
- output << deparse_item(node['rarg'])
1051
- output.join(' ')
1052
- end
1053
-
1054
- if node['op'] == 3
1055
- output << deparse_item(node['larg'])
1056
- output << 'EXCEPT'
1057
- output << deparse_item(node['rarg'])
1058
- output.join(' ')
1059
- end
1060
-
1061
- if node[TARGET_LIST_FIELD]
1062
- output << 'SELECT'
1063
- if node['distinctClause']
1064
- output << 'DISTINCT'
1065
- unless node['distinctClause'].compact.empty?
1066
- columns = node['distinctClause'].map { |item| deparse_item(item, :select) }
1067
- output << "ON (#{columns.join(', ')})"
1068
- end
1069
- end
1070
- output << node[TARGET_LIST_FIELD].map do |item|
1071
- deparse_item(item, :select)
1072
- end.join(', ')
1073
-
1074
- if node['intoClause']
1075
- output << 'INTO'
1076
- output << deparse_item(node['intoClause'])
1077
- end
1078
- end
1079
-
1080
- if node[FROM_CLAUSE_FIELD]
1081
- output << 'FROM'
1082
- output << node[FROM_CLAUSE_FIELD].map do |item|
1083
- deparse_item(item)
1084
- end.join(', ')
1085
- end
1086
-
1087
- if node['whereClause']
1088
- output << 'WHERE'
1089
- output << deparse_item(node['whereClause'])
1090
- end
1091
-
1092
- if node['valuesLists']
1093
- output << 'VALUES'
1094
- output << node['valuesLists'].map do |value_list|
1095
- '(' + value_list.map { |v| deparse_item(v) }.join(', ') + ')'
1096
- end.join(', ')
1097
- end
1098
-
1099
- if node['groupClause']
1100
- output << 'GROUP BY'
1101
- output << node['groupClause'].map do |item|
1102
- deparse_item(item)
1103
- end.join(', ')
1104
- end
1105
-
1106
- if node['havingClause']
1107
- output << 'HAVING'
1108
- output << deparse_item(node['havingClause'])
1109
- end
1110
-
1111
- if node['sortClause']
1112
- output << 'ORDER BY'
1113
- output << node['sortClause'].map do |item|
1114
- deparse_item(item)
1115
- end.join(', ')
1116
- end
1117
-
1118
- if node['limitCount']
1119
- output << 'LIMIT'
1120
- output << deparse_item(node['limitCount'])
1121
- end
1122
-
1123
- if node['limitOffset']
1124
- output << 'OFFSET'
1125
- output << deparse_item(node['limitOffset'])
1126
- end
1127
-
1128
- if node['lockingClause']
1129
- node['lockingClause'].map do |item|
1130
- output << deparse_item(item)
1131
- end
1132
- end
1133
-
1134
- output.join(' ')
1135
- end
1136
-
1137
- def deparse_sql_value_function(node)
1138
- output = []
1139
- lookup = [
1140
- 'current_date',
1141
- 'current_time',
1142
- 'current_time', # with precision
1143
- 'current_timestamp',
1144
- 'current_timestamp', # with precision
1145
- 'localtime',
1146
- 'localtime', # with precision
1147
- 'localtimestamp',
1148
- 'localtimestamp', # with precision
1149
- 'current_role',
1150
- 'current_user',
1151
- 'session_user',
1152
- 'user',
1153
- 'current_catalog',
1154
- 'current_schema'
1155
- ]
1156
- output << lookup[node['op']]
1157
- output << "(#{node['typmod']})" unless node.fetch('typmod', -1) == -1
1158
- output.join('')
1159
- end
1160
-
1161
- def deparse_insert_into(node)
1162
- output = []
1163
- output << deparse_item(node['withClause']) if node['withClause']
1164
-
1165
- output << 'INSERT INTO'
1166
- output << deparse_item(node['relation'])
1167
-
1168
- if node['cols']
1169
- output << '(' + node['cols'].map do |column|
1170
- deparse_item(column)
1171
- end.join(', ') + ')'
1172
- end
1173
-
1174
- output << deparse_item(node['selectStmt'])
1175
-
1176
- if node['returningList']
1177
- output << 'RETURNING'
1178
- output << node['returningList'].map do |column|
1179
- deparse_item(column, :select)
1180
- end.join(', ')
1181
- end
1182
-
1183
- output.join(' ')
1184
- end
1185
-
1186
- def deparse_update(node)
1187
- output = []
1188
- output << deparse_item(node['withClause']) if node['withClause']
1189
-
1190
- output << 'UPDATE'
1191
- output << deparse_item(node['relation'])
1192
-
1193
- if node[TARGET_LIST_FIELD]
1194
- output << 'SET'
1195
- columns = node[TARGET_LIST_FIELD].map do |item|
1196
- deparse_item(item, :update)
1197
- end
1198
- output << columns.join(', ')
1199
- end
1200
-
1201
- if node['whereClause']
1202
- output << 'WHERE'
1203
- output << deparse_item(node['whereClause'])
1204
- end
1205
-
1206
- if node['returningList']
1207
- output << 'RETURNING'
1208
- output << node['returningList'].map do |item|
1209
- # RETURNING is formatted like a SELECT
1210
- deparse_item(item, :select)
1211
- end.join(', ')
1212
- end
1213
-
1214
- output.join(' ')
1215
- end
1216
-
1217
- def deparse_typecast(node)
1218
- if deparse_item(node['typeName']) == 'boolean'
1219
- deparse_item(node['arg']) == "'t'" ? 'true' : 'false'
1220
- else
1221
- context = true if node['arg']['A_Expr']
1222
- deparse_item(node['arg'], context) + '::' + deparse_typename(node['typeName'][TYPE_NAME])
1223
- end
1224
- end
1225
-
1226
- def deparse_typename(node)
1227
- names = node['names'].map { |n| deparse_item(n, TYPE_NAME) }
1228
-
1229
- # Intervals are tricky and should be handled in a separate method because
1230
- # they require performing some bitmask operations.
1231
- return deparse_interval_type(node) if names == %w[pg_catalog interval]
1232
-
1233
- output = []
1234
- output << 'SETOF' if node['setof']
1235
-
1236
- if node['typmods']
1237
- arguments = node['typmods'].map do |item|
1238
- deparse_item(item)
1239
- end.join(', ')
1240
- end
1241
- output << deparse_typename_cast(names, arguments)
1242
- output.last << '[]' if node['arrayBounds']
1243
-
1244
- output.join(' ')
1245
- end
1246
-
1247
- def deparse_typename_cast(names, arguments) # rubocop:disable Metrics/CyclomaticComplexity
1248
- catalog, type = names
1249
- # Just pass along any custom types.
1250
- # (The pg_catalog types are built-in Postgres system types and are
1251
- # handled in the case statement below)
1252
- return names.join('.') + (arguments.nil? ? '' : "(#{arguments})") if catalog != 'pg_catalog'
1253
-
1254
- case type
1255
- when 'bpchar'
1256
- # char(2) or char(9)
1257
- "char(#{arguments})"
1258
- when 'varchar'
1259
- arguments.nil? ? 'varchar' : "varchar(#{arguments})"
1260
- when 'numeric'
1261
- # numeric(3, 5)
1262
- arguments.nil? ? 'numeric' : "numeric(#{arguments})"
1263
- when 'bool'
1264
- 'boolean'
1265
- when 'int2'
1266
- 'smallint'
1267
- when 'int4'
1268
- 'int'
1269
- when 'int8'
1270
- 'bigint'
1271
- when 'real', 'float4'
1272
- 'real'
1273
- when 'float8'
1274
- 'double precision'
1275
- when 'time'
1276
- 'time'
1277
- when 'timetz'
1278
- 'time with time zone'
1279
- when 'timestamp'
1280
- 'timestamp'
1281
- when 'timestamptz'
1282
- 'timestamp with time zone'
1283
- else
1284
- raise format("Can't deparse type: %s", type)
1285
- end
1286
- end
1287
-
1288
- # Deparses interval type expressions like `interval year to month` or
1289
- # `interval hour to second(5)`
1290
- def deparse_interval_type(node)
1291
- type = ['interval']
1292
-
1293
- if node['typmods']
1294
- typmods = node['typmods'].map { |typmod| deparse_item(typmod) }
1295
- type << Interval.from_int(typmods.first.to_i).map do |part|
1296
- # only the `second` type can take an argument.
1297
- if part == 'second' && typmods.size == 2
1298
- "second(#{typmods.last})"
1299
- else
1300
- part
1301
- end.downcase
1302
- end.join(' to ')
1303
- end
1304
-
1305
- type.join(' ')
1306
- end
1307
-
1308
- def deparse_nulltest(node)
1309
- output = [deparse_item(node['arg'])]
1310
- case node['nulltesttype']
1311
- when 0
1312
- output << 'IS NULL'
1313
- when 1
1314
- output << 'IS NOT NULL'
1315
- end
1316
- output.join(' ')
1317
- end
1318
-
1319
- TRANSACTION_CMDS = {
1320
- TRANS_STMT_BEGIN => 'BEGIN',
1321
- TRANS_STMT_COMMIT => 'COMMIT',
1322
- TRANS_STMT_ROLLBACK => 'ROLLBACK',
1323
- TRANS_STMT_SAVEPOINT => 'SAVEPOINT',
1324
- TRANS_STMT_RELEASE => 'RELEASE',
1325
- TRANS_STMT_ROLLBACK_TO => 'ROLLBACK TO SAVEPOINT'
1326
- }.freeze
1327
- def deparse_transaction(node)
1328
- output = []
1329
- output << TRANSACTION_CMDS[node['kind']] || raise(format("Can't deparse TRANSACTION %s", node.inspect))
1330
-
1331
- if node['options']
1332
- output += node['options'].map { |item| deparse_item(item) }
1333
- end
1334
-
1335
- output.join(' ')
1336
- end
1337
-
1338
- def deparse_coalesce(node)
1339
- format('COALESCE(%s)', node['args'].map { |a| deparse_item(a) }.join(', '))
1340
- end
1341
-
1342
- def deparse_defelem(node)
1343
- case node['defname']
1344
- when 'as'
1345
- "AS $$#{deparse_item_list(node['arg'], :defname_as).join("\n")}$$"
1346
- when 'language'
1347
- "language #{deparse_item(node['arg'])}"
1348
- when 'volatility'
1349
- node['arg']['String']['str'].upcase # volatility does not need to be quoted
1350
- when 'strict'
1351
- deparse_item(node['arg']) == '1' ? 'RETURNS NULL ON NULL INPUT' : 'CALLED ON NULL INPUT'
1352
- else
1353
- deparse_item(node['arg'])
1354
- end
1355
- end
1356
-
1357
- def deparse_define_stmt(node)
1358
- dispatch = {
1359
- 1 => :deparse_create_aggregate,
1360
- 25 => :deparse_create_operator,
1361
- 45 => :deparse_create_type
1362
- }
1363
- method(dispatch.fetch(node['kind'])).call(node)
1364
- end
1365
-
1366
- def deparse_create_aggregate(node)
1367
- output = ['CREATE AGGREGATE']
1368
- output << node['defnames'].map(&method(:deparse_item))
1369
- args = node['args'][0] || [{ A_STAR => nil }]
1370
- output << "(#{args.map(&method(:deparse_item)).join(', ')})"
1371
- definitions = node['definition'].map do |definition|
1372
- definition_output = [definition['DefElem']['defname']]
1373
- definition_output << definition['DefElem']['arg']['TypeName']['names'].map(&method(:deparse_item)).join(', ') if definition['DefElem'].key?('arg')
1374
- definition_output.join('=')
1375
- end
1376
- output << "(#{definitions.join(', ')})"
1377
- output.join(' ')
1378
- end
1379
-
1380
- def deparse_create_operator(node)
1381
- output = ['CREATE OPERATOR']
1382
- output << node['defnames'][0]['String']['str']
1383
- definitions = node['definition'].map do |definition|
1384
- definition_output = [definition['DefElem']['defname']]
1385
- definition_output << definition['DefElem']['arg']['TypeName']['names'].map(&method(:deparse_item)).join(', ') if definition['DefElem'].key?('arg')
1386
- definition_output.join('=')
1387
- end
1388
- output << "(#{definitions.join(', ')})"
1389
- output.join(' ')
1390
- end
1391
-
1392
- def deparse_create_type(node)
1393
- output = ['CREATE TYPE']
1394
- output << node['defnames'].map(&method(:deparse_item))
1395
- if node.key?('definition')
1396
- definitions = node['definition'].map do |definition|
1397
- definition_output = [definition['DefElem']['defname']]
1398
- if definition['DefElem'].key?('arg')
1399
- definition_output += definition['DefElem']['arg']['TypeName']['names'].map(&method(:deparse_item))
1400
- end
1401
- definition_output.join('=')
1402
- end
1403
- output << "(#{definitions.join(', ')})"
1404
- end
1405
- output.join(' ')
1406
- end
1407
-
1408
- def deparse_delete_from(node)
1409
- output = []
1410
- output << deparse_item(node['withClause']) if node['withClause']
1411
-
1412
- output << 'DELETE FROM'
1413
- output << deparse_item(node['relation'])
1414
-
1415
- if node['usingClause']
1416
- output << 'USING'
1417
- output << node['usingClause'].map do |item|
1418
- deparse_item(item)
1419
- end.join(', ')
1420
- end
1421
-
1422
- if node['whereClause']
1423
- output << 'WHERE'
1424
- output << deparse_item(node['whereClause'])
1425
- end
1426
-
1427
- if node['returningList']
1428
- output << 'RETURNING'
1429
- output << node['returningList'].map do |item|
1430
- # RETURNING is formatted like a SELECT
1431
- deparse_item(item, :select)
1432
- end.join(', ')
1433
- end
1434
-
1435
- output.join(' ')
1436
- end
1437
-
1438
- def deparse_discard(node)
1439
- output = ['DISCARD']
1440
- output << 'ALL' if (node['target']).zero?
1441
- output << 'PLANS' if node['target'] == 1
1442
- output << 'SEQUENCES' if node['target'] == 2
1443
- output << 'TEMP' if node['target'] == 3
1444
- output.join(' ')
1445
- end
1446
-
1447
- def deparse_drop(node) # rubocop:disable Metrics/CyclomaticComplexity
1448
- output = ['DROP']
1449
- output << 'TABLE' if node['removeType'] == OBJECT_TYPE_TABLE
1450
- output << 'SCHEMA' if node['removeType'] == OBJECT_TYPE_SCHEMA
1451
- output << 'CONCURRENTLY' if node['concurrent']
1452
- output << 'IF EXISTS' if node['missing_ok']
1453
-
1454
- objects = node['objects']
1455
- objects = [objects] unless objects[0].is_a?(Array)
1456
- output << objects.map { |list| list.map { |object| deparse_item(object) } }.join(', ')
1457
-
1458
- output << 'CASCADE' if node['behavior'] == 1
1459
-
1460
- output.join(' ')
1461
- end
1462
-
1463
- def deparse_explain(node)
1464
- output = ['EXPLAIN']
1465
- options = node.fetch('options', []).map { |option| option['DefElem']['defname'].upcase }
1466
- if options.size == 1
1467
- output.concat(options)
1468
- elsif options.size > 1
1469
- output << "(#{options.join(', ')})"
1470
- end
1471
- output << deparse_item(node['query'])
1472
- output.join(' ')
1473
- 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
1474
17
 
1475
- # The PG parser adds several pieces of view data onto the RANGEVAR
1476
- # that need to be printed before deparse_rangevar is called.
1477
- def relpersistence(rangevar)
1478
- if rangevar[RANGE_VAR]['relpersistence'] == 't'
1479
- 'TEMPORARY'
1480
- elsif rangevar[RANGE_VAR]['relpersistence'] == 'u'
1481
- 'UNLOGGED'
1482
- end
1483
- 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 ', '')
1484
21
  end
1485
22
  end