gitlab-pg_query 1.3.1 → 2.0.4

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