pg_query 2.2.1 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Rakefile +2 -2
  4. data/ext/pg_query/include/access/amapi.h +45 -1
  5. data/ext/pg_query/include/access/attmap.h +1 -1
  6. data/ext/pg_query/include/access/attnum.h +2 -2
  7. data/ext/pg_query/include/access/clog.h +4 -2
  8. data/ext/pg_query/include/access/commit_ts.h +6 -9
  9. data/ext/pg_query/include/access/detoast.h +1 -11
  10. data/ext/pg_query/include/access/genam.h +15 -12
  11. data/ext/pg_query/include/access/gin.h +2 -2
  12. data/ext/pg_query/include/access/htup.h +1 -1
  13. data/ext/pg_query/include/access/htup_details.h +75 -87
  14. data/ext/pg_query/include/access/itup.h +7 -1
  15. data/ext/pg_query/include/access/parallel.h +2 -2
  16. data/ext/pg_query/include/access/printtup.h +1 -1
  17. data/ext/pg_query/include/access/relation.h +1 -1
  18. data/ext/pg_query/include/access/relscan.h +17 -2
  19. data/ext/pg_query/include/access/rmgr.h +30 -3
  20. data/ext/pg_query/include/access/rmgrlist.h +23 -23
  21. data/ext/pg_query/include/access/sdir.h +1 -1
  22. data/ext/pg_query/include/access/skey.h +1 -1
  23. data/ext/pg_query/include/access/stratnum.h +4 -2
  24. data/ext/pg_query/include/access/sysattr.h +1 -1
  25. data/ext/pg_query/include/access/table.h +2 -1
  26. data/ext/pg_query/include/access/tableam.h +272 -20
  27. data/ext/pg_query/include/access/toast_compression.h +73 -0
  28. data/ext/pg_query/include/access/transam.h +123 -13
  29. data/ext/pg_query/include/access/tupconvert.h +1 -1
  30. data/ext/pg_query/include/access/tupdesc.h +1 -1
  31. data/ext/pg_query/include/access/tupmacs.h +3 -3
  32. data/ext/pg_query/include/access/twophase.h +3 -1
  33. data/ext/pg_query/include/access/xact.h +73 -19
  34. data/ext/pg_query/include/access/xlog.h +60 -155
  35. data/ext/pg_query/include/access/xlog_internal.h +40 -13
  36. data/ext/pg_query/include/access/xlogdefs.h +8 -16
  37. data/ext/pg_query/include/access/xlogprefetcher.h +55 -0
  38. data/ext/pg_query/include/access/xlogreader.h +145 -39
  39. data/ext/pg_query/include/access/xlogrecord.h +18 -9
  40. data/ext/pg_query/include/access/xlogrecovery.h +157 -0
  41. data/ext/pg_query/include/c.h +101 -44
  42. data/ext/pg_query/include/catalog/catalog.h +3 -1
  43. data/ext/pg_query/include/catalog/catversion.h +2 -2
  44. data/ext/pg_query/include/catalog/dependency.h +8 -16
  45. data/ext/pg_query/include/catalog/genbki.h +83 -5
  46. data/ext/pg_query/include/catalog/index.h +18 -3
  47. data/ext/pg_query/include/catalog/indexing.h +12 -324
  48. data/ext/pg_query/include/catalog/namespace.h +4 -2
  49. data/ext/pg_query/include/catalog/objectaccess.h +70 -2
  50. data/ext/pg_query/include/catalog/objectaddress.h +11 -6
  51. data/ext/pg_query/include/catalog/pg_aggregate.h +14 -10
  52. data/ext/pg_query/include/catalog/pg_aggregate_d.h +2 -1
  53. data/ext/pg_query/include/catalog/pg_am.h +4 -1
  54. data/ext/pg_query/include/catalog/pg_am_d.h +3 -1
  55. data/ext/pg_query/include/catalog/pg_attribute.h +27 -10
  56. data/ext/pg_query/include/catalog/pg_attribute_d.h +21 -18
  57. data/ext/pg_query/include/catalog/pg_authid.h +7 -2
  58. data/ext/pg_query/include/catalog/pg_authid_d.h +17 -9
  59. data/ext/pg_query/include/catalog/pg_class.h +44 -14
  60. data/ext/pg_query/include/catalog/pg_class_d.h +30 -1
  61. data/ext/pg_query/include/catalog/pg_collation.h +33 -8
  62. data/ext/pg_query/include/catalog/pg_collation_d.h +20 -3
  63. data/ext/pg_query/include/catalog/pg_constraint.h +38 -12
  64. data/ext/pg_query/include/catalog/pg_constraint_d.h +10 -4
  65. data/ext/pg_query/include/catalog/pg_control.h +3 -5
  66. data/ext/pg_query/include/catalog/pg_conversion.h +7 -4
  67. data/ext/pg_query/include/catalog/pg_conversion_d.h +4 -1
  68. data/ext/pg_query/include/catalog/pg_depend.h +11 -7
  69. data/ext/pg_query/include/catalog/pg_depend_d.h +3 -1
  70. data/ext/pg_query/include/catalog/pg_event_trigger.h +9 -3
  71. data/ext/pg_query/include/catalog/pg_event_trigger_d.h +3 -1
  72. data/ext/pg_query/include/catalog/pg_index.h +17 -7
  73. data/ext/pg_query/include/catalog/pg_index_d.h +20 -17
  74. data/ext/pg_query/include/catalog/pg_language.h +10 -5
  75. data/ext/pg_query/include/catalog/pg_language_d.h +3 -1
  76. data/ext/pg_query/include/catalog/pg_namespace.h +7 -2
  77. data/ext/pg_query/include/catalog/pg_namespace_d.h +3 -1
  78. data/ext/pg_query/include/catalog/pg_opclass.h +8 -5
  79. data/ext/pg_query/include/catalog/pg_opclass_d.h +3 -1
  80. data/ext/pg_query/include/catalog/pg_operator.h +18 -15
  81. data/ext/pg_query/include/catalog/pg_operator_d.h +37 -1
  82. data/ext/pg_query/include/catalog/pg_opfamily.h +6 -3
  83. data/ext/pg_query/include/catalog/pg_opfamily_d.h +3 -1
  84. data/ext/pg_query/include/catalog/pg_parameter_acl.h +60 -0
  85. data/ext/pg_query/include/catalog/pg_parameter_acl_d.h +34 -0
  86. data/ext/pg_query/include/catalog/pg_partitioned_table.h +20 -9
  87. data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +2 -1
  88. data/ext/pg_query/include/catalog/pg_proc.h +20 -11
  89. data/ext/pg_query/include/catalog/pg_proc_d.h +10 -8
  90. data/ext/pg_query/include/catalog/pg_publication.h +50 -7
  91. data/ext/pg_query/include/catalog/pg_publication_d.h +3 -1
  92. data/ext/pg_query/include/catalog/pg_replication_origin.h +6 -1
  93. data/ext/pg_query/include/catalog/pg_replication_origin_d.h +5 -1
  94. data/ext/pg_query/include/catalog/pg_statistic.h +19 -12
  95. data/ext/pg_query/include/catalog/pg_statistic_d.h +2 -1
  96. data/ext/pg_query/include/catalog/pg_statistic_ext.h +19 -5
  97. data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +7 -2
  98. data/ext/pg_query/include/catalog/pg_transform.h +8 -5
  99. data/ext/pg_query/include/catalog/pg_transform_d.h +3 -1
  100. data/ext/pg_query/include/catalog/pg_trigger.h +24 -8
  101. data/ext/pg_query/include/catalog/pg_trigger_d.h +4 -1
  102. data/ext/pg_query/include/catalog/pg_ts_config.h +6 -3
  103. data/ext/pg_query/include/catalog/pg_ts_config_d.h +3 -1
  104. data/ext/pg_query/include/catalog/pg_ts_dict.h +8 -3
  105. data/ext/pg_query/include/catalog/pg_ts_dict_d.h +3 -1
  106. data/ext/pg_query/include/catalog/pg_ts_parser.h +6 -3
  107. data/ext/pg_query/include/catalog/pg_ts_parser_d.h +3 -1
  108. data/ext/pg_query/include/catalog/pg_ts_template.h +6 -3
  109. data/ext/pg_query/include/catalog/pg_ts_template_d.h +3 -1
  110. data/ext/pg_query/include/catalog/pg_type.h +55 -24
  111. data/ext/pg_query/include/catalog/pg_type_d.h +70 -31
  112. data/ext/pg_query/include/catalog/storage.h +5 -3
  113. data/ext/pg_query/include/commands/async.h +3 -4
  114. data/ext/pg_query/include/commands/dbcommands.h +2 -1
  115. data/ext/pg_query/include/commands/defrem.h +11 -24
  116. data/ext/pg_query/include/commands/event_trigger.h +2 -2
  117. data/ext/pg_query/include/commands/explain.h +1 -1
  118. data/ext/pg_query/include/commands/prepare.h +1 -1
  119. data/ext/pg_query/include/commands/tablespace.h +2 -2
  120. data/ext/pg_query/include/commands/trigger.h +18 -16
  121. data/ext/pg_query/include/commands/user.h +2 -2
  122. data/ext/pg_query/include/commands/vacuum.h +88 -41
  123. data/ext/pg_query/include/commands/variable.h +1 -1
  124. data/ext/pg_query/include/common/file_perm.h +4 -4
  125. data/ext/pg_query/include/common/hashfn.h +1 -1
  126. data/ext/pg_query/include/common/ip.h +1 -7
  127. data/ext/pg_query/include/common/keywords.h +2 -6
  128. data/ext/pg_query/include/common/kwlookup.h +1 -1
  129. data/ext/pg_query/include/common/pg_prng.h +60 -0
  130. data/ext/pg_query/include/common/relpath.h +2 -2
  131. data/ext/pg_query/include/common/string.h +24 -1
  132. data/ext/pg_query/include/common/unicode_combining_table.h +114 -2
  133. data/ext/pg_query/include/common/unicode_east_asian_fw_table.h +125 -0
  134. data/ext/pg_query/include/datatype/timestamp.h +40 -1
  135. data/ext/pg_query/include/executor/execdesc.h +1 -1
  136. data/ext/pg_query/include/executor/executor.h +65 -22
  137. data/ext/pg_query/include/executor/functions.h +17 -3
  138. data/ext/pg_query/include/executor/instrument.h +33 -16
  139. data/ext/pg_query/include/executor/spi.h +41 -3
  140. data/ext/pg_query/include/executor/tablefunc.h +1 -1
  141. data/ext/pg_query/include/executor/tuptable.h +1 -1
  142. data/ext/pg_query/include/fmgr.h +13 -7
  143. data/ext/pg_query/include/funcapi.h +16 -4
  144. data/ext/pg_query/include/getaddrinfo.h +1 -1
  145. data/ext/pg_query/include/jit/jit.h +11 -11
  146. data/ext/pg_query/include/kwlist_d.h +517 -494
  147. data/ext/pg_query/include/lib/dshash.h +112 -0
  148. data/ext/pg_query/include/lib/ilist.h +20 -1
  149. data/ext/pg_query/include/lib/pairingheap.h +1 -1
  150. data/ext/pg_query/include/lib/simplehash.h +140 -15
  151. data/ext/pg_query/include/lib/sort_template.h +432 -0
  152. data/ext/pg_query/include/lib/stringinfo.h +1 -1
  153. data/ext/pg_query/include/libpq/auth.h +6 -4
  154. data/ext/pg_query/include/libpq/crypt.h +5 -4
  155. data/ext/pg_query/include/libpq/hba.h +43 -4
  156. data/ext/pg_query/include/libpq/libpq-be.h +23 -6
  157. data/ext/pg_query/include/libpq/libpq.h +30 -20
  158. data/ext/pg_query/include/libpq/pqcomm.h +17 -31
  159. data/ext/pg_query/include/libpq/pqformat.h +1 -1
  160. data/ext/pg_query/include/libpq/pqsignal.h +4 -4
  161. data/ext/pg_query/include/mb/pg_wchar.h +105 -23
  162. data/ext/pg_query/include/mb/stringinfo_mb.h +1 -1
  163. data/ext/pg_query/include/miscadmin.h +47 -41
  164. data/ext/pg_query/include/nodes/bitmapset.h +1 -1
  165. data/ext/pg_query/include/nodes/execnodes.h +270 -78
  166. data/ext/pg_query/include/nodes/extensible.h +4 -2
  167. data/ext/pg_query/include/nodes/lockoptions.h +1 -1
  168. data/ext/pg_query/include/nodes/makefuncs.h +7 -6
  169. data/ext/pg_query/include/nodes/memnodes.h +5 -3
  170. data/ext/pg_query/include/nodes/nodeFuncs.h +1 -1
  171. data/ext/pg_query/include/nodes/nodes.h +30 -11
  172. data/ext/pg_query/include/nodes/params.h +1 -1
  173. data/ext/pg_query/include/nodes/parsenodes.h +322 -90
  174. data/ext/pg_query/include/nodes/pathnodes.h +243 -66
  175. data/ext/pg_query/include/nodes/pg_list.h +75 -69
  176. data/ext/pg_query/include/nodes/plannodes.h +111 -28
  177. data/ext/pg_query/include/nodes/primnodes.h +99 -47
  178. data/ext/pg_query/include/nodes/print.h +1 -1
  179. data/ext/pg_query/include/nodes/tidbitmap.h +1 -1
  180. data/ext/pg_query/include/nodes/value.h +58 -39
  181. data/ext/pg_query/include/optimizer/cost.h +9 -2
  182. data/ext/pg_query/include/optimizer/geqo.h +9 -7
  183. data/ext/pg_query/include/optimizer/geqo_gene.h +1 -1
  184. data/ext/pg_query/include/optimizer/optimizer.h +25 -17
  185. data/ext/pg_query/include/optimizer/paths.h +6 -6
  186. data/ext/pg_query/include/optimizer/planmain.h +15 -14
  187. data/ext/pg_query/include/parser/analyze.h +19 -5
  188. data/ext/pg_query/include/parser/gram.h +947 -913
  189. data/ext/pg_query/include/parser/gramparse.h +1 -1
  190. data/ext/pg_query/include/parser/kwlist.h +463 -453
  191. data/ext/pg_query/include/parser/parse_agg.h +2 -7
  192. data/ext/pg_query/include/parser/parse_coerce.h +3 -1
  193. data/ext/pg_query/include/parser/parse_expr.h +2 -3
  194. data/ext/pg_query/include/parser/parse_func.h +2 -1
  195. data/ext/pg_query/include/parser/parse_node.h +21 -9
  196. data/ext/pg_query/include/parser/parse_oper.h +1 -3
  197. data/ext/pg_query/include/parser/parse_relation.h +5 -4
  198. data/ext/pg_query/include/parser/parse_type.h +1 -1
  199. data/ext/pg_query/include/parser/parser.h +31 -4
  200. data/ext/pg_query/include/parser/parsetree.h +1 -1
  201. data/ext/pg_query/include/parser/scanner.h +1 -1
  202. data/ext/pg_query/include/parser/scansup.h +2 -5
  203. data/ext/pg_query/include/partitioning/partdefs.h +1 -1
  204. data/ext/pg_query/include/pg_config.h +83 -41
  205. data/ext/pg_query/include/pg_config_manual.h +74 -21
  206. data/ext/pg_query/include/pg_getopt.h +6 -6
  207. data/ext/pg_query/include/pg_query.h +5 -4
  208. data/ext/pg_query/include/pg_query_enum_defs.c +358 -241
  209. data/ext/pg_query/include/pg_query_fingerprint_conds.c +44 -7
  210. data/ext/pg_query/include/pg_query_fingerprint_defs.c +939 -113
  211. data/ext/pg_query/include/pg_query_outfuncs_conds.c +43 -13
  212. data/ext/pg_query/include/pg_query_outfuncs_defs.c +151 -26
  213. data/ext/pg_query/include/pg_query_readfuncs_conds.c +11 -2
  214. data/ext/pg_query/include/pg_query_readfuncs_defs.c +173 -30
  215. data/ext/pg_query/include/pg_trace.h +1 -1
  216. data/ext/pg_query/include/pgstat.h +449 -1238
  217. data/ext/pg_query/include/pgtime.h +14 -4
  218. data/ext/pg_query/include/pl_gram.h +126 -128
  219. data/ext/pg_query/include/pl_reserved_kwlist.h +1 -1
  220. data/ext/pg_query/include/pl_reserved_kwlist_d.h +10 -10
  221. data/ext/pg_query/include/pl_unreserved_kwlist.h +2 -3
  222. data/ext/pg_query/include/pl_unreserved_kwlist_d.h +54 -56
  223. data/ext/pg_query/include/plerrcodes.h +9 -1
  224. data/ext/pg_query/include/plpgsql.h +52 -54
  225. data/ext/pg_query/include/port/atomics/arch-arm.h +7 -1
  226. data/ext/pg_query/include/port/atomics/arch-ppc.h +1 -1
  227. data/ext/pg_query/include/port/atomics/arch-x86.h +1 -1
  228. data/ext/pg_query/include/port/atomics/fallback.h +1 -1
  229. data/ext/pg_query/include/port/atomics/generic-gcc.h +3 -3
  230. data/ext/pg_query/include/port/atomics/generic.h +1 -1
  231. data/ext/pg_query/include/port/atomics.h +1 -1
  232. data/ext/pg_query/include/port/pg_bitutils.h +40 -10
  233. data/ext/pg_query/include/port/pg_bswap.h +1 -1
  234. data/ext/pg_query/include/port/pg_crc32c.h +1 -1
  235. data/ext/pg_query/include/port.h +71 -46
  236. data/ext/pg_query/include/portability/instr_time.h +1 -1
  237. data/ext/pg_query/include/postgres.h +60 -16
  238. data/ext/pg_query/include/postmaster/autovacuum.h +17 -17
  239. data/ext/pg_query/include/postmaster/auxprocess.h +20 -0
  240. data/ext/pg_query/include/postmaster/bgworker.h +2 -1
  241. data/ext/pg_query/include/postmaster/bgworker_internals.h +2 -2
  242. data/ext/pg_query/include/postmaster/bgwriter.h +5 -5
  243. data/ext/pg_query/include/postmaster/fork_process.h +1 -1
  244. data/ext/pg_query/include/postmaster/interrupt.h +1 -1
  245. data/ext/pg_query/include/postmaster/pgarch.h +42 -8
  246. data/ext/pg_query/include/postmaster/postmaster.h +18 -17
  247. data/ext/pg_query/include/postmaster/startup.h +39 -0
  248. data/ext/pg_query/include/postmaster/syslogger.h +15 -10
  249. data/ext/pg_query/include/postmaster/walwriter.h +3 -3
  250. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +1419 -914
  251. data/ext/pg_query/include/protobuf/pg_query.pb.h +43678 -32769
  252. data/ext/pg_query/include/regex/regex.h +18 -16
  253. data/ext/pg_query/include/replication/logicallauncher.h +3 -5
  254. data/ext/pg_query/include/replication/logicalproto.h +161 -17
  255. data/ext/pg_query/include/replication/logicalworker.h +1 -1
  256. data/ext/pg_query/include/replication/origin.h +7 -7
  257. data/ext/pg_query/include/replication/reorderbuffer.h +259 -42
  258. data/ext/pg_query/include/replication/slot.h +22 -11
  259. data/ext/pg_query/include/replication/syncrep.h +5 -5
  260. data/ext/pg_query/include/replication/walreceiver.h +145 -13
  261. data/ext/pg_query/include/replication/walsender.h +8 -8
  262. data/ext/pg_query/include/rewrite/prs2lock.h +1 -1
  263. data/ext/pg_query/include/rewrite/rewriteHandler.h +1 -3
  264. data/ext/pg_query/include/rewrite/rewriteManip.h +1 -1
  265. data/ext/pg_query/include/rewrite/rewriteSupport.h +1 -1
  266. data/ext/pg_query/include/storage/backendid.h +3 -3
  267. data/ext/pg_query/include/storage/block.h +4 -10
  268. data/ext/pg_query/include/storage/buf.h +1 -1
  269. data/ext/pg_query/include/storage/bufmgr.h +19 -14
  270. data/ext/pg_query/include/storage/bufpage.h +6 -8
  271. data/ext/pg_query/include/storage/condition_variable.h +13 -2
  272. data/ext/pg_query/include/storage/dsm.h +4 -1
  273. data/ext/pg_query/include/storage/dsm_impl.h +3 -2
  274. data/ext/pg_query/include/storage/fd.h +33 -3
  275. data/ext/pg_query/include/storage/fileset.h +40 -0
  276. data/ext/pg_query/include/storage/ipc.h +4 -1
  277. data/ext/pg_query/include/storage/item.h +1 -1
  278. data/ext/pg_query/include/storage/itemid.h +1 -1
  279. data/ext/pg_query/include/storage/itemptr.h +3 -1
  280. data/ext/pg_query/include/storage/large_object.h +2 -2
  281. data/ext/pg_query/include/storage/latch.h +9 -13
  282. data/ext/pg_query/include/storage/lmgr.h +2 -1
  283. data/ext/pg_query/include/storage/lock.h +11 -8
  284. data/ext/pg_query/include/storage/lockdefs.h +2 -2
  285. data/ext/pg_query/include/storage/lwlock.h +5 -32
  286. data/ext/pg_query/include/storage/lwlocknames.h +0 -1
  287. data/ext/pg_query/include/storage/off.h +1 -1
  288. data/ext/pg_query/include/storage/pg_sema.h +1 -1
  289. data/ext/pg_query/include/storage/pg_shmem.h +9 -7
  290. data/ext/pg_query/include/storage/pmsignal.h +15 -4
  291. data/ext/pg_query/include/storage/predicate.h +4 -4
  292. data/ext/pg_query/include/storage/proc.h +173 -59
  293. data/ext/pg_query/include/storage/procarray.h +98 -0
  294. data/ext/pg_query/include/storage/proclist_types.h +1 -1
  295. data/ext/pg_query/include/storage/procsignal.h +3 -7
  296. data/ext/pg_query/include/storage/relfilenode.h +1 -1
  297. data/ext/pg_query/include/storage/s_lock.h +60 -21
  298. data/ext/pg_query/include/storage/sharedfileset.h +3 -11
  299. data/ext/pg_query/include/storage/shm_mq.h +5 -4
  300. data/ext/pg_query/include/storage/shm_toc.h +1 -1
  301. data/ext/pg_query/include/storage/shmem.h +1 -1
  302. data/ext/pg_query/include/storage/sinval.h +3 -3
  303. data/ext/pg_query/include/storage/sinvaladt.h +1 -1
  304. data/ext/pg_query/include/storage/smgr.h +10 -8
  305. data/ext/pg_query/include/storage/spin.h +2 -2
  306. data/ext/pg_query/include/storage/standby.h +13 -6
  307. data/ext/pg_query/include/storage/standbydefs.h +2 -2
  308. data/ext/pg_query/include/storage/sync.h +7 -3
  309. data/ext/pg_query/include/tcop/cmdtag.h +1 -1
  310. data/ext/pg_query/include/tcop/cmdtaglist.h +3 -2
  311. data/ext/pg_query/include/tcop/deparse_utility.h +1 -1
  312. data/ext/pg_query/include/tcop/dest.h +1 -1
  313. data/ext/pg_query/include/tcop/fastpath.h +1 -2
  314. data/ext/pg_query/include/tcop/pquery.h +1 -1
  315. data/ext/pg_query/include/tcop/tcopprot.h +19 -11
  316. data/ext/pg_query/include/tcop/utility.h +7 -3
  317. data/ext/pg_query/include/tsearch/ts_cache.h +2 -2
  318. data/ext/pg_query/include/utils/acl.h +24 -3
  319. data/ext/pg_query/include/utils/aclchk_internal.h +1 -1
  320. data/ext/pg_query/include/utils/array.h +7 -2
  321. data/ext/pg_query/include/utils/backend_progress.h +44 -0
  322. data/ext/pg_query/include/utils/backend_status.h +321 -0
  323. data/ext/pg_query/include/utils/builtins.h +10 -11
  324. data/ext/pg_query/include/utils/bytea.h +3 -2
  325. data/ext/pg_query/include/utils/catcache.h +1 -1
  326. data/ext/pg_query/include/utils/date.h +1 -1
  327. data/ext/pg_query/include/utils/datetime.h +8 -7
  328. data/ext/pg_query/include/utils/datum.h +9 -1
  329. data/ext/pg_query/include/utils/dsa.h +1 -1
  330. data/ext/pg_query/include/utils/dynahash.h +4 -3
  331. data/ext/pg_query/include/utils/elog.h +52 -21
  332. data/ext/pg_query/include/utils/errcodes.h +2 -0
  333. data/ext/pg_query/include/utils/expandeddatum.h +1 -1
  334. data/ext/pg_query/include/utils/expandedrecord.h +1 -1
  335. data/ext/pg_query/include/utils/float.h +7 -7
  336. data/ext/pg_query/include/utils/fmgroids.h +1300 -696
  337. data/ext/pg_query/include/utils/fmgrprotos.h +199 -16
  338. data/ext/pg_query/include/utils/fmgrtab.h +6 -5
  339. data/ext/pg_query/include/utils/guc.h +69 -43
  340. data/ext/pg_query/include/utils/guc_tables.h +23 -19
  341. data/ext/pg_query/include/utils/hsearch.h +15 -11
  342. data/ext/pg_query/include/utils/inval.h +4 -1
  343. data/ext/pg_query/include/utils/lsyscache.h +11 -1
  344. data/ext/pg_query/include/utils/memdebug.h +1 -1
  345. data/ext/pg_query/include/utils/memutils.h +8 -3
  346. data/ext/pg_query/include/utils/numeric.h +19 -5
  347. data/ext/pg_query/include/utils/palloc.h +25 -3
  348. data/ext/pg_query/include/utils/partcache.h +1 -1
  349. data/ext/pg_query/include/utils/pg_locale.h +17 -9
  350. data/ext/pg_query/include/utils/pg_lsn.h +1 -1
  351. data/ext/pg_query/include/utils/pgstat_internal.h +784 -0
  352. data/ext/pg_query/include/utils/pidfile.h +1 -1
  353. data/ext/pg_query/include/utils/plancache.h +6 -5
  354. data/ext/pg_query/include/utils/portal.h +10 -12
  355. data/ext/pg_query/include/utils/ps_status.h +1 -1
  356. data/ext/pg_query/include/utils/queryenvironment.h +1 -1
  357. data/ext/pg_query/include/utils/queryjumble.h +88 -0
  358. data/ext/pg_query/include/utils/regproc.h +14 -3
  359. data/ext/pg_query/include/utils/rel.h +71 -19
  360. data/ext/pg_query/include/utils/relcache.h +8 -5
  361. data/ext/pg_query/include/utils/reltrigger.h +1 -1
  362. data/ext/pg_query/include/utils/resowner.h +1 -1
  363. data/ext/pg_query/include/utils/rls.h +2 -2
  364. data/ext/pg_query/include/utils/ruleutils.h +4 -1
  365. data/ext/pg_query/include/utils/sharedtuplestore.h +1 -1
  366. data/ext/pg_query/include/utils/snapmgr.h +34 -14
  367. data/ext/pg_query/include/utils/snapshot.h +14 -1
  368. data/ext/pg_query/include/utils/sortsupport.h +117 -2
  369. data/ext/pg_query/include/utils/syscache.h +6 -1
  370. data/ext/pg_query/include/utils/timeout.h +11 -4
  371. data/ext/pg_query/include/utils/timestamp.h +6 -5
  372. data/ext/pg_query/include/utils/tuplesort.h +25 -11
  373. data/ext/pg_query/include/utils/tuplestore.h +2 -2
  374. data/ext/pg_query/include/utils/typcache.h +24 -17
  375. data/ext/pg_query/include/utils/tzparser.h +1 -1
  376. data/ext/pg_query/include/utils/varlena.h +5 -3
  377. data/ext/pg_query/include/utils/wait_event.h +289 -0
  378. data/ext/pg_query/include/utils/xml.h +4 -4
  379. data/ext/pg_query/pg_query.pb-c.c +4302 -2304
  380. data/ext/pg_query/pg_query_deparse.c +986 -301
  381. data/ext/pg_query/pg_query_fingerprint.c +30 -10
  382. data/ext/pg_query/pg_query_json_plpgsql.c +0 -25
  383. data/ext/pg_query/pg_query_normalize.c +1 -1
  384. data/ext/pg_query/pg_query_outfuncs_json.c +54 -16
  385. data/ext/pg_query/pg_query_outfuncs_protobuf.c +70 -10
  386. data/ext/pg_query/pg_query_parse.c +1 -1
  387. data/ext/pg_query/pg_query_readfuncs_protobuf.c +42 -8
  388. data/ext/pg_query/pg_query_scan.c +2 -1
  389. data/ext/pg_query/pg_query_split.c +3 -2
  390. data/ext/pg_query/src_backend_catalog_namespace.c +20 -9
  391. data/ext/pg_query/src_backend_catalog_pg_proc.c +4 -1
  392. data/ext/pg_query/src_backend_commands_define.c +11 -1
  393. data/ext/pg_query/src_backend_nodes_bitmapset.c +3 -1
  394. data/ext/pg_query/src_backend_nodes_copyfuncs.c +401 -76
  395. data/ext/pg_query/src_backend_nodes_equalfuncs.c +290 -46
  396. data/ext/pg_query/src_backend_nodes_extensible.c +1 -1
  397. data/ext/pg_query/src_backend_nodes_list.c +74 -11
  398. data/ext/pg_query/src_backend_nodes_makefuncs.c +5 -4
  399. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +55 -12
  400. data/ext/pg_query/src_backend_nodes_value.c +28 -19
  401. data/ext/pg_query/src_backend_parser_gram.c +33874 -31261
  402. data/ext/pg_query/src_backend_parser_parser.c +26 -7
  403. data/ext/pg_query/src_backend_parser_scan.c +172 -209
  404. data/ext/pg_query/src_backend_parser_scansup.c +4 -28
  405. data/ext/pg_query/src_backend_postmaster_postmaster.c +77 -106
  406. data/ext/pg_query/src_backend_storage_ipc_ipc.c +13 -4
  407. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +5 -4
  408. data/ext/pg_query/src_backend_tcop_postgres.c +62 -23
  409. data/ext/pg_query/src_backend_utils_activity_pgstat_database.c +140 -0
  410. data/ext/pg_query/src_backend_utils_adt_datum.c +13 -1
  411. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +1 -1
  412. data/ext/pg_query/src_backend_utils_adt_format_type.c +6 -2
  413. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +71 -5
  414. data/ext/pg_query/src_backend_utils_error_assert.c +16 -14
  415. data/ext/pg_query/src_backend_utils_error_elog.c +172 -99
  416. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +12 -17
  417. data/ext/pg_query/src_backend_utils_hash_dynahash.c +40 -10
  418. data/ext/pg_query/src_backend_utils_init_globals.c +5 -5
  419. data/ext/pg_query/src_backend_utils_mb_mbutils.c +55 -66
  420. data/ext/pg_query/src_backend_utils_misc_guc.c +206 -45
  421. data/ext/pg_query/src_backend_utils_mmgr_aset.c +7 -5
  422. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +123 -35
  423. data/ext/pg_query/src_common_encnames.c +1 -1
  424. data/ext/pg_query/src_common_hashfn.c +3 -3
  425. data/ext/pg_query/src_common_keywords.c +15 -2
  426. data/ext/pg_query/src_common_kwlist_d.h +517 -494
  427. data/ext/pg_query/src_common_kwlookup.c +1 -1
  428. data/ext/pg_query/src_common_pg_prng.c +152 -0
  429. data/ext/pg_query/src_common_psprintf.c +1 -1
  430. data/ext/pg_query/src_common_string.c +7 -1
  431. data/ext/pg_query/src_common_stringinfo.c +1 -1
  432. data/ext/pg_query/src_common_wchar.c +701 -109
  433. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +45 -20
  434. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +1 -18
  435. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1233 -1259
  436. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +1 -1
  437. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +10 -10
  438. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +2 -2
  439. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +54 -56
  440. data/ext/pg_query/src_port_pg_bitutils.c +41 -31
  441. data/ext/pg_query/src_port_pgsleep.c +1 -1
  442. data/ext/pg_query/src_port_pgstrcasecmp.c +1 -1
  443. data/ext/pg_query/src_port_qsort.c +12 -224
  444. data/ext/pg_query/src_port_snprintf.c +37 -13
  445. data/ext/pg_query/src_port_strerror.c +9 -19
  446. data/ext/pg_query/src_port_strnlen.c +1 -1
  447. data/lib/pg_query/filter_columns.rb +1 -1
  448. data/lib/pg_query/fingerprint.rb +5 -1
  449. data/lib/pg_query/node.rb +2 -2
  450. data/lib/pg_query/param_refs.rb +1 -1
  451. data/lib/pg_query/parse.rb +8 -7
  452. data/lib/pg_query/pg_query_pb.rb +1108 -942
  453. data/lib/pg_query/truncate.rb +1 -1
  454. data/lib/pg_query/version.rb +1 -1
  455. metadata +23 -13
  456. data/ext/pg_query/include/access/xloginsert.h +0 -64
  457. data/ext/pg_query/include/bootstrap/bootstrap.h +0 -62
  458. data/ext/pg_query/include/parser/parse_clause.h +0 -54
  459. data/ext/pg_query/include/parser/parse_collate.h +0 -27
  460. data/ext/pg_query/include/parser/parse_target.h +0 -46
  461. data/ext/pg_query/pg_query_ruby_freebsd.sym +0 -2
  462. data/ext/pg_query/src_backend_libpq_pqcomm.c +0 -659
  463. data/ext/pg_query/src_backend_parser_parse_expr.c +0 -313
  464. data/ext/pg_query/src_port_erand48.c +0 -127
  465. data/ext/pg_query/src_port_random.c +0 -31
