pg_query 1.2.0 → 2.0.3

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 +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 +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 -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 +71 -42
  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 -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 -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