@@ -204,7 +204,7 @@ static void deparsePreparableStmt(StringInfo str, Node *node);
204
204
  static void deparseRuleActionStmt(StringInfo str, Node *node);
205
205
  static void deparseExplainableStmt(StringInfo str, Node *node);
206
206
  static void deparseStmt(StringInfo str, Node *node);
207
- static void deparseValue(StringInfo str, Value *value, DeparseNodeContext context);
207
+ static void deparseValue(StringInfo str, union ValUnion *value, DeparseNodeContext context);
208
208
 
209
209
  // "any_name" in gram.y
210
210
  static void deparseAnyName(StringInfo str, List *parts)
@@ -249,6 +249,8 @@ static void deparseAnyNameSkipLast(StringInfo str, List *parts)
249
249
  // "a_expr" / "b_expr" in gram.y
250
250
  static void deparseExpr(StringInfo str, Node *node)
251
251
  {
252
+ if (node == NULL)
253
+ return;
252
254
  switch (nodeTag(node))
253
255
  {
254
256
  case T_FuncCall:
@@ -381,7 +383,6 @@ static void deparseCExpr(StringInfo str, Node *node)
381
383
  static void deparseExprList(StringInfo str, List *exprs)
382
384
  {
383
385
  ListCell *lc;
384
-
385
386
  foreach(lc, exprs)
386
387
  {
387
388
  deparseExpr(str, lfirst(lc));
@@ -460,15 +461,15 @@ static void deparseSimpleTypename(StringInfo str, Node *node)
460
461
  }
461
462
 
462
463
  // "NumericOnly" in gram.y
463
- static void deparseNumericOnly(StringInfo str, Value *value)
464
+ static void deparseNumericOnly(StringInfo str, union ValUnion *value)
464
465
  {
465
466
  switch (nodeTag(value))
466
467
  {
467
468
  case T_Integer:
468
- appendStringInfo(str, "%d", value->val.ival);
469
+ appendStringInfo(str, "%d", value->ival.ival);
469
470
  break;
470
471
  case T_Float:
471
- appendStringInfoString(str, value->val.str);
472
+ appendStringInfoString(str, value->sval.sval);
472
473
  break;
473
474
  default:
474
475
  Assert(false);
@@ -482,7 +483,7 @@ static void deparseNumericOnlyList(StringInfo str, List *l)
482
483
 
483
484
  foreach(lc, l)
484
485
  {
485
- deparseNumericOnly(str, (Value *) lfirst(lc));
486
+ deparseNumericOnly(str, (union ValUnion *) lfirst(lc));
486
487
  if (lnext(l, lc))
487
488
  appendStringInfoString(str, ", ");
488
489
  }
@@ -501,25 +502,25 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
501
502
  else if (strcmp(def_elem->defname, "cache") == 0)
502
503
  {
503
504
  appendStringInfoString(str, "CACHE ");
504
- deparseNumericOnly(str, (Value *) def_elem->arg);
505
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
505
506
  }
506
- else if (strcmp(def_elem->defname, "cycle") == 0 && intVal(def_elem->arg) == 1)
507
+ else if (strcmp(def_elem->defname, "cycle") == 0 && boolVal(def_elem->arg))
507
508
  {
508
509
  appendStringInfoString(str, "CYCLE");
509
510
  }
510
- else if (strcmp(def_elem->defname, "cycle") == 0 && intVal(def_elem->arg) == 0)
511
+ else if (strcmp(def_elem->defname, "cycle") == 0 && !boolVal(def_elem->arg))
511
512
  {
512
513
  appendStringInfoString(str, "NO CYCLE");
513
514
  }
514
515
  else if (strcmp(def_elem->defname, "increment") == 0)
515
516
  {
516
517
  appendStringInfoString(str, "INCREMENT ");
517
- deparseNumericOnly(str, (Value *) def_elem->arg);
518
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
518
519
  }
519
520
  else if (strcmp(def_elem->defname, "maxvalue") == 0 && def_elem->arg != NULL)
520
521
  {
521
522
  appendStringInfoString(str, "MAXVALUE ");
522
- deparseNumericOnly(str, (Value *) def_elem->arg);
523
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
523
524
  }
524
525
  else if (strcmp(def_elem->defname, "maxvalue") == 0 && def_elem->arg == NULL)
525
526
  {
@@ -528,7 +529,7 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
528
529
  else if (strcmp(def_elem->defname, "minvalue") == 0 && def_elem->arg != NULL)
529
530
  {
530
531
  appendStringInfoString(str, "MINVALUE ");
531
- deparseNumericOnly(str, (Value *) def_elem->arg);
532
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
532
533
  }
533
534
  else if (strcmp(def_elem->defname, "minvalue") == 0 && def_elem->arg == NULL)
534
535
  {
@@ -547,7 +548,7 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
547
548
  else if (strcmp(def_elem->defname, "start") == 0)
548
549
  {
549
550
  appendStringInfoString(str, "START ");
550
- deparseNumericOnly(str, (Value *) def_elem->arg);
551
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
551
552
  }
552
553
  else if (strcmp(def_elem->defname, "restart") == 0 && def_elem->arg == NULL)
553
554
  {
@@ -556,7 +557,7 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
556
557
  else if (strcmp(def_elem->defname, "restart") == 0 && def_elem->arg != NULL)
557
558
  {
558
559
  appendStringInfoString(str, "RESTART ");
559
- deparseNumericOnly(str, (Value *) def_elem->arg);
560
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
560
561
  }
561
562
  else
562
563
  {
@@ -711,7 +712,7 @@ static void deparseDefArg(StringInfo str, Node *arg, bool is_operator_def_arg)
711
712
  }
712
713
  else if (IsA(arg, Float) || IsA(arg, Integer)) // NumericOnly
713
714
  {
714
- deparseValue(str, (Value *) arg, DEPARSE_NODE_CONTEXT_NONE);
715
+ deparseValue(str, (union ValUnion *) arg, DEPARSE_NODE_CONTEXT_NONE);
715
716
  }
716
717
  else if (IsA(arg, String))
717
718
  {
@@ -792,11 +793,11 @@ static void deparseCreateGenericOptions(StringInfo str, List *options)
792
793
  // "common_func_opt_item" in gram.y
793
794
  static void deparseCommonFuncOptItem(StringInfo str, DefElem *def_elem)
794
795
  {
795
- if (strcmp(def_elem->defname, "strict") == 0 && intVal(def_elem->arg) == 1)
796
+ if (strcmp(def_elem->defname, "strict") == 0 && boolVal(def_elem->arg))
796
797
  {
797
798
  appendStringInfoString(str, "RETURNS NULL ON NULL INPUT");
798
799
  }
799
- else if (strcmp(def_elem->defname, "strict") == 0 && intVal(def_elem->arg) == 0)
800
+ else if (strcmp(def_elem->defname, "strict") == 0 && !boolVal(def_elem->arg))
800
801
  {
801
802
  appendStringInfoString(str, "CALLED ON NULL INPUT");
802
803
  }
@@ -812,31 +813,31 @@ static void deparseCommonFuncOptItem(StringInfo str, DefElem *def_elem)
812
813
  {
813
814
  appendStringInfoString(str, "VOLATILE");
814
815
  }
815
- else if (strcmp(def_elem->defname, "security") == 0 && intVal(def_elem->arg) == 1)
816
+ else if (strcmp(def_elem->defname, "security") == 0 && boolVal(def_elem->arg))
816
817
  {
817
818
  appendStringInfoString(str, "SECURITY DEFINER");
818
819
  }
819
- else if (strcmp(def_elem->defname, "security") == 0 && intVal(def_elem->arg) == 0)
820
+ else if (strcmp(def_elem->defname, "security") == 0 && !boolVal(def_elem->arg))
820
821
  {
821
822
  appendStringInfoString(str, "SECURITY INVOKER");
822
823
  }
823
- else if (strcmp(def_elem->defname, "leakproof") == 0 && intVal(def_elem->arg) == 1)
824
+ else if (strcmp(def_elem->defname, "leakproof") == 0 && boolVal(def_elem->arg))
824
825
  {
825
826
  appendStringInfoString(str, "LEAKPROOF");
826
827
  }
827
- else if (strcmp(def_elem->defname, "leakproof") == 0 && intVal(def_elem->arg) == 0)
828
+ else if (strcmp(def_elem->defname, "leakproof") == 0 && !boolVal(def_elem->arg))
828
829
  {
829
830
  appendStringInfoString(str, "NOT LEAKPROOF");
830
831
  }
831
832
  else if (strcmp(def_elem->defname, "cost") == 0)
832
833
  {
833
834
  appendStringInfoString(str, "COST ");
834
- deparseValue(str, (Value *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
835
+ deparseValue(str, (union ValUnion *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
835
836
  }
836
837
  else if (strcmp(def_elem->defname, "rows") == 0)
837
838
  {
838
839
  appendStringInfoString(str, "ROWS ");
839
- deparseValue(str, (Value *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
840
+ deparseValue(str, (union ValUnion *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
840
841
  }
841
842
  else if (strcmp(def_elem->defname, "support") == 0)
842
843
  {
@@ -993,19 +994,22 @@ static void deparseFuncName(StringInfo str, List *func_name)
993
994
  static void deparseFunctionWithArgtypes(StringInfo str, ObjectWithArgs *object_with_args)
994
995
  {
995
996
  ListCell *lc;
996
-
997
997
  deparseFuncName(str, object_with_args->objname);
998
998
 
999
999
  if (!object_with_args->args_unspecified)
1000
1000
  {
1001
1001
  appendStringInfoChar(str, '(');
1002
- foreach(lc, object_with_args->objargs)
1002
+ List *objargs = object_with_args->objargs;
1003
+ if (object_with_args->objfuncargs)
1004
+ objargs = object_with_args->objfuncargs;
1005
+
1006
+ foreach(lc, objargs)
1003
1007
  {
1004
- if (IsA(lfirst(lc), TypeName))
1005
- deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1006
- else
1008
+ if (IsA(lfirst(lc), FunctionParameter))
1007
1009
  deparseFunctionParameter(str, castNode(FunctionParameter, lfirst(lc)));
1008
- if (lnext(object_with_args->objargs, lc))
1010
+ else
1011
+ deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1012
+ if (lnext(objargs, lc))
1009
1013
  appendStringInfoString(str, ", ");
1010
1014
  }
1011
1015
  appendStringInfoChar(str, ')');
@@ -1095,16 +1099,23 @@ static void deparseAggregateWithArgtypes(StringInfo str, ObjectWithArgs *object_
1095
1099
  deparseFuncName(str, object_with_args->objname);
1096
1100
 
1097
1101
  appendStringInfoChar(str, '(');
1098
- if (object_with_args->objargs == NULL)
1102
+ if (object_with_args->objargs == NULL && object_with_args->objfuncargs == NULL)
1099
1103
  {
1100
1104
  appendStringInfoChar(str, '*');
1101
1105
  }
1102
1106
  else
1103
1107
  {
1104
- foreach(lc, object_with_args->objargs)
1108
+ List *objargs = object_with_args->objargs;
1109
+ if (object_with_args->objfuncargs)
1110
+ objargs = object_with_args->objfuncargs;
1111
+
1112
+ foreach(lc, objargs)
1105
1113
  {
1106
- deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1107
- if (lnext(object_with_args->objargs, lc))
1114
+ if (IsA(lfirst(lc), FunctionParameter))
1115
+ deparseFunctionParameter(str, castNode(FunctionParameter, lfirst(lc)));
1116
+ else
1117
+ deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1118
+ if (lnext(objargs, lc))
1108
1119
  appendStringInfoString(str, ", ");
1109
1120
  }
1110
1121
  }
@@ -1235,6 +1246,64 @@ static void deparseOptBooleanOrString(StringInfo str, char *s)
1235
1246
  deparseNonReservedWordOrSconst(str, s);
1236
1247
  }
1237
1248
 
1249
+ static void deparseOptBoolean(StringInfo str, Node *node)
1250
+ {
1251
+ if (node == NULL)
1252
+ {
1253
+ return;
1254
+ }
1255
+
1256
+ switch (nodeTag(node))
1257
+ {
1258
+ case T_String:
1259
+ appendStringInfo(str, " %s", strVal(node));
1260
+ break;
1261
+ case T_Integer:
1262
+ appendStringInfo(str, " %d", intVal(node));
1263
+ break;
1264
+ case T_Boolean:
1265
+ appendStringInfo(str, " %s", boolVal(node) ? "TRUE" : "FALSE");
1266
+ break;
1267
+ default:
1268
+ Assert(false);
1269
+ break;
1270
+ }
1271
+ }
1272
+
1273
+ bool optBooleanValue(Node *node)
1274
+ {
1275
+ if (node == NULL)
1276
+ {
1277
+ return true;
1278
+ }
1279
+
1280
+ switch (nodeTag(node))
1281
+ {
1282
+ case T_String: {
1283
+ // Longest valid string is "off\0"
1284
+ char lower[4];
1285
+ strncpy(lower, strVal(node), 4);
1286
+ lower[3] = 0;
1287
+
1288
+ if (strcmp(lower, "on") == 0) {
1289
+ return true;
1290
+ } else if (strcmp(lower, "off") == 0) {
1291
+ return false;
1292
+ }
1293
+
1294
+ // No sane way to handle this.
1295
+ return false;
1296
+ }
1297
+ case T_Integer:
1298
+ return intVal(node) != 0;
1299
+ case T_Boolean:
1300
+ return boolVal(node);
1301
+ default:
1302
+ Assert(false);
1303
+ return false;
1304
+ }
1305
+ }
1306
+
1238
1307
  // "var_name"
1239
1308
  //
1240
1309
  // Note this is kept separate from ColId in case we want to improve the
@@ -1259,7 +1328,7 @@ static void deparseVarList(StringInfo str, List *l)
1259
1328
  {
1260
1329
  A_Const *a_const = castNode(A_Const, lfirst(lc));
1261
1330
  if (IsA(&a_const->val, Integer) || IsA(&a_const->val, Float))
1262
- deparseNumericOnly(str, (Value *) &a_const->val);
1331
+ deparseNumericOnly(str, (union ValUnion *) &a_const->val);
1263
1332
  else if (IsA(&a_const->val, String))
1264
1333
  deparseOptBooleanOrString(str, strVal(&a_const->val));
1265
1334
  else
@@ -1340,7 +1409,7 @@ static void deparseAlterIdentityColumnOptionList(StringInfo str, List *l)
1340
1409
  else if (strcmp(def_elem->defname, "restart") == 0 && def_elem->arg != NULL)
1341
1410
  {
1342
1411
  appendStringInfoString(str, "RESTART ");
1343
- deparseNumericOnly(str, (Value *) def_elem->arg);
1412
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
1344
1413
  }
1345
1414
  else if (strcmp(def_elem->defname, "generated") == 0)
1346
1415
  {
@@ -2010,6 +2079,38 @@ static void deparseCreatedbOptList(StringInfo str, List *l)
2010
2079
  }
2011
2080
  }
2012
2081
 
2082
+ // "utility_option_list" in gram.y
2083
+ static void deparseUtilityOptionList(StringInfo str, List *options)
2084
+ {
2085
+ ListCell *lc = NULL;
2086
+ char *defname = NULL;
2087
+
2088
+ if (list_length(options) > 0)
2089
+ {
2090
+ appendStringInfoChar(str, '(');
2091
+ foreach(lc, options)
2092
+ {
2093
+ DefElem *def_elem = castNode(DefElem, lfirst(lc));
2094
+ deparseGenericDefElemName(str, def_elem->defname);
2095
+
2096
+ if (def_elem->arg != NULL)
2097
+ {
2098
+ appendStringInfoChar(str, ' ');
2099
+ if (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float))
2100
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
2101
+ else if (IsA(def_elem->arg, String))
2102
+ deparseOptBooleanOrString(str, strVal(def_elem->arg));
2103
+ else
2104
+ Assert(false);
2105
+ }
2106
+
2107
+ if (lnext(options, lc))
2108
+ appendStringInfoString(str, ", ");
2109
+ }
2110
+ appendStringInfoString(str, ") ");
2111
+ }
2112
+ }
2113
+
2013
2114
  static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2014
2115
  {
2015
2116
  const ListCell *lc = NULL;
@@ -2074,6 +2175,8 @@ static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2074
2175
  if (list_length(stmt->groupClause) > 0)
2075
2176
  {
2076
2177
  appendStringInfoString(str, "GROUP BY ");
2178
+ if (stmt->groupDistinct)
2179
+ appendStringInfoString(str, "DISTINCT ");
2077
2180
  deparseGroupByList(str, stmt->groupClause);
2078
2181
  appendStringInfoChar(str, ' ');
2079
2182
  }
@@ -2159,7 +2262,7 @@ static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2159
2262
  else if (stmt->limitOption == LIMIT_OPTION_WITH_TIES)
2160
2263
  appendStringInfoString(str, "FETCH FIRST ");
2161
2264
 
2162
- if (IsA(stmt->limitCount, A_Const) && IsA(&castNode(A_Const, stmt->limitCount)->val, Null))
2265
+ if (IsA(stmt->limitCount, A_Const) && castNode(A_Const, stmt->limitCount)->isnull)
2163
2266
  appendStringInfoString(str, "ALL");
2164
2267
  else
2165
2268
  deparseCExpr(str, stmt->limitCount);
@@ -2295,7 +2398,8 @@ static void deparseAlias(StringInfo str, Alias *alias)
2295
2398
 
2296
2399
  static void deparseAConst(StringInfo str, A_Const *a_const)
2297
2400
  {
2298
- deparseValue(str, &a_const->val, DEPARSE_NODE_CONTEXT_CONSTANT);
2401
+ union ValUnion *val = a_const->isnull ? NULL : &a_const->val;
2402
+ deparseValue(str, val, DEPARSE_NODE_CONTEXT_CONSTANT);
2299
2403
  }
2300
2404
 
2301
2405
  static void deparseFuncCall(StringInfo str, FuncCall *func_call)
@@ -2323,8 +2427,217 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2323
2427
  deparseExpr(str, lfourth(func_call->args));
2324
2428
  appendStringInfoChar(str, ')');
2325
2429
  return;
2326
- }
2430
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2431
+ list_length(func_call->funcname) == 2 &&
2432
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2433
+ strcmp(strVal(lsecond(func_call->funcname)), "substring") == 0)
2434
+ {
2435
+ /*
2436
+ * "SUBSTRING" is a keyword on its own merit, and only accepts the
2437
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.substring)
2438
+ */
2439
+ Assert(list_length(func_call->args) == 2 || list_length(func_call->args) == 3);
2440
+ appendStringInfoString(str, "SUBSTRING(");
2441
+ deparseExpr(str, linitial(func_call->args));
2442
+ appendStringInfoString(str, " FROM ");
2443
+ deparseExpr(str, lsecond(func_call->args));
2444
+ if (list_length(func_call->args) == 3)
2445
+ {
2446
+ appendStringInfoString(str, " FOR ");
2447
+ deparseExpr(str, lthird(func_call->args));
2448
+ }
2449
+ appendStringInfoChar(str, ')');
2450
+ return;
2451
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2452
+ list_length(func_call->funcname) == 2 &&
2453
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2454
+ strcmp(strVal(lsecond(func_call->funcname)), "position") == 0 &&
2455
+ list_length(func_call->args) == 2)
2456
+ {
2457
+ /*
2458
+ * "POSITION" is a keyword on its own merit, and only accepts the
2459
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.position)
2460
+ * Note that the first and second arguments are switched in this format
2461
+ */
2462
+ appendStringInfoString(str, "POSITION(");
2463
+ deparseExpr(str, lsecond(func_call->args));
2464
+ appendStringInfoString(str, " IN ");
2465
+ deparseExpr(str, linitial(func_call->args));
2466
+ appendStringInfoChar(str, ')');
2467
+ return;
2468
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2469
+ list_length(func_call->funcname) == 2 &&
2470
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2471
+ strcmp(strVal(lsecond(func_call->funcname)), "overlay") == 0 &&
2472
+ list_length(func_call->args) == 3)
2473
+ {
2474
+ /*
2475
+ * "OVERLAY" is a keyword on its own merit, and only accepts the
2476
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
2477
+ */
2478
+ appendStringInfoString(str, "overlay(");
2479
+ deparseExpr(str, linitial(func_call->args));
2480
+ appendStringInfoString(str, " placing ");
2481
+ deparseExpr(str, lsecond(func_call->args));
2482
+ appendStringInfoString(str, " from ");
2483
+ deparseExpr(str, lthird(func_call->args));
2484
+ appendStringInfoChar(str, ')');
2485
+ return;
2486
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2487
+ list_length(func_call->funcname) == 2 &&
2488
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2489
+ strcmp(strVal(lsecond(func_call->funcname)), "pg_collation_for") == 0 &&
2490
+ list_length(func_call->args) == 1)
2491
+ {
2492
+ /*
2493
+ * "collation for" is a keyword on its own merit, and only accepts the
2494
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
2495
+ */
2496
+ appendStringInfoString(str, "collation for (");
2497
+ deparseExpr(str, linitial(func_call->args));
2498
+ appendStringInfoChar(str, ')');
2499
+ return;
2500
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2501
+ list_length(func_call->funcname) == 2 &&
2502
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2503
+ strcmp(strVal(lsecond(func_call->funcname)), "extract") == 0 &&
2504
+ list_length(func_call->args) == 2)
2505
+ {
2506
+ /*
2507
+ * "EXTRACT" is a keyword on its own merit, and only accepts the
2508
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.extract)
2509
+ */
2510
+ appendStringInfoString(str, "extract (");
2511
+ deparseExpr(str, linitial(func_call->args));
2512
+ appendStringInfoString(str, " FROM ");
2513
+ deparseExpr(str, lsecond(func_call->args));
2514
+ appendStringInfoChar(str, ')');
2515
+ return;
2516
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2517
+ list_length(func_call->funcname) == 2 &&
2518
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2519
+ strcmp(strVal(lsecond(func_call->funcname)), "overlaps") == 0 &&
2520
+ list_length(func_call->args) == 4)
2521
+ {
2522
+ /*
2523
+ * "OVERLAPS" is a keyword on its own merit, and only accepts the
2524
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlaps)
2525
+ * format: (start_1, end_1) overlaps (start_2, end_2)
2526
+ */
2527
+ appendStringInfoChar(str, '(');
2528
+ deparseExpr(str, linitial(func_call->args));
2529
+ appendStringInfoString(str, ", ");
2530
+ deparseExpr(str, lsecond(func_call->args));
2531
+ appendStringInfoString(str, ") ");
2532
+
2533
+ appendStringInfoString(str, "overlaps ");
2534
+ appendStringInfoChar(str, '(');
2535
+ deparseExpr(str, lthird(func_call->args));
2536
+ appendStringInfoString(str, ", ");
2537
+ deparseExpr(str, lfourth(func_call->args));
2538
+ appendStringInfoString(str, ") ");
2539
+ return;
2540
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2541
+ list_length(func_call->funcname) == 2 &&
2542
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2543
+ (
2544
+ strcmp(strVal(lsecond(func_call->funcname)), "ltrim") == 0 ||
2545
+ strcmp(strVal(lsecond(func_call->funcname)), "btrim") == 0 ||
2546
+ strcmp(strVal(lsecond(func_call->funcname)), "rtrim") == 0
2547
+ ))
2548
+ {
2549
+ /*
2550
+ * "TRIM " is a keyword on its own merit, and only accepts the
2551
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.ltrim)
2552
+ * Note that the first and second arguments are switched in this format
2553
+ */
2554
+ Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2555
+ appendStringInfoString(str, "TRIM (");
2556
+ if (strcmp(strVal(lsecond(func_call->funcname)), "ltrim") == 0)
2557
+ appendStringInfoString(str, "LEADING ");
2558
+ else if (strcmp(strVal(lsecond(func_call->funcname)), "btrim") == 0)
2559
+ appendStringInfoString(str, "BOTH ");
2560
+ else if (strcmp(strVal(lsecond(func_call->funcname)), "rtrim") == 0)
2561
+ appendStringInfoString(str, "TRAILING ");
2562
+
2563
+ if (list_length(func_call->args) == 2)
2564
+ deparseExpr(str, lsecond(func_call->args));
2565
+ appendStringInfoString(str, " FROM ");
2566
+ deparseExpr(str, linitial(func_call->args));
2567
+ appendStringInfoChar(str, ')');
2568
+ return;
2569
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2570
+ list_length(func_call->funcname) == 2 &&
2571
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2572
+ strcmp(strVal(lsecond(func_call->funcname)), "timezone") == 0 &&
2573
+ list_length(func_call->args) == 2)
2574
+ {
2575
+ /*
2576
+ * "AT TIME ZONE" is a keyword on its own merit, and only accepts the
2577
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.timezone)
2578
+ * Note that the arguments are swapped in this case
2579
+ */
2580
+ deparseExpr(str, lsecond(func_call->args));
2581
+ appendStringInfoString(str, " AT TIME ZONE ");
2582
+ deparseExpr(str, linitial(func_call->args));
2583
+ return;
2584
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2585
+ list_length(func_call->funcname) == 2 &&
2586
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2587
+ strcmp(strVal(lsecond(func_call->funcname)), "normalize") == 0)
2588
+ {
2589
+ /*
2590
+ * "NORMALIZE" is a keyword on its own merit, and only accepts the
2591
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.normalize)
2592
+ */
2593
+ Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2594
+ appendStringInfoString(str, "normalize (");
2327
2595
 
2596
+ deparseExpr(str, linitial(func_call->args));
2597
+ if (list_length(func_call->args) == 2)
2598
+ {
2599
+ appendStringInfoString(str, ", ");
2600
+ Assert(IsA(lsecond(func_call->args), A_Const));
2601
+ A_Const *aconst = lsecond(func_call->args);
2602
+ deparseValue(str, &aconst->val, DEPARSE_NODE_CONTEXT_NONE);
2603
+ }
2604
+ appendStringInfoChar(str, ')');
2605
+ return;
2606
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2607
+ list_length(func_call->funcname) == 2 &&
2608
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2609
+ strcmp(strVal(lsecond(func_call->funcname)), "is_normalized") == 0)
2610
+ {
2611
+ /*
2612
+ * "IS NORMALIZED" is a keyword on its own merit, and only accepts the
2613
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.is_normalized)
2614
+ */
2615
+ Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2616
+
2617
+ deparseExpr(str, linitial(func_call->args));
2618
+ appendStringInfoString(str, " IS ");
2619
+ if (list_length(func_call->args) == 2)
2620
+ {
2621
+ Assert(IsA(lsecond(func_call->args), A_Const));
2622
+ A_Const *aconst = lsecond(func_call->args);
2623
+ deparseValue(str, &aconst->val, DEPARSE_NODE_CONTEXT_NONE);
2624
+ }
2625
+ appendStringInfoString(str, " NORMALIZED ");
2626
+ return;
2627
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2628
+ list_length(func_call->funcname) == 2 &&
2629
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2630
+ strcmp(strVal(lsecond(func_call->funcname)), "xmlexists") == 0 &&
2631
+ list_length(func_call->args) == 2)
2632
+ {
2633
+ appendStringInfoString(str, "xmlexists (");
2634
+ deparseExpr(str, linitial(func_call->args));
2635
+ appendStringInfoString(str, " PASSING ");
2636
+ deparseExpr(str, lsecond(func_call->args));
2637
+ appendStringInfoChar(str, ')');
2638
+ return;
2639
+ }
2640
+
2328
2641
  deparseFuncName(str, func_call->funcname);
2329
2642
  appendStringInfoChar(str, '(');
2330
2643
 
@@ -2648,31 +2961,13 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2648
2961
  deparseExpr(str, a_expr->rexpr);
2649
2962
  appendStringInfoChar(str, ')');
2650
2963
  return;
2651
- case AEXPR_OF: /* IS [NOT] OF - name must be "=" or "<>" */
2652
- Assert(list_length(a_expr->name) == 1);
2653
- Assert(IsA(linitial(a_expr->name), String));
2654
- Assert(IsA(a_expr->rexpr, List));
2655
- deparseExpr(str, a_expr->lexpr);
2656
- appendStringInfoChar(str, ' ');
2657
- name = ((Value *) linitial(a_expr->name))->val.str;
2658
- if (strcmp(name, "=") == 0) {
2659
- appendStringInfoString(str, "IS OF ");
2660
- } else if (strcmp(name, "<>") == 0) {
2661
- appendStringInfoString(str, "IS NOT OF ");
2662
- } else {
2663
- Assert(false);
2664
- }
2665
- appendStringInfoChar(str, '(');
2666
- deparseTypeList(str, castNode(List, a_expr->rexpr));
2667
- appendStringInfoChar(str, ')');
2668
- return;
2669
2964
  case AEXPR_IN: /* [NOT] IN - name must be "=" or "<>" */
2670
2965
  Assert(list_length(a_expr->name) == 1);
2671
2966
  Assert(IsA(linitial(a_expr->name), String));
2672
2967
  Assert(IsA(a_expr->rexpr, List));
2673
2968
  deparseExpr(str, a_expr->lexpr);
2674
2969
  appendStringInfoChar(str, ' ');
2675
- name = ((Value *) linitial(a_expr->name))->val.str;
2970
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2676
2971
  if (strcmp(name, "=") == 0) {
2677
2972
  appendStringInfoString(str, "IN ");
2678
2973
  } else if (strcmp(name, "<>") == 0) {
@@ -2693,7 +2988,7 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2693
2988
  deparseExpr(str, a_expr->lexpr);
2694
2989
  appendStringInfoChar(str, ' ');
2695
2990
 
2696
- name = ((Value *) linitial(a_expr->name))->val.str;
2991
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2697
2992
  if (strcmp(name, "~~") == 0) {
2698
2993
  appendStringInfoString(str, "LIKE ");
2699
2994
  } else if (strcmp(name, "!~~") == 0) {
@@ -2710,7 +3005,7 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2710
3005
  deparseExpr(str, a_expr->lexpr);
2711
3006
  appendStringInfoChar(str, ' ');
2712
3007
 
2713
- name = ((Value *) linitial(a_expr->name))->val.str;
3008
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2714
3009
  if (strcmp(name, "~~*") == 0) {
2715
3010
  appendStringInfoString(str, "ILIKE ");
2716
3011
  } else if (strcmp(name, "!~~*") == 0) {
@@ -2727,7 +3022,7 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2727
3022
  deparseExpr(str, a_expr->lexpr);
2728
3023
  appendStringInfoChar(str, ' ');
2729
3024
 
2730
- name = ((Value *) linitial(a_expr->name))->val.str;
3025
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2731
3026
  if (strcmp(name, "~") == 0) {
2732
3027
  appendStringInfoString(str, "SIMILAR TO ");
2733
3028
  } else if (strcmp(name, "!~") == 0) {
@@ -2769,10 +3064,6 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2769
3064
  appendStringInfoString(str, " AND ");
2770
3065
  }
2771
3066
  return;
2772
- case AEXPR_PAREN: /* nameless dummy node for parentheses */
2773
- // Not present in parse trees when operator_precedence_warning is turned off
2774
- Assert(false);
2775
- return;
2776
3067
  }
2777
3068
  }
2778
3069
 
@@ -3032,6 +3323,12 @@ static void deparseJoinExpr(StringInfo str, JoinExpr *join_expr)
3032
3323
  appendStringInfoString(str, "USING (");
3033
3324
  deparseNameList(str, join_expr->usingClause);
3034
3325
  appendStringInfoString(str, ") ");
3326
+
3327
+ if (join_expr->join_using_alias)
3328
+ {
3329
+ appendStringInfoString(str, "AS ");
3330
+ appendStringInfoString(str, join_expr->join_using_alias->aliasname);
3331
+ }
3035
3332
  }
3036
3333
 
3037
3334
  if (need_alias_parens)
@@ -3043,6 +3340,49 @@ static void deparseJoinExpr(StringInfo str, JoinExpr *join_expr)
3043
3340
  removeTrailingSpace(str);
3044
3341
  }
3045
3342
 
3343
+ static void deparseCTESearchClause(StringInfo str, CTESearchClause *search_clause)
3344
+ {
3345
+ appendStringInfoString(str, " SEARCH ");
3346
+ if (search_clause->search_breadth_first)
3347
+ appendStringInfoString(str, "BREADTH ");
3348
+ else
3349
+ appendStringInfoString(str, "DEPTH ");
3350
+
3351
+ appendStringInfoString(str, "FIRST BY ");
3352
+
3353
+ if (search_clause->search_col_list)
3354
+ deparseColumnList(str, search_clause->search_col_list);
3355
+
3356
+ appendStringInfoString(str, " SET ");
3357
+ appendStringInfoString(str, quote_identifier(search_clause->search_seq_column));
3358
+ }
3359
+
3360
+ static void deparseCTECycleClause(StringInfo str, CTECycleClause *cycle_clause)
3361
+ {
3362
+ appendStringInfoString(str, " CYCLE ");
3363
+
3364
+ if (cycle_clause->cycle_col_list)
3365
+ deparseColumnList(str, cycle_clause->cycle_col_list);
3366
+
3367
+ appendStringInfoString(str, " SET ");
3368
+ appendStringInfoString(str, quote_identifier(cycle_clause->cycle_mark_column));
3369
+
3370
+ if (cycle_clause->cycle_mark_value)
3371
+ {
3372
+ appendStringInfoString(str, " TO ");
3373
+ deparseExpr(str, cycle_clause->cycle_mark_value);
3374
+ }
3375
+
3376
+ if (cycle_clause->cycle_mark_default)
3377
+ {
3378
+ appendStringInfoString(str, " DEFAULT ");
3379
+ deparseExpr(str, cycle_clause->cycle_mark_default);
3380
+ }
3381
+
3382
+ appendStringInfoString(str, " USING ");
3383
+ appendStringInfoString(str, quote_identifier(cycle_clause->cycle_path_column));
3384
+ }
3385
+
3046
3386
  static void deparseCommonTableExpr(StringInfo str, CommonTableExpr *cte)
3047
3387
  {
3048
3388
  deparseColId(str, cte->ctename);
@@ -3070,6 +3410,11 @@ static void deparseCommonTableExpr(StringInfo str, CommonTableExpr *cte)
3070
3410
  appendStringInfoChar(str, '(');
3071
3411
  deparsePreparableStmt(str, cte->ctequery);
3072
3412
  appendStringInfoChar(str, ')');
3413
+
3414
+ if (cte->search_clause)
3415
+ deparseCTESearchClause(str, cte->search_clause);
3416
+ if (cte->cycle_clause)
3417
+ deparseCTECycleClause(str, cte->cycle_clause);
3073
3418
  }
3074
3419
 
3075
3420
  static void deparseRangeSubselect(StringInfo str, RangeSubselect *range_subselect)
@@ -3174,6 +3519,7 @@ static void deparseRowExpr(StringInfo str, RowExpr *row_expr)
3174
3519
  case COERCE_EXPLICIT_CALL:
3175
3520
  appendStringInfoString(str, "ROW");
3176
3521
  break;
3522
+ case COERCE_SQL_SYNTAX:
3177
3523
  case COERCE_EXPLICIT_CAST:
3178
3524
  // Not present in raw parser output
3179
3525
  Assert(false);
@@ -3243,8 +3589,18 @@ static void deparseTypeCast(StringInfo str, TypeCast *type_cast)
3243
3589
  {
3244
3590
  need_parens = true;
3245
3591
  }
3592
+
3593
+ if (list_length(type_cast->typeName->names) == 1 &&
3594
+ strcmp(strVal(linitial(type_cast->typeName->names)), "point") == 0 &&
3595
+ a_const->location > type_cast->typeName->location)
3596
+ {
3597
+ appendStringInfoString(str, " point ");
3598
+ deparseAConst(str, a_const);
3599
+ return;
3600
+ }
3246
3601
  }
3247
3602
 
3603
+
3248
3604
  if (need_parens)
3249
3605
  appendStringInfoChar(str, '(');
3250
3606
  deparseExpr(str, type_cast->arg);
@@ -3602,7 +3958,7 @@ static void deparseColumnDef(StringInfo str, ColumnDef *column_def)
3602
3958
 
3603
3959
  if (column_def->colname != NULL)
3604
3960
  {
3605
- appendStringInfoString(str, column_def->colname);
3961
+ appendStringInfoString(str, quote_identifier(column_def->colname));
3606
3962
  appendStringInfoChar(str, ' ');
3607
3963
  }
3608
3964
 
@@ -3639,6 +3995,22 @@ static void deparseColumnDef(StringInfo str, ColumnDef *column_def)
3639
3995
  removeTrailingSpace(str);
3640
3996
  }
3641
3997
 
3998
+ static void deparseInsertOverride(StringInfo str, OverridingKind override)
3999
+ {
4000
+ switch (override)
4001
+ {
4002
+ case OVERRIDING_NOT_SET:
4003
+ // Do nothing
4004
+ break;
4005
+ case OVERRIDING_USER_VALUE:
4006
+ appendStringInfoString(str, "OVERRIDING USER VALUE ");
4007
+ break;
4008
+ case OVERRIDING_SYSTEM_VALUE:
4009
+ appendStringInfoString(str, "OVERRIDING SYSTEM VALUE ");
4010
+ break;
4011
+ }
4012
+ }
4013
+
3642
4014
  static void deparseInsertStmt(StringInfo str, InsertStmt *insert_stmt)
3643
4015
  {
3644
4016
  ListCell *lc;
@@ -3661,18 +4033,7 @@ static void deparseInsertStmt(StringInfo str, InsertStmt *insert_stmt)
3661
4033
  appendStringInfoString(str, ") ");
3662
4034
  }
3663
4035
 
3664
- switch (insert_stmt->override)
3665
- {
3666
- case OVERRIDING_NOT_SET:
3667
- // Do nothing
3668
- break;
3669
- case OVERRIDING_USER_VALUE:
3670
- appendStringInfoString(str, "OVERRIDING USER VALUE ");
3671
- break;
3672
- case OVERRIDING_SYSTEM_VALUE:
3673
- appendStringInfoString(str, "OVERRIDING SYSTEM VALUE ");
3674
- break;
3675
- }
4036
+ deparseInsertOverride(str, insert_stmt->override);
3676
4037
 
3677
4038
  if (insert_stmt->selectStmt != NULL)
3678
4039
  {
@@ -3799,6 +4160,90 @@ static void deparseUpdateStmt(StringInfo str, UpdateStmt *update_stmt)
3799
4160
  removeTrailingSpace(str);
3800
4161
  }
3801
4162
 
4163
+ static void deparseMergeStmt(StringInfo str, MergeStmt *merge_stmt)
4164
+ {
4165
+ if (merge_stmt->withClause != NULL)
4166
+ {
4167
+ deparseWithClause(str, merge_stmt->withClause);
4168
+ appendStringInfoChar(str, ' ');
4169
+ }
4170
+
4171
+ appendStringInfoString(str, "MERGE INTO ");
4172
+ deparseRangeVar(str, merge_stmt->relation, DEPARSE_NODE_CONTEXT_NONE);
4173
+ appendStringInfoChar(str, ' ');
4174
+
4175
+ appendStringInfoString(str, "USING ");
4176
+ deparseTableRef(str, merge_stmt->sourceRelation);
4177
+ appendStringInfoChar(str, ' ');
4178
+
4179
+ appendStringInfoString(str, "ON ");
4180
+ deparseExpr(str, merge_stmt->joinCondition);
4181
+ appendStringInfoChar(str, ' ');
4182
+
4183
+ ListCell *lc, *lc2;
4184
+ foreach (lc, merge_stmt->mergeWhenClauses)
4185
+ {
4186
+ MergeWhenClause *clause = castNode(MergeWhenClause, lfirst(lc));
4187
+
4188
+ appendStringInfoString(str, "WHEN ");
4189
+
4190
+ if (!clause->matched)
4191
+ {
4192
+ appendStringInfoString(str, "NOT ");
4193
+ }
4194
+
4195
+ appendStringInfoString(str, "MATCHED ");
4196
+
4197
+ if (clause->condition)
4198
+ {
4199
+ appendStringInfoString(str, "AND ");
4200
+ deparseExpr(str, clause->condition);
4201
+ appendStringInfoChar(str, ' ');
4202
+ }
4203
+
4204
+ appendStringInfoString(str, "THEN ");
4205
+
4206
+ switch (clause->commandType) {
4207
+ case CMD_INSERT:
4208
+ appendStringInfoString(str, "INSERT ");
4209
+
4210
+ if (clause->targetList) {
4211
+ appendStringInfoChar(str, '(');
4212
+ deparseInsertColumnList(str, clause->targetList);
4213
+ appendStringInfoString(str, ") ");
4214
+ }
4215
+
4216
+ deparseInsertOverride(str, clause->override);
4217
+
4218
+ if (clause->values) {
4219
+ appendStringInfoString(str, "VALUES (");
4220
+ deparseExprList(str, clause->values);
4221
+ appendStringInfoString(str, ")");
4222
+ } else {
4223
+ appendStringInfoString(str, "DEFAULT VALUES ");
4224
+ }
4225
+
4226
+ break;
4227
+ case CMD_UPDATE:
4228
+ appendStringInfoString(str, "UPDATE SET ");
4229
+ deparseSetClauseList(str, clause->targetList);
4230
+ break;
4231
+ case CMD_DELETE:
4232
+ appendStringInfoString(str, "DELETE");
4233
+ break;
4234
+ case CMD_NOTHING:
4235
+ appendStringInfoString(str, "DO NOTHING");
4236
+ break;
4237
+ default:
4238
+ elog(ERROR, "deparse: unpermitted command type in merge statement: %d", clause->commandType);
4239
+ break;
4240
+ }
4241
+
4242
+ if (lfirst(lc) != llast(merge_stmt->mergeWhenClauses))
4243
+ appendStringInfoChar(str, ' ');
4244
+ }
4245
+ }
4246
+
3802
4247
  static void deparseDeleteStmt(StringInfo str, DeleteStmt *delete_stmt)
3803
4248
  {
3804
4249
  if (delete_stmt->withClause != NULL)
@@ -3914,6 +4359,10 @@ static void deparseCreateCastStmt(StringInfo str, CreateCastStmt *create_cast_st
3914
4359
  case COERCION_ASSIGNMENT:
3915
4360
  appendStringInfoString(str, "AS ASSIGNMENT");
3916
4361
  break;
4362
+ case COERCION_PLPGSQL:
4363
+ // Not present in raw parser output
4364
+ Assert(false);
4365
+ break;
3917
4366
  case COERCION_EXPLICIT:
3918
4367
  // Default
3919
4368
  break;
@@ -4294,10 +4743,24 @@ static void deparseConstraint(StringInfo str, Constraint *constraint)
4294
4743
  appendStringInfoString(str, "ON DELETE CASCADE ");
4295
4744
  break;
4296
4745
  case FKCONSTR_ACTION_SETNULL:
4297
- appendStringInfoString(str, "ON DELETE SET NULL ");
4298
- break;
4299
4746
  case FKCONSTR_ACTION_SETDEFAULT:
4300
- appendStringInfoString(str, "ON DELETE SET DEFAULT ");
4747
+ appendStringInfoString(str, "ON DELETE SET ");
4748
+
4749
+ switch (constraint->fk_del_action) {
4750
+ case FKCONSTR_ACTION_SETDEFAULT: appendStringInfoString(str, "DEFAULT "); break;
4751
+ case FKCONSTR_ACTION_SETNULL: appendStringInfoString(str, "NULL "); break;
4752
+ }
4753
+
4754
+ if (constraint->fk_del_set_cols) {
4755
+ appendStringInfoString(str, "(");
4756
+ ListCell *lc;
4757
+ foreach (lc, constraint->fk_del_set_cols) {
4758
+ appendStringInfoString(str, strVal(lfirst(lc)));
4759
+ if (lfirst(lc) != llast(constraint->fk_del_set_cols))
4760
+ appendStringInfoString(str, ", ");
4761
+ }
4762
+ appendStringInfoString(str, ")");
4763
+ }
4301
4764
  break;
4302
4765
  default:
4303
4766
  // Not specified
@@ -4332,6 +4795,12 @@ static void deparseConstraint(StringInfo str, Constraint *constraint)
4332
4795
  removeTrailingSpace(str);
4333
4796
  }
4334
4797
 
4798
+ static void deparseReturnStmt(StringInfo str, ReturnStmt *return_stmt)
4799
+ {
4800
+ appendStringInfoString(str, "RETURN ");
4801
+ deparseExpr(str, return_stmt->returnval);
4802
+ }
4803
+
4335
4804
  static void deparseCreateFunctionStmt(StringInfo str, CreateFunctionStmt *create_function_stmt)
4336
4805
  {
4337
4806
  ListCell *lc;
@@ -4392,6 +4861,20 @@ static void deparseCreateFunctionStmt(StringInfo str, CreateFunctionStmt *create
4392
4861
  appendStringInfoChar(str, ' ');
4393
4862
  }
4394
4863
 
4864
+ if (create_function_stmt->sql_body)
4865
+ {
4866
+ /* RETURN or BEGIN ... END
4867
+ */
4868
+ if (IsA(create_function_stmt->sql_body, ReturnStmt))
4869
+ deparseReturnStmt(str, castNode(ReturnStmt, create_function_stmt->sql_body));
4870
+ else
4871
+ {
4872
+ appendStringInfoString(str, "BEGIN ATOMIC ");
4873
+ deparseExprList(str, castNode(List, create_function_stmt->sql_body));
4874
+ appendStringInfoString(str, "END ");
4875
+ }
4876
+ }
4877
+
4395
4878
  removeTrailingSpace(str);
4396
4879
  }
4397
4880
 
@@ -4400,7 +4883,7 @@ static void deparseFunctionParameter(StringInfo str, FunctionParameter *function
4400
4883
  switch (function_parameter->mode)
4401
4884
  {
4402
4885
  case FUNC_PARAM_IN: /* input only */
4403
- // Default
4886
+ appendStringInfoString(str, "IN ");
4404
4887
  break;
4405
4888
  case FUNC_PARAM_OUT: /* output only */
4406
4889
  appendStringInfoString(str, "OUT ");
@@ -4415,6 +4898,9 @@ static void deparseFunctionParameter(StringInfo str, FunctionParameter *function
4415
4898
  // No special annotation, the caller is expected to correctly put
4416
4899
  // this into the RETURNS part of the CREATE FUNCTION statement
4417
4900
  break;
4901
+ case FUNC_PARAM_DEFAULT:
4902
+ // Default
4903
+ break;
4418
4904
  default:
4419
4905
  Assert(false);
4420
4906
  break;
@@ -4446,7 +4932,6 @@ static void deparseCheckPointStmt(StringInfo str, CheckPointStmt *check_point_st
4446
4932
  static void deparseCreateSchemaStmt(StringInfo str, CreateSchemaStmt *create_schema_stmt)
4447
4933
  {
4448
4934
  ListCell *lc;
4449
-
4450
4935
  appendStringInfoString(str, "CREATE SCHEMA ");
4451
4936
 
4452
4937
  if (create_schema_stmt->if_not_exists)
@@ -4465,11 +4950,14 @@ static void deparseCreateSchemaStmt(StringInfo str, CreateSchemaStmt *create_sch
4465
4950
  appendStringInfoChar(str, ' ');
4466
4951
  }
4467
4952
 
4468
- foreach(lc, create_schema_stmt->schemaElts)
4953
+ if (create_schema_stmt->schemaElts)
4469
4954
  {
4470
- deparseSchemaStmt(str, lfirst(lc));
4471
- if (lnext(create_schema_stmt->schemaElts, lc))
4472
- appendStringInfoChar(str, ' ');
4955
+ foreach(lc, create_schema_stmt->schemaElts)
4956
+ {
4957
+ deparseSchemaStmt(str, lfirst(lc));
4958
+ if (lnext(create_schema_stmt->schemaElts, lc))
4959
+ appendStringInfoChar(str, ' ');
4960
+ }
4473
4961
  }
4474
4962
 
4475
4963
  removeTrailingSpace(str);
@@ -4523,6 +5011,9 @@ static void deparseRoleSpec(StringInfo str, RoleSpec *role_spec)
4523
5011
  Assert(role_spec->rolename != NULL);
4524
5012
  appendStringInfoString(str, quote_identifier(role_spec->rolename));
4525
5013
  break;
5014
+ case ROLESPEC_CURRENT_ROLE:
5015
+ appendStringInfoString(str, "CURRENT_ROLE");
5016
+ break;
4526
5017
  case ROLESPEC_CURRENT_USER:
4527
5018
  appendStringInfoString(str, "CURRENT_USER");
4528
5019
  break;
@@ -4619,6 +5110,8 @@ static void deparsePartitionCmd(StringInfo str, PartitionCmd *partition_cmd)
4619
5110
  appendStringInfoChar(str, ' ');
4620
5111
  deparsePartitionBoundSpec(str, partition_cmd->bound);
4621
5112
  }
5113
+ if (partition_cmd->concurrent)
5114
+ appendStringInfoString(str, " CONCURRENTLY ");
4622
5115
  }
4623
5116
 
4624
5117
  // "TableElement" in gram.y
@@ -4983,7 +5476,7 @@ static void deparseSecLabelStmt(StringInfo str, SecLabelStmt *sec_label_stmt)
4983
5476
  break;
4984
5477
  case OBJECT_LARGEOBJECT:
4985
5478
  appendStringInfoString(str, "LARGE OBJECT ");
4986
- deparseValue(str, (Value *) sec_label_stmt->object, DEPARSE_NODE_CONTEXT_CONSTANT);
5479
+ deparseValue(str, (union ValUnion *) sec_label_stmt->object, DEPARSE_NODE_CONTEXT_CONSTANT);
4987
5480
  break;
4988
5481
  case OBJECT_PROCEDURE:
4989
5482
  appendStringInfoString(str, "PROCEDURE ");
@@ -5067,7 +5560,7 @@ static void deparseCreateTableAsStmt(StringInfo str, CreateTableAsStmt *create_t
5067
5560
 
5068
5561
  deparseOptTemp(str, create_table_as_stmt->into->rel->relpersistence);
5069
5562
 
5070
- switch (create_table_as_stmt->relkind)
5563
+ switch (create_table_as_stmt->objtype)
5071
5564
  {
5072
5565
  case OBJECT_TABLE:
5073
5566
  appendStringInfoString(str, "TABLE ");
@@ -5340,7 +5833,7 @@ static void deparseDropStmt(StringInfo str, DropStmt *drop_stmt)
5340
5833
  appendStringInfoChar(str, ' ');
5341
5834
  break;
5342
5835
  case OBJECT_LANGUAGE:
5343
- deparseStringLiteral(str, strVal(linitial(drop_stmt->objects)));
5836
+ deparseNameList(str, drop_stmt->objects);
5344
5837
  appendStringInfoChar(str, ' ');
5345
5838
  break;
5346
5839
  case OBJECT_TYPE:
@@ -5471,8 +5964,7 @@ static void deparseAlterObjectDependsStmt(StringInfo str, AlterObjectDependsStmt
5471
5964
  if (alter_object_depends_stmt->remove)
5472
5965
  appendStringInfoString(str, "NO ");
5473
5966
 
5474
- appendStringInfoString(str, "DEPENDS ON EXTENSION ");
5475
- deparseColId(str, strVal(alter_object_depends_stmt->extname));
5967
+ appendStringInfo(str, "DEPENDS ON EXTENSION %s", alter_object_depends_stmt->extname->sval);
5476
5968
  }
5477
5969
 
5478
5970
  static void deparseAlterObjectSchemaStmt(StringInfo str, AlterObjectSchemaStmt *alter_object_schema_stmt)
@@ -5662,6 +6154,10 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5662
6154
  appendStringInfoString(str, "ALTER COLUMN ");
5663
6155
  options = "SET STORAGE";
5664
6156
  break;
6157
+ case AT_SetCompression: /* alter column set compression */
6158
+ appendStringInfoString(str, "ALTER COLUMN ");
6159
+ options = "SET COMPRESSION";
6160
+ break;
5665
6161
  case AT_DropColumn: /* drop column */
5666
6162
  if (context == DEPARSE_NODE_CONTEXT_ALTER_TYPE)
5667
6163
  appendStringInfoString(str, "DROP ATTRIBUTE ");
@@ -5709,6 +6205,7 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5709
6205
  Assert(false);
5710
6206
  break;
5711
6207
  case AT_ReAddComment: /* internal to commands/tablecmds.c */
6208
+ case AT_ReAddStatistics: /* internal to commands/tablecmds.c */
5712
6209
  Assert(false);
5713
6210
  break;
5714
6211
  case AT_AlterColumnType: /* alter column type */
@@ -5747,6 +6244,9 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5747
6244
  case AT_SetRelOptions: /* SET (...) -- AM specific parameters */
5748
6245
  appendStringInfoString(str, "SET ");
5749
6246
  break;
6247
+ case AT_SetAccessMethod:
6248
+ appendStringInfo(str, "SET ACCESS METHOD ");
6249
+ break;
5750
6250
  case AT_ResetRelOptions: /* RESET (...) -- AM specific parameters */
5751
6251
  appendStringInfoString(str, "RESET ");
5752
6252
  break;
@@ -5826,6 +6326,9 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5826
6326
  case AT_DetachPartition: /* DETACH PARTITION */
5827
6327
  appendStringInfoString(str, "DETACH PARTITION ");
5828
6328
  break;
6329
+ case AT_DetachPartitionFinalize: /* DETACH PARTITION FINALIZE */
6330
+ appendStringInfoString(str, "DETACH PARTITION ");
6331
+ break;
5829
6332
  case AT_AddIdentity: /* ADD IDENTITY */
5830
6333
  appendStringInfoString(str, "ALTER ");
5831
6334
  options = "ADD";
@@ -5874,6 +6377,10 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5874
6377
  deparsePartitionCmd(str, castNode(PartitionCmd, alter_table_cmd->def));
5875
6378
  appendStringInfoChar(str, ' ');
5876
6379
  break;
6380
+ case AT_DetachPartitionFinalize:
6381
+ deparsePartitionCmd(str, castNode(PartitionCmd, alter_table_cmd->def));
6382
+ appendStringInfoString(str, "FINALIZE ");
6383
+ break;
5877
6384
  case AT_AddColumn:
5878
6385
  case AT_AlterColumnType:
5879
6386
  deparseColumnDef(str, castNode(ColumnDef, alter_table_cmd->def));
@@ -5901,6 +6408,13 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5901
6408
  deparseColId(str, strVal(alter_table_cmd->def));
5902
6409
  appendStringInfoChar(str, ' ');
5903
6410
  break;
6411
+ case AT_SetCompression:
6412
+ if (strcmp(strVal(alter_table_cmd->def), "default") == 0)
6413
+ appendStringInfoString(str, "DEFAULT");
6414
+ else
6415
+ deparseColId(str, strVal(alter_table_cmd->def));
6416
+ appendStringInfoChar(str, ' ');
6417
+ break;
5904
6418
  case AT_AddIdentity:
5905
6419
  case AT_AddConstraint:
5906
6420
  case AT_AlterConstraint:
@@ -5939,14 +6453,9 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5939
6453
  removeTrailingSpace(str);
5940
6454
  }
5941
6455
 
5942
- static void deparseAlterTableStmt(StringInfo str, AlterTableStmt *alter_table_stmt)
6456
+ static DeparseNodeContext deparseAlterTableObjType(StringInfo str, ObjectType type)
5943
6457
  {
5944
- ListCell *lc;
5945
- DeparseNodeContext context = DEPARSE_NODE_CONTEXT_NONE;
5946
-
5947
- appendStringInfoString(str, "ALTER ");
5948
-
5949
- switch (alter_table_stmt->relkind)
6458
+ switch (type)
5950
6459
  {
5951
6460
  case OBJECT_TABLE:
5952
6461
  appendStringInfoString(str, "TABLE ");
@@ -5968,13 +6477,49 @@ static void deparseAlterTableStmt(StringInfo str, AlterTableStmt *alter_table_st
5968
6477
  break;
5969
6478
  case OBJECT_TYPE:
5970
6479
  appendStringInfoString(str, "TYPE ");
5971
- context = DEPARSE_NODE_CONTEXT_ALTER_TYPE;
6480
+ return DEPARSE_NODE_CONTEXT_ALTER_TYPE;
5972
6481
  break;
5973
6482
  default:
5974
6483
  Assert(false);
5975
6484
  break;
5976
6485
  }
5977
6486
 
6487
+ return DEPARSE_NODE_CONTEXT_NONE;
6488
+ }
6489
+
6490
+ static void deparseAlterTableMoveAllStmt(StringInfo str, AlterTableMoveAllStmt *move_all_stmt)
6491
+ {
6492
+ appendStringInfoString(str, "ALTER ");
6493
+ deparseAlterTableObjType(str, move_all_stmt->objtype);
6494
+
6495
+ appendStringInfoString(str, "ALL IN TABLESPACE ");
6496
+ appendStringInfoString(str, move_all_stmt->orig_tablespacename);
6497
+ appendStringInfoChar(str, ' ');
6498
+
6499
+ if (move_all_stmt->roles)
6500
+ {
6501
+ appendStringInfoString(str, "OWNED BY ");
6502
+ deparseRoleList(str, move_all_stmt->roles);
6503
+ appendStringInfoChar(str, ' ');
6504
+ }
6505
+
6506
+ appendStringInfoString(str, "SET TABLESPACE ");
6507
+ appendStringInfoString(str, move_all_stmt->new_tablespacename);
6508
+ appendStringInfoChar(str, ' ');
6509
+
6510
+ if (move_all_stmt->nowait)
6511
+ {
6512
+ appendStringInfoString(str, "NOWAIT");
6513
+ }
6514
+ }
6515
+
6516
+ static void deparseAlterTableStmt(StringInfo str, AlterTableStmt *alter_table_stmt)
6517
+ {
6518
+ ListCell *lc;
6519
+
6520
+ appendStringInfoString(str, "ALTER ");
6521
+ DeparseNodeContext context = deparseAlterTableObjType(str, alter_table_stmt->objtype);
6522
+
5978
6523
  if (alter_table_stmt->missing_ok)
5979
6524
  appendStringInfoString(str, "IF EXISTS ");
5980
6525
 
@@ -6458,28 +7003,7 @@ static void deparseVacuumStmt(StringInfo str, VacuumStmt *vacuum_stmt)
6458
7003
  else
6459
7004
  appendStringInfoString(str, "ANALYZE ");
6460
7005
 
6461
- if (list_length(vacuum_stmt->options) > 0)
6462
- {
6463
- appendStringInfoChar(str, '(');
6464
- foreach(lc, vacuum_stmt->options)
6465
- {
6466
- DefElem *def_elem = castNode(DefElem, lfirst(lc));
6467
- deparseGenericDefElemName(str, def_elem->defname);
6468
- if (def_elem->arg != NULL)
6469
- {
6470
- appendStringInfoChar(str, ' ');
6471
- if (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float))
6472
- deparseNumericOnly(str, (Value *) def_elem->arg);
6473
- else if (IsA(def_elem->arg, String))
6474
- deparseOptBooleanOrString(str, strVal(def_elem->arg));
6475
- else
6476
- Assert(false);
6477
- }
6478
- if (lnext(vacuum_stmt->options, lc))
6479
- appendStringInfoString(str, ", ");
6480
- }
6481
- appendStringInfoString(str, ") ");
6482
- }
7006
+ deparseUtilityOptionList(str, vacuum_stmt->options);
6483
7007
 
6484
7008
  foreach(lc, vacuum_stmt->rels)
6485
7009
  {
@@ -6590,31 +7114,7 @@ static void deparseExplainStmt(StringInfo str, ExplainStmt *explain_stmt)
6590
7114
 
6591
7115
  appendStringInfoString(str, "EXPLAIN ");
6592
7116
 
6593
- if (list_length(explain_stmt->options) > 0)
6594
- {
6595
- appendStringInfoChar(str, '(');
6596
-
6597
- foreach(lc, explain_stmt->options)
6598
- {
6599
- DefElem *def_elem = castNode(DefElem, lfirst(lc));
6600
- deparseGenericDefElemName(str, def_elem->defname);
6601
-
6602
- if (def_elem->arg != NULL && IsA(def_elem->arg, String))
6603
- {
6604
- appendStringInfoChar(str, ' ');
6605
- deparseOptBooleanOrString(str, strVal(def_elem->arg));
6606
- }
6607
- else if (def_elem->arg != NULL && (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float)))
6608
- {
6609
- appendStringInfoChar(str, ' ');
6610
- deparseNumericOnly(str, (Value *) def_elem->arg);
6611
- }
6612
-
6613
- if (lnext(explain_stmt->options, lc))
6614
- appendStringInfoString(str, ", ");
6615
- }
6616
- appendStringInfoString(str, ") ");
6617
- }
7117
+ deparseUtilityOptionList(str, explain_stmt->options);
6618
7118
 
6619
7119
  deparseExplainableStmt(str, explain_stmt->query);
6620
7120
  }
@@ -6668,130 +7168,194 @@ static void deparseCopyStmt(StringInfo str, CopyStmt *copy_stmt)
6668
7168
 
6669
7169
  if (list_length(copy_stmt->options) > 0)
6670
7170
  {
6671
- appendStringInfoString(str, "WITH (");
7171
+ // In some cases, equivalent expressions may have slightly different parse trees for `COPY`
7172
+ // statements. For example the following two statements result in different (but equivalent) parse
7173
+ // trees:
7174
+ //
7175
+ // - COPY foo FROM STDIN CSV FREEZE
7176
+ // - COPY foo FROM STDIN WITH (FORMAT CSV, FREEZE)
7177
+ //
7178
+ // In order to make sure we deparse to the "correct" version, we always try to deparse to the older
7179
+ // compact syntax first.
7180
+ //
7181
+ // The old syntax can be seen here in the Postgres 8.4 Reference:
7182
+ // https://www.postgresql.org/docs/8.4/sql-copy.html
7183
+
7184
+ bool old_fmt = true;
7185
+
7186
+ // Loop over the options to see if any require the new `WITH (...)` syntax.
6672
7187
  foreach(lc, copy_stmt->options)
6673
7188
  {
6674
7189
  DefElem *def_elem = castNode(DefElem, lfirst(lc));
6675
7190
 
6676
- if (strcmp(def_elem->defname, "format") == 0)
6677
- {
6678
- appendStringInfoString(str, "FORMAT ");
6679
-
6680
- char *format = strVal(def_elem->arg);
6681
- if (strcmp(format, "binary") == 0)
6682
- appendStringInfoString(str, "BINARY");
6683
- else if (strcmp(format, "csv") == 0)
6684
- appendStringInfoString(str, "CSV");
6685
- else
6686
- Assert(false);
6687
- }
6688
- else if (strcmp(def_elem->defname, "freeze") == 0 && (def_elem->arg == NULL || intVal(def_elem->arg) == 1))
6689
- {
6690
- appendStringInfoString(str, "FREEZE");
6691
- if (def_elem->arg != NULL && intVal(def_elem->arg) == 1)
6692
- appendStringInfoString(str, " 1");
6693
- }
6694
- else if (strcmp(def_elem->defname, "delimiter") == 0)
6695
- {
6696
- appendStringInfoString(str, "DELIMITER ");
6697
- deparseStringLiteral(str, strVal(def_elem->arg));
6698
- }
6699
- else if (strcmp(def_elem->defname, "null") == 0)
6700
- {
6701
- appendStringInfoString(str, "NULL ");
6702
- deparseStringLiteral(str, strVal(def_elem->arg));
6703
- }
6704
- else if (strcmp(def_elem->defname, "header") == 0 && (def_elem->arg == NULL || intVal(def_elem->arg) == 1))
6705
- {
6706
- appendStringInfoString(str, "HEADER");
6707
- if (def_elem->arg != NULL && intVal(def_elem->arg) == 1)
6708
- appendStringInfoString(str, " 1");
6709
- }
6710
- else if (strcmp(def_elem->defname, "quote") == 0)
6711
- {
6712
- appendStringInfoString(str, "QUOTE ");
6713
- deparseStringLiteral(str, strVal(def_elem->arg));
6714
- }
6715
- else if (strcmp(def_elem->defname, "escape") == 0)
7191
+ if (strcmp(def_elem->defname, "freeze") == 0 && optBooleanValue(def_elem->arg))
7192
+ {}
7193
+ else if (strcmp(def_elem->defname, "header") == 0 && def_elem->arg && optBooleanValue(def_elem->arg))
7194
+ {}
7195
+ else if (strcmp(def_elem->defname, "format") == 0 && strcmp(strVal(def_elem->arg), "csv") == 0)
7196
+ {}
7197
+ else if (strcmp(def_elem->defname, "force_quote") == 0 && def_elem->arg && nodeTag(def_elem->arg) == T_List)
7198
+ {}
7199
+ else
6716
7200
  {
6717
- appendStringInfoString(str, "ESCAPE ");
6718
- deparseStringLiteral(str, strVal(def_elem->arg));
7201
+ old_fmt = false;
7202
+ break;
6719
7203
  }
6720
- else if (strcmp(def_elem->defname, "force_quote") == 0)
7204
+ }
7205
+
7206
+ // Branch to differing output modes, depending on if we can use the old syntax.
7207
+ if (old_fmt) {
7208
+ foreach(lc, copy_stmt->options)
6721
7209
  {
6722
- appendStringInfoString(str, "FORCE_QUOTE ");
6723
- if (IsA(def_elem->arg, A_Star))
7210
+ DefElem *def_elem = castNode(DefElem, lfirst(lc));
7211
+
7212
+ if (strcmp(def_elem->defname, "freeze") == 0 && optBooleanValue(def_elem->arg))
6724
7213
  {
6725
- appendStringInfoChar(str, '*');
7214
+ appendStringInfoString(str, "FREEZE ");
6726
7215
  }
6727
- else if (IsA(def_elem->arg, List))
7216
+ else if (strcmp(def_elem->defname, "header") == 0 && def_elem->arg && optBooleanValue(def_elem->arg))
6728
7217
  {
6729
- appendStringInfoChar(str, '(');
7218
+ appendStringInfoString(str, "HEADER ");
7219
+ }
7220
+ else if (strcmp(def_elem->defname, "format") == 0 && strcmp(strVal(def_elem->arg), "csv") == 0)
7221
+ {
7222
+ appendStringInfoString(str, "CSV ");
7223
+ }
7224
+ else if (strcmp(def_elem->defname, "force_quote") == 0 && def_elem->arg && nodeTag(def_elem->arg) == T_List)
7225
+ {
7226
+ appendStringInfoString(str, "FORCE QUOTE ");
6730
7227
  deparseColumnList(str, castNode(List, def_elem->arg));
6731
- appendStringInfoChar(str, ')');
6732
7228
  }
6733
7229
  else
6734
7230
  {
7231
+ // This isn't reachable, the conditions here are exactly the same as the first loop above.
6735
7232
  Assert(false);
6736
7233
  }
6737
7234
  }
6738
- else if (strcmp(def_elem->defname, "force_not_null") == 0)
7235
+ } else {
7236
+ appendStringInfoString(str, "WITH (");
7237
+ foreach(lc, copy_stmt->options)
6739
7238
  {
6740
- appendStringInfoString(str, "FORCE_NOT_NULL (");
6741
- deparseColumnList(str, castNode(List, def_elem->arg));
6742
- appendStringInfoChar(str, ')');
6743
- }
6744
- else if (strcmp(def_elem->defname, "force_null") == 0)
6745
- {
6746
- appendStringInfoString(str, "FORCE_NULL (");
6747
- deparseColumnList(str, castNode(List, def_elem->arg));
6748
- appendStringInfoChar(str, ')');
6749
- }
6750
- else if (strcmp(def_elem->defname, "encoding") == 0)
6751
- {
6752
- appendStringInfoString(str, "ENCODING ");
6753
- deparseStringLiteral(str, strVal(def_elem->arg));
6754
- }
6755
- else
6756
- {
6757
- appendStringInfoString(str, quote_identifier(def_elem->defname));
6758
- if (def_elem->arg != NULL)
6759
- appendStringInfoChar(str, ' ');
6760
-
6761
- if (def_elem->arg == NULL)
7239
+ DefElem *def_elem = castNode(DefElem, lfirst(lc));
7240
+
7241
+ if (strcmp(def_elem->defname, "format") == 0)
6762
7242
  {
6763
- // Nothing
7243
+ appendStringInfoString(str, "FORMAT ");
7244
+
7245
+ char *format = strVal(def_elem->arg);
7246
+ if (strcmp(format, "binary") == 0)
7247
+ appendStringInfoString(str, "BINARY");
7248
+ else if (strcmp(format, "csv") == 0)
7249
+ appendStringInfoString(str, "CSV");
7250
+ else
7251
+ Assert(false);
6764
7252
  }
6765
- else if (IsA(def_elem->arg, String))
7253
+ else if (strcmp(def_elem->defname, "freeze") == 0)
6766
7254
  {
6767
- deparseOptBooleanOrString(str, strVal(def_elem->arg));
7255
+ appendStringInfoString(str, "FREEZE");
7256
+ deparseOptBoolean(str, def_elem->arg);
6768
7257
  }
6769
- else if (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float))
7258
+ else if (strcmp(def_elem->defname, "delimiter") == 0)
6770
7259
  {
6771
- deparseNumericOnly(str, (Value *) def_elem->arg);
7260
+ appendStringInfoString(str, "DELIMITER ");
7261
+ deparseStringLiteral(str, strVal(def_elem->arg));
6772
7262
  }
6773
- else if (IsA(def_elem->arg, A_Star))
7263
+ else if (strcmp(def_elem->defname, "null") == 0)
6774
7264
  {
6775
- deparseAStar(str, castNode(A_Star, def_elem->arg));
7265
+ appendStringInfoString(str, "NULL ");
7266
+ deparseStringLiteral(str, strVal(def_elem->arg));
6776
7267
  }
6777
- else if (IsA(def_elem->arg, List))
7268
+ else if (strcmp(def_elem->defname, "header") == 0)
6778
7269
  {
6779
- List *l = castNode(List, def_elem->arg);
6780
- appendStringInfoChar(str, '(');
6781
- foreach(lc2, l)
7270
+ appendStringInfoString(str, "HEADER");
7271
+ deparseOptBoolean(str, def_elem->arg);
7272
+ }
7273
+ else if (strcmp(def_elem->defname, "quote") == 0)
7274
+ {
7275
+ appendStringInfoString(str, "QUOTE ");
7276
+ deparseStringLiteral(str, strVal(def_elem->arg));
7277
+ }
7278
+ else if (strcmp(def_elem->defname, "escape") == 0)
7279
+ {
7280
+ appendStringInfoString(str, "ESCAPE ");
7281
+ deparseStringLiteral(str, strVal(def_elem->arg));
7282
+ }
7283
+ else if (strcmp(def_elem->defname, "force_quote") == 0)
7284
+ {
7285
+ appendStringInfoString(str, "FORCE_QUOTE ");
7286
+ if (IsA(def_elem->arg, A_Star))
7287
+ {
7288
+ appendStringInfoChar(str, '*');
7289
+ }
7290
+ else if (IsA(def_elem->arg, List))
7291
+ {
7292
+ appendStringInfoChar(str, '(');
7293
+ deparseColumnList(str, castNode(List, def_elem->arg));
7294
+ appendStringInfoChar(str, ')');
7295
+ }
7296
+ else
6782
7297
  {
6783
- deparseOptBooleanOrString(str, strVal(lfirst(lc2)));
6784
- if (lnext(l, lc2))
6785
- appendStringInfoString(str, ", ");
7298
+ Assert(false);
6786
7299
  }
7300
+ }
7301
+ else if (strcmp(def_elem->defname, "force_not_null") == 0)
7302
+ {
7303
+ appendStringInfoString(str, "FORCE_NOT_NULL (");
7304
+ deparseColumnList(str, castNode(List, def_elem->arg));
6787
7305
  appendStringInfoChar(str, ')');
6788
7306
  }
6789
- }
7307
+ else if (strcmp(def_elem->defname, "force_null") == 0)
7308
+ {
7309
+ appendStringInfoString(str, "FORCE_NULL (");
7310
+ deparseColumnList(str, castNode(List, def_elem->arg));
7311
+ appendStringInfoChar(str, ')');
7312
+ }
7313
+ else if (strcmp(def_elem->defname, "encoding") == 0)
7314
+ {
7315
+ appendStringInfoString(str, "ENCODING ");
7316
+ deparseStringLiteral(str, strVal(def_elem->arg));
7317
+ }
7318
+ else
7319
+ {
7320
+ appendStringInfoString(str, quote_identifier(def_elem->defname));
7321
+ if (def_elem->arg != NULL)
7322
+ appendStringInfoChar(str, ' ');
7323
+
7324
+ if (def_elem->arg == NULL)
7325
+ {
7326
+ // Nothing
7327
+ }
7328
+ else if (IsA(def_elem->arg, String))
7329
+ {
7330
+ deparseOptBooleanOrString(str, strVal(def_elem->arg));
7331
+ }
7332
+ else if (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float))
7333
+ {
7334
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
7335
+ }
7336
+ else if (IsA(def_elem->arg, A_Star))
7337
+ {
7338
+ deparseAStar(str, castNode(A_Star, def_elem->arg));
7339
+ }
7340
+ else if (IsA(def_elem->arg, List))
7341
+ {
7342
+ List *l = castNode(List, def_elem->arg);
7343
+ appendStringInfoChar(str, '(');
7344
+ foreach(lc2, l)
7345
+ {
7346
+ deparseOptBooleanOrString(str, strVal(lfirst(lc2)));
7347
+ if (lnext(l, lc2))
7348
+ appendStringInfoString(str, ", ");
7349
+ }
7350
+ appendStringInfoChar(str, ')');
7351
+ }
7352
+ }
6790
7353
 
6791
- if (lnext(copy_stmt->options, lc))
6792
- appendStringInfoString(str, ", ");
7354
+ if (lnext(copy_stmt->options, lc))
7355
+ appendStringInfoString(str, ", ");
7356
+ }
7357
+ appendStringInfoString(str, ") ");
6793
7358
  }
6794
- appendStringInfoString(str, ") ");
6795
7359
  }
6796
7360
 
6797
7361
  deparseWhereClause(str, copy_stmt->whereClause);
@@ -7248,7 +7812,6 @@ static void deparseAccessPriv(StringInfo str, AccessPriv *access_priv)
7248
7812
  static void deparseGrantStmt(StringInfo str, GrantStmt *grant_stmt)
7249
7813
  {
7250
7814
  ListCell *lc;
7251
-
7252
7815
  if (grant_stmt->is_grant)
7253
7816
  appendStringInfoString(str, "GRANT ");
7254
7817
  else
@@ -7295,6 +7858,12 @@ static void deparseGrantStmt(StringInfo str, GrantStmt *grant_stmt)
7295
7858
 
7296
7859
  deparseOptDropBehavior(str, grant_stmt->behavior);
7297
7860
 
7861
+ if (grant_stmt->grantor)
7862
+ {
7863
+ appendStringInfoString(str, "GRANTED BY ");
7864
+ deparseRoleSpec(str, castNode(RoleSpec, grant_stmt->grantor));
7865
+ }
7866
+
7298
7867
  removeTrailingSpace(str);
7299
7868
  }
7300
7869
 
@@ -7307,6 +7876,9 @@ static void deparseGrantRoleStmt(StringInfo str, GrantRoleStmt *grant_role_stmt)
7307
7876
  else
7308
7877
  appendStringInfoString(str, "REVOKE ");
7309
7878
 
7879
+ if (!grant_role_stmt->is_grant && grant_role_stmt->admin_opt)
7880
+ appendStringInfoString(str, "ADMIN OPTION FOR ");
7881
+
7310
7882
  foreach(lc, grant_role_stmt->granted_roles)
7311
7883
  {
7312
7884
  deparseAccessPriv(str, castNode(AccessPriv, lfirst(lc)));
@@ -7323,9 +7895,15 @@ static void deparseGrantRoleStmt(StringInfo str, GrantRoleStmt *grant_role_stmt)
7323
7895
  deparseRoleList(str, grant_role_stmt->grantee_roles);
7324
7896
  appendStringInfoChar(str, ' ');
7325
7897
 
7326
- if (grant_role_stmt->admin_opt)
7898
+ if (grant_role_stmt->is_grant && grant_role_stmt->admin_opt)
7327
7899
  appendStringInfoString(str, "WITH ADMIN OPTION ");
7328
7900
 
7901
+ if (grant_role_stmt->grantor)
7902
+ {
7903
+ appendStringInfoString(str, "GRANTED BY ");
7904
+ deparseRoleSpec(str, castNode(RoleSpec, grant_role_stmt->grantor));
7905
+ }
7906
+
7329
7907
  removeTrailingSpace(str);
7330
7908
  }
7331
7909
 
@@ -7396,6 +7974,11 @@ static void deparseIndexStmt(StringInfo str, IndexStmt *index_stmt)
7396
7974
  appendStringInfoString(str, ") ");
7397
7975
  }
7398
7976
 
7977
+ if (index_stmt->nulls_not_distinct)
7978
+ {
7979
+ appendStringInfoString(str, "NULLS NOT DISTINCT ");
7980
+ }
7981
+
7399
7982
  deparseOptWith(str, index_stmt->options);
7400
7983
 
7401
7984
  if (index_stmt->tableSpace != NULL)
@@ -7499,59 +8082,59 @@ static void deparseAlterRoleElem(StringInfo str, DefElem *def_elem)
7499
8082
  appendStringInfoString(str, "VALID UNTIL ");
7500
8083
  deparseStringLiteral(str, strVal(def_elem->arg));
7501
8084
  }
7502
- else if (strcmp(def_elem->defname, "superuser") == 0 && intVal(def_elem->arg) == 1)
8085
+ else if (strcmp(def_elem->defname, "superuser") == 0 && boolVal(def_elem->arg))
7503
8086
  {
7504
8087
  appendStringInfoString(str, "SUPERUSER");
7505
8088
  }
7506
- else if (strcmp(def_elem->defname, "superuser") == 0 && intVal(def_elem->arg) == 0)
8089
+ else if (strcmp(def_elem->defname, "superuser") == 0 && !boolVal(def_elem->arg))
7507
8090
  {
7508
8091
  appendStringInfoString(str, "NOSUPERUSER");
7509
8092
  }
7510
- else if (strcmp(def_elem->defname, "createrole") == 0 && intVal(def_elem->arg) == 1)
8093
+ else if (strcmp(def_elem->defname, "createrole") == 0 && boolVal(def_elem->arg))
7511
8094
  {
7512
8095
  appendStringInfoString(str, "CREATEROLE");
7513
8096
  }
7514
- else if (strcmp(def_elem->defname, "createrole") == 0 && intVal(def_elem->arg) == 0)
8097
+ else if (strcmp(def_elem->defname, "createrole") == 0 && !boolVal(def_elem->arg))
7515
8098
  {
7516
8099
  appendStringInfoString(str, "NOCREATEROLE");
7517
8100
  }
7518
- else if (strcmp(def_elem->defname, "isreplication") == 0 && intVal(def_elem->arg) == 1)
8101
+ else if (strcmp(def_elem->defname, "isreplication") == 0 && boolVal(def_elem->arg))
7519
8102
  {
7520
8103
  appendStringInfoString(str, "REPLICATION");
7521
8104
  }
7522
- else if (strcmp(def_elem->defname, "isreplication") == 0 && intVal(def_elem->arg) == 0)
8105
+ else if (strcmp(def_elem->defname, "isreplication") == 0 && !boolVal(def_elem->arg))
7523
8106
  {
7524
8107
  appendStringInfoString(str, "NOREPLICATION");
7525
8108
  }
7526
- else if (strcmp(def_elem->defname, "createdb") == 0 && intVal(def_elem->arg) == 1)
8109
+ else if (strcmp(def_elem->defname, "createdb") == 0 && boolVal(def_elem->arg))
7527
8110
  {
7528
8111
  appendStringInfoString(str, "CREATEDB");
7529
8112
  }
7530
- else if (strcmp(def_elem->defname, "createdb") == 0 && intVal(def_elem->arg) == 0)
8113
+ else if (strcmp(def_elem->defname, "createdb") == 0 && !boolVal(def_elem->arg))
7531
8114
  {
7532
8115
  appendStringInfoString(str, "NOCREATEDB");
7533
8116
  }
7534
- else if (strcmp(def_elem->defname, "canlogin") == 0 && intVal(def_elem->arg) == 1)
8117
+ else if (strcmp(def_elem->defname, "canlogin") == 0 && boolVal(def_elem->arg))
7535
8118
  {
7536
8119
  appendStringInfoString(str, "LOGIN");
7537
8120
  }
7538
- else if (strcmp(def_elem->defname, "canlogin") == 0 && intVal(def_elem->arg) == 0)
8121
+ else if (strcmp(def_elem->defname, "canlogin") == 0 && !boolVal(def_elem->arg))
7539
8122
  {
7540
8123
  appendStringInfoString(str, "NOLOGIN");
7541
8124
  }
7542
- else if (strcmp(def_elem->defname, "bypassrls") == 0 && intVal(def_elem->arg) == 1)
8125
+ else if (strcmp(def_elem->defname, "bypassrls") == 0 && boolVal(def_elem->arg))
7543
8126
  {
7544
8127
  appendStringInfoString(str, "BYPASSRLS");
7545
8128
  }
7546
- else if (strcmp(def_elem->defname, "bypassrls") == 0 && intVal(def_elem->arg) == 0)
8129
+ else if (strcmp(def_elem->defname, "bypassrls") == 0 && !boolVal(def_elem->arg))
7547
8130
  {
7548
8131
  appendStringInfoString(str, "NOBYPASSRLS");
7549
8132
  }
7550
- else if (strcmp(def_elem->defname, "inherit") == 0 && intVal(def_elem->arg) == 1)
8133
+ else if (strcmp(def_elem->defname, "inherit") == 0 && boolVal(def_elem->arg))
7551
8134
  {
7552
8135
  appendStringInfoString(str, "INHERIT");
7553
8136
  }
7554
- else if (strcmp(def_elem->defname, "inherit") == 0 && intVal(def_elem->arg) == 0)
8137
+ else if (strcmp(def_elem->defname, "inherit") == 0 && !boolVal(def_elem->arg))
7555
8138
  {
7556
8139
  appendStringInfoString(str, "NOINHERIT");
7557
8140
  }
@@ -7824,8 +8407,7 @@ static void deparseReindexStmt(StringInfo str, ReindexStmt *reindex_stmt)
7824
8407
  {
7825
8408
  appendStringInfoString(str, "REINDEX ");
7826
8409
 
7827
- if (reindex_stmt->options & REINDEXOPT_VERBOSE)
7828
- appendStringInfoString(str, "(VERBOSE) ");
8410
+ deparseUtilityOptionList(str, reindex_stmt->params);
7829
8411
 
7830
8412
  switch (reindex_stmt->kind)
7831
8413
  {
@@ -7846,9 +8428,6 @@ static void deparseReindexStmt(StringInfo str, ReindexStmt *reindex_stmt)
7846
8428
  break;
7847
8429
  }
7848
8430
 
7849
- if (reindex_stmt->concurrent)
7850
- appendStringInfoString(str, "CONCURRENTLY ");
7851
-
7852
8431
  if (reindex_stmt->relation != NULL)
7853
8432
  {
7854
8433
  deparseRangeVar(str, reindex_stmt->relation, DEPARSE_NODE_CONTEXT_NONE);
@@ -7892,6 +8471,9 @@ static void deparseRuleStmt(StringInfo str, RuleStmt* rule_stmt)
7892
8471
  case CMD_DELETE:
7893
8472
  appendStringInfoString(str, "DELETE ");
7894
8473
  break;
8474
+ case CMD_MERGE:
8475
+ appendStringInfoString(str, "MERGE ");
8476
+ break;
7895
8477
  }
7896
8478
 
7897
8479
  appendStringInfoString(str, "TO ");
@@ -8214,7 +8796,12 @@ static void deparseCreateTableSpaceStmt(StringInfo str, CreateTableSpaceStmt *cr
8214
8796
  }
8215
8797
 
8216
8798
  appendStringInfoString(str, "LOCATION ");
8217
- deparseStringLiteral(str, create_table_space_stmt->location);
8799
+
8800
+ if (create_table_space_stmt->location != NULL)
8801
+ deparseStringLiteral(str, create_table_space_stmt->location);
8802
+ else
8803
+ appendStringInfoString(str, "''");
8804
+
8218
8805
  appendStringInfoChar(str, ' ');
8219
8806
 
8220
8807
  deparseOptWith(str, create_table_space_stmt->options);
@@ -8277,6 +8864,50 @@ static void deparseCreateAmStmt(StringInfo str, CreateAmStmt *create_am_stmt)
8277
8864
  deparseHandlerName(str, create_am_stmt->handler_name);
8278
8865
  }
8279
8866
 
8867
+ static void deparsePublicationObjectList(StringInfo str, List *pubobjects) {
8868
+ const ListCell *lc;
8869
+ foreach(lc, pubobjects) {
8870
+ PublicationObjSpec *obj = lfirst(lc);
8871
+
8872
+ switch (obj->pubobjtype) {
8873
+ case PUBLICATIONOBJ_TABLE:
8874
+ appendStringInfoString(str, "TABLE ");
8875
+ deparseRangeVar(str, obj->pubtable->relation, DEPARSE_NODE_CONTEXT_NONE);
8876
+
8877
+ if (obj->pubtable->columns)
8878
+ {
8879
+ appendStringInfoChar(str, '(');
8880
+ deparseColumnList(str, obj->pubtable->columns);
8881
+ appendStringInfoChar(str, ')');
8882
+ }
8883
+
8884
+ if (obj->pubtable->whereClause)
8885
+ {
8886
+ appendStringInfoString(str, " WHERE (");
8887
+ deparseExpr(str, obj->pubtable->whereClause);
8888
+ appendStringInfoString(str, ")");
8889
+ }
8890
+
8891
+ break;
8892
+ case PUBLICATIONOBJ_TABLES_IN_SCHEMA:
8893
+ appendStringInfoString(str, "TABLES IN SCHEMA ");
8894
+ appendStringInfoString(str, quote_identifier(obj->name));
8895
+ break;
8896
+ case PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA:
8897
+ appendStringInfoString(str, "TABLES IN SCHEMA CURRENT_SCHEMA");
8898
+ break;
8899
+ case PUBLICATIONOBJ_CONTINUATION:
8900
+ // This should be unreachable, the parser merges these before we can even get here.
8901
+ Assert(false);
8902
+ break;
8903
+ }
8904
+
8905
+ if (lnext(pubobjects, lc)) {
8906
+ appendStringInfoString(str, ", ");
8907
+ }
8908
+ }
8909
+ }
8910
+
8280
8911
  static void deparseCreatePublicationStmt(StringInfo str, CreatePublicationStmt *create_publication_stmt)
8281
8912
  {
8282
8913
  ListCell *lc = NULL;
@@ -8285,10 +8916,10 @@ static void deparseCreatePublicationStmt(StringInfo str, CreatePublicationStmt *
8285
8916
  appendStringInfoString(str, quote_identifier(create_publication_stmt->pubname));
8286
8917
  appendStringInfoChar(str, ' ');
8287
8918
 
8288
- if (list_length(create_publication_stmt->tables) > 0)
8919
+ if (list_length(create_publication_stmt->pubobjects) > 0)
8289
8920
  {
8290
- appendStringInfoString(str, "FOR TABLE ");
8291
- deparseRelationExprList(str, create_publication_stmt->tables);
8921
+ appendStringInfoString(str, "FOR ");
8922
+ deparsePublicationObjectList(str, create_publication_stmt->pubobjects);
8292
8923
  appendStringInfoChar(str, ' ');
8293
8924
  }
8294
8925
  else if (create_publication_stmt->for_all_tables)
@@ -8306,25 +8937,22 @@ static void deparseAlterPublicationStmt(StringInfo str, AlterPublicationStmt *al
8306
8937
  deparseColId(str, alter_publication_stmt->pubname);
8307
8938
  appendStringInfoChar(str, ' ');
8308
8939
 
8309
- if (list_length(alter_publication_stmt->tables) > 0)
8940
+ if (list_length(alter_publication_stmt->pubobjects) > 0)
8310
8941
  {
8311
- switch (alter_publication_stmt->tableAction)
8942
+ switch (alter_publication_stmt->action)
8312
8943
  {
8313
- case DEFELEM_SET:
8314
- appendStringInfoString(str, "SET TABLE ");
8315
- break;
8316
- case DEFELEM_ADD:
8317
- appendStringInfoString(str, "ADD TABLE ");
8944
+ case AP_SetObjects:
8945
+ appendStringInfoString(str, "SET ");
8318
8946
  break;
8319
- case DEFELEM_DROP:
8320
- appendStringInfoString(str, "DROP TABLE ");
8947
+ case AP_AddObjects:
8948
+ appendStringInfoString(str, "ADD ");
8321
8949
  break;
8322
- case DEFELEM_UNSPEC:
8323
- Assert(false);
8950
+ case AP_DropObjects:
8951
+ appendStringInfoString(str, "DROP ");
8324
8952
  break;
8325
8953
  }
8326
8954
 
8327
- deparseRelationExprList(str, alter_publication_stmt->tables);
8955
+ deparsePublicationObjectList(str, alter_publication_stmt->pubobjects);
8328
8956
  }
8329
8957
  else if (list_length(alter_publication_stmt->options) > 0)
8330
8958
  {
@@ -8581,7 +9209,7 @@ static void deparseCommentStmt(StringInfo str, CommentStmt *comment_stmt)
8581
9209
  appendStringInfoString(str, quote_identifier(strVal(linitial(l))));
8582
9210
  break;
8583
9211
  case OBJECT_LARGEOBJECT:
8584
- deparseValue(str, (Value *) comment_stmt->object, DEPARSE_NODE_CONTEXT_NONE);
9212
+ deparseValue(str, (union ValUnion *) comment_stmt->object, DEPARSE_NODE_CONTEXT_NONE);
8585
9213
  break;
8586
9214
  case OBJECT_CAST:
8587
9215
  l = castNode(List, comment_stmt->object);
@@ -8605,6 +9233,19 @@ static void deparseCommentStmt(StringInfo str, CommentStmt *comment_stmt)
8605
9233
  appendStringInfoString(str, "NULL");
8606
9234
  }
8607
9235
 
9236
+ static void deparseStatsElem(StringInfo str, StatsElem *stats_elem)
9237
+ {
9238
+ // only one of stats_elem->name or stats_elem->expr can be non-null
9239
+ if (stats_elem->name)
9240
+ appendStringInfoString(str, stats_elem->name);
9241
+ else if (stats_elem->expr)
9242
+ {
9243
+ appendStringInfoChar(str, '(');
9244
+ deparseExpr(str, stats_elem->expr);
9245
+ appendStringInfoChar(str, ')');
9246
+ }
9247
+ }
9248
+
8608
9249
  static void deparseCreateStatsStmt(StringInfo str, CreateStatsStmt *create_stats_stmt)
8609
9250
  {
8610
9251
  ListCell *lc;
@@ -8625,7 +9266,12 @@ static void deparseCreateStatsStmt(StringInfo str, CreateStatsStmt *create_stats
8625
9266
  }
8626
9267
 
8627
9268
  appendStringInfoString(str, "ON ");
8628
- deparseExprList(str, create_stats_stmt->exprs);
9269
+ foreach (lc, create_stats_stmt->exprs)
9270
+ {
9271
+ deparseStatsElem(str, lfirst(lc));
9272
+ if (lnext(create_stats_stmt->exprs, lc))
9273
+ appendStringInfoString(str, ", ");
9274
+ }
8629
9275
 
8630
9276
  appendStringInfoString(str, " FROM ");
8631
9277
  deparseFromList(str, create_stats_stmt->relations);
@@ -8737,7 +9383,7 @@ static void deparseVariableShowStmt(StringInfo str, VariableShowStmt *variable_s
8737
9383
  else if (strcmp(variable_show_stmt->name, "all") == 0)
8738
9384
  appendStringInfoString(str, "SESSION ALL");
8739
9385
  else
8740
- appendStringInfoString(str, variable_show_stmt->name);
9386
+ appendStringInfoString(str, quote_identifier(variable_show_stmt->name));
8741
9387
  }
8742
9388
 
8743
9389
  static void deparseRangeTableSample(StringInfo str, RangeTableSample *range_table_sample)
@@ -8802,6 +9448,10 @@ static void deparseAlterSubscriptionStmt(StringInfo str, AlterSubscriptionStmt *
8802
9448
  appendStringInfoString(str, "SET ");
8803
9449
  deparseDefinition(str, alter_subscription_stmt->options);
8804
9450
  break;
9451
+ case ALTER_SUBSCRIPTION_SKIP:
9452
+ appendStringInfoString(str, "SKIP ");
9453
+ deparseDefinition(str, alter_subscription_stmt->options);
9454
+ break;
8805
9455
  case ALTER_SUBSCRIPTION_CONNECTION:
8806
9456
  appendStringInfoString(str, "CONNECTION ");
8807
9457
  deparseStringLiteral(str, alter_subscription_stmt->conninfo);
@@ -8811,7 +9461,29 @@ static void deparseAlterSubscriptionStmt(StringInfo str, AlterSubscriptionStmt *
8811
9461
  appendStringInfoString(str, "REFRESH PUBLICATION ");
8812
9462
  deparseOptDefinition(str, alter_subscription_stmt->options);
8813
9463
  break;
8814
- case ALTER_SUBSCRIPTION_PUBLICATION:
9464
+ case ALTER_SUBSCRIPTION_ADD_PUBLICATION:
9465
+ appendStringInfoString(str, "ADD PUBLICATION ");
9466
+ foreach(lc, alter_subscription_stmt->publication)
9467
+ {
9468
+ deparseColLabel(str, strVal(lfirst(lc)));
9469
+ if (lnext(alter_subscription_stmt->publication, lc))
9470
+ appendStringInfoString(str, ", ");
9471
+ }
9472
+ appendStringInfoChar(str, ' ');
9473
+ deparseOptDefinition(str, alter_subscription_stmt->options);
9474
+ break;
9475
+ case ALTER_SUBSCRIPTION_DROP_PUBLICATION:
9476
+ appendStringInfoString(str, "DROP PUBLICATION ");
9477
+ foreach(lc, alter_subscription_stmt->publication)
9478
+ {
9479
+ deparseColLabel(str, strVal(lfirst(lc)));
9480
+ if (lnext(alter_subscription_stmt->publication, lc))
9481
+ appendStringInfoString(str, ", ");
9482
+ }
9483
+ appendStringInfoChar(str, ' ');
9484
+ deparseOptDefinition(str, alter_subscription_stmt->options);
9485
+ break;
9486
+ case ALTER_SUBSCRIPTION_SET_PUBLICATION:
8815
9487
  appendStringInfoString(str, "SET PUBLICATION ");
8816
9488
  foreach(lc, alter_subscription_stmt->publication)
8817
9489
  {
@@ -8826,17 +9498,13 @@ static void deparseAlterSubscriptionStmt(StringInfo str, AlterSubscriptionStmt *
8826
9498
  Assert(list_length(alter_subscription_stmt->options) == 1);
8827
9499
  DefElem *defelem = castNode(DefElem, linitial(alter_subscription_stmt->options));
8828
9500
  Assert(strcmp(defelem->defname, "enabled") == 0);
8829
- if (intVal(defelem->arg) == 1)
9501
+ if (optBooleanValue(defelem->arg))
8830
9502
  {
8831
9503
  appendStringInfoString(str, " ENABLE ");
8832
9504
  }
8833
- else if (intVal(defelem->arg) == 0)
8834
- {
8835
- appendStringInfoString(str, " DISABLE ");
8836
- }
8837
9505
  else
8838
9506
  {
8839
- Assert(false);
9507
+ appendStringInfoString(str, " DISABLE ");
8840
9508
  }
8841
9509
  break;
8842
9510
  }
@@ -8898,7 +9566,7 @@ static void deparseAlterOwnerStmt(StringInfo str, AlterOwnerStmt *alter_owner_st
8898
9566
  break;
8899
9567
  case OBJECT_LARGEOBJECT:
8900
9568
  appendStringInfoString(str, "LARGE OBJECT ");
8901
- deparseNumericOnly(str, (Value *) alter_owner_stmt->object);
9569
+ deparseNumericOnly(str, (union ValUnion *) alter_owner_stmt->object);
8902
9570
  break;
8903
9571
  case OBJECT_OPERATOR:
8904
9572
  appendStringInfoString(str, "OPERATOR ");
@@ -9061,6 +9729,8 @@ static void deparseCreateTrigStmt(StringInfo str, CreateTrigStmt *create_trig_st
9061
9729
  bool skip_events_or = true;
9062
9730
 
9063
9731
  appendStringInfoString(str, "CREATE ");
9732
+ if (create_trig_stmt->replace)
9733
+ appendStringInfoString(str, "OR REPLACE ");
9064
9734
  if (create_trig_stmt->isconstraint)
9065
9735
  appendStringInfoString(str, "CONSTRAINT ");
9066
9736
  appendStringInfoString(str, "TRIGGER ");
@@ -9224,8 +9894,6 @@ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
9224
9894
  Assert(false);
9225
9895
  }
9226
9896
  deparseExpr(str, linitial(xml_expr->args));
9227
- if (strcmp(strVal(&castNode(A_Const, castNode(TypeCast, lsecond(xml_expr->args))->arg)->val), "t") == 0)
9228
- appendStringInfoString(str, " PRESERVE WHITESPACE");
9229
9897
  appendStringInfoChar(str, ')');
9230
9898
  break;
9231
9899
  case IS_XMLPI: /* XMLPI(name [, args]) */
@@ -9242,7 +9910,7 @@ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
9242
9910
  appendStringInfoString(str, "xmlroot(");
9243
9911
  deparseExpr(str, linitial(xml_expr->args));
9244
9912
  appendStringInfoString(str, ", version ");
9245
- if (nodeTag(&castNode(A_Const, lsecond(xml_expr->args))->val) == T_Null)
9913
+ if (castNode(A_Const, lsecond(xml_expr->args))->isnull)
9246
9914
  appendStringInfoString(str, "NO VALUE");
9247
9915
  else
9248
9916
  deparseExpr(str, lsecond(xml_expr->args));
@@ -9372,8 +10040,8 @@ static void deparseGroupingFunc(StringInfo str, GroupingFunc *grouping_func)
9372
10040
  static void deparseClusterStmt(StringInfo str, ClusterStmt *cluster_stmt)
9373
10041
  {
9374
10042
  appendStringInfoString(str, "CLUSTER ");
9375
- if (cluster_stmt->options & CLUOPT_VERBOSE)
9376
- appendStringInfoString(str, "VERBOSE ");
10043
+
10044
+ deparseUtilityOptionList(str, cluster_stmt->params);
9377
10045
 
9378
10046
  if (cluster_stmt->relation != NULL)
9379
10047
  {
@@ -9391,42 +10059,47 @@ static void deparseClusterStmt(StringInfo str, ClusterStmt *cluster_stmt)
9391
10059
  removeTrailingSpace(str);
9392
10060
  }
9393
10061
 
9394
- static void deparseValue(StringInfo str, Value *value, DeparseNodeContext context)
10062
+ static void deparseValue(StringInfo str, union ValUnion *value, DeparseNodeContext context)
9395
10063
  {
10064
+ if (!value) {
10065
+ appendStringInfoString(str, "NULL");
10066
+ return;
10067
+ }
10068
+
9396
10069
  switch (nodeTag(value))
9397
10070
  {
9398
10071
  case T_Integer:
9399
10072
  case T_Float:
9400
10073
  deparseNumericOnly(str, value);
9401
10074
  break;
10075
+ case T_Boolean:
10076
+ appendStringInfoString(str, value->boolval.boolval ? "true" : "false");
10077
+ break;
9402
10078
  case T_String:
9403
10079
  if (context == DEPARSE_NODE_CONTEXT_IDENTIFIER) {
9404
- appendStringInfoString(str, quote_identifier(value->val.str));
10080
+ appendStringInfoString(str, quote_identifier(value->sval.sval));
9405
10081
  } else if (context == DEPARSE_NODE_CONTEXT_CONSTANT) {
9406
- deparseStringLiteral(str, value->val.str);
10082
+ deparseStringLiteral(str, value->sval.sval);
9407
10083
  } else {
9408
- appendStringInfoString(str, value->val.str);
10084
+ appendStringInfoString(str, value->sval.sval);
9409
10085
  }
9410
10086
  break;
9411
10087
  case T_BitString:
9412
- if (strlen(value->val.str) >= 1 && value->val.str[0] == 'x')
10088
+ if (strlen(value->sval.sval) >= 1 && value->sval.sval[0] == 'x')
9413
10089
  {
9414
10090
  appendStringInfoChar(str, 'x');
9415
- deparseStringLiteral(str, value->val.str + 1);
10091
+ deparseStringLiteral(str, value->sval.sval + 1);
9416
10092
  }
9417
- else if (strlen(value->val.str) >= 1 && value->val.str[0] == 'b')
10093
+ else if (strlen(value->sval.sval) >= 1 && value->sval.sval[0] == 'b')
9418
10094
  {
9419
10095
  appendStringInfoChar(str, 'b');
9420
- deparseStringLiteral(str, value->val.str + 1);
10096
+ deparseStringLiteral(str, value->sval.sval + 1);
9421
10097
  }
9422
10098
  else
9423
10099
  {
9424
10100
  Assert(false);
9425
10101
  }
9426
10102
  break;
9427
- case T_Null:
9428
- appendStringInfoString(str, "NULL");
9429
- break;
9430
10103
  default:
9431
10104
  elog(ERROR, "deparse: unrecognized value node type: %d",
9432
10105
  (int) nodeTag(value));
@@ -9451,6 +10124,9 @@ static void deparsePreparableStmt(StringInfo str, Node *node)
9451
10124
  case T_DeleteStmt:
9452
10125
  deparseDeleteStmt(str, castNode(DeleteStmt, node));
9453
10126
  break;
10127
+ case T_MergeStmt:
10128
+ deparseMergeStmt(str, castNode(MergeStmt, node));
10129
+ break;
9454
10130
  default:
9455
10131
  Assert(false);
9456
10132
  }
@@ -9510,6 +10186,9 @@ static void deparseExplainableStmt(StringInfo str, Node *node)
9510
10186
  case T_ExecuteStmt:
9511
10187
  deparseExecuteStmt(str, castNode(ExecuteStmt, node));
9512
10188
  break;
10189
+ case T_MergeStmt:
10190
+ deparseMergeStmt(str, castNode(MergeStmt, node));
10191
+ break;
9513
10192
  default:
9514
10193
  Assert(false);
9515
10194
  }
@@ -9632,6 +10311,9 @@ static void deparseStmt(StringInfo str, Node *node)
9632
10311
  case T_AlterSystemStmt:
9633
10312
  deparseAlterSystemStmt(str, castNode(AlterSystemStmt, node));
9634
10313
  break;
10314
+ case T_AlterTableMoveAllStmt:
10315
+ deparseAlterTableMoveAllStmt(str, castNode(AlterTableMoveAllStmt, node));
10316
+ break;
9635
10317
  case T_AlterTableStmt:
9636
10318
  deparseAlterTableStmt(str, castNode(AlterTableStmt, node));
9637
10319
  break;
@@ -9842,6 +10524,9 @@ static void deparseStmt(StringInfo str, Node *node)
9842
10524
  case T_LockStmt:
9843
10525
  deparseLockStmt(str, castNode(LockStmt, node));
9844
10526
  break;
10527
+ case T_MergeStmt:
10528
+ deparseMergeStmt(str, castNode(MergeStmt, node));
10529
+ break;
9845
10530
  case T_NotifyStmt:
9846
10531
  deparseNotifyStmt(str, castNode(NotifyStmt, node));
9847
10532
  break;