pg_query 2.2.1 → 4.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (466) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/README.md +29 -33
  4. data/Rakefile +2 -2
  5. data/ext/pg_query/include/access/amapi.h +45 -1
  6. data/ext/pg_query/include/access/attmap.h +1 -1
  7. data/ext/pg_query/include/access/attnum.h +2 -2
  8. data/ext/pg_query/include/access/clog.h +4 -2
  9. data/ext/pg_query/include/access/commit_ts.h +6 -9
  10. data/ext/pg_query/include/access/detoast.h +1 -11
  11. data/ext/pg_query/include/access/genam.h +15 -12
  12. data/ext/pg_query/include/access/gin.h +2 -2
  13. data/ext/pg_query/include/access/htup.h +1 -1
  14. data/ext/pg_query/include/access/htup_details.h +75 -87
  15. data/ext/pg_query/include/access/itup.h +7 -1
  16. data/ext/pg_query/include/access/parallel.h +2 -2
  17. data/ext/pg_query/include/access/printtup.h +1 -1
  18. data/ext/pg_query/include/access/relation.h +1 -1
  19. data/ext/pg_query/include/access/relscan.h +17 -2
  20. data/ext/pg_query/include/access/rmgr.h +30 -3
  21. data/ext/pg_query/include/access/rmgrlist.h +23 -23
  22. data/ext/pg_query/include/access/sdir.h +1 -1
  23. data/ext/pg_query/include/access/skey.h +1 -1
  24. data/ext/pg_query/include/access/stratnum.h +4 -2
  25. data/ext/pg_query/include/access/sysattr.h +1 -1
  26. data/ext/pg_query/include/access/table.h +2 -1
  27. data/ext/pg_query/include/access/tableam.h +272 -20
  28. data/ext/pg_query/include/access/toast_compression.h +73 -0
  29. data/ext/pg_query/include/access/transam.h +123 -13
  30. data/ext/pg_query/include/access/tupconvert.h +1 -1
  31. data/ext/pg_query/include/access/tupdesc.h +1 -1
  32. data/ext/pg_query/include/access/tupmacs.h +3 -3
  33. data/ext/pg_query/include/access/twophase.h +3 -1
  34. data/ext/pg_query/include/access/xact.h +73 -19
  35. data/ext/pg_query/include/access/xlog.h +60 -155
  36. data/ext/pg_query/include/access/xlog_internal.h +40 -13
  37. data/ext/pg_query/include/access/xlogdefs.h +8 -16
  38. data/ext/pg_query/include/access/xlogprefetcher.h +55 -0
  39. data/ext/pg_query/include/access/xlogreader.h +145 -39
  40. data/ext/pg_query/include/access/xlogrecord.h +18 -9
  41. data/ext/pg_query/include/access/xlogrecovery.h +157 -0
  42. data/ext/pg_query/include/c.h +101 -44
  43. data/ext/pg_query/include/catalog/catalog.h +3 -1
  44. data/ext/pg_query/include/catalog/catversion.h +2 -2
  45. data/ext/pg_query/include/catalog/dependency.h +8 -16
  46. data/ext/pg_query/include/catalog/genbki.h +83 -5
  47. data/ext/pg_query/include/catalog/index.h +18 -3
  48. data/ext/pg_query/include/catalog/indexing.h +12 -324
  49. data/ext/pg_query/include/catalog/namespace.h +4 -2
  50. data/ext/pg_query/include/catalog/objectaccess.h +70 -2
  51. data/ext/pg_query/include/catalog/objectaddress.h +11 -6
  52. data/ext/pg_query/include/catalog/pg_aggregate.h +14 -10
  53. data/ext/pg_query/include/catalog/pg_aggregate_d.h +2 -1
  54. data/ext/pg_query/include/catalog/pg_am.h +4 -1
  55. data/ext/pg_query/include/catalog/pg_am_d.h +3 -1
  56. data/ext/pg_query/include/catalog/pg_attribute.h +27 -10
  57. data/ext/pg_query/include/catalog/pg_attribute_d.h +21 -18
  58. data/ext/pg_query/include/catalog/pg_authid.h +7 -2
  59. data/ext/pg_query/include/catalog/pg_authid_d.h +17 -9
  60. data/ext/pg_query/include/catalog/pg_class.h +44 -14
  61. data/ext/pg_query/include/catalog/pg_class_d.h +30 -1
  62. data/ext/pg_query/include/catalog/pg_collation.h +33 -8
  63. data/ext/pg_query/include/catalog/pg_collation_d.h +20 -3
  64. data/ext/pg_query/include/catalog/pg_constraint.h +38 -12
  65. data/ext/pg_query/include/catalog/pg_constraint_d.h +10 -4
  66. data/ext/pg_query/include/catalog/pg_control.h +3 -5
  67. data/ext/pg_query/include/catalog/pg_conversion.h +7 -4
  68. data/ext/pg_query/include/catalog/pg_conversion_d.h +4 -1
  69. data/ext/pg_query/include/catalog/pg_depend.h +11 -7
  70. data/ext/pg_query/include/catalog/pg_depend_d.h +3 -1
  71. data/ext/pg_query/include/catalog/pg_event_trigger.h +9 -3
  72. data/ext/pg_query/include/catalog/pg_event_trigger_d.h +3 -1
  73. data/ext/pg_query/include/catalog/pg_index.h +17 -7
  74. data/ext/pg_query/include/catalog/pg_index_d.h +20 -17
  75. data/ext/pg_query/include/catalog/pg_language.h +10 -5
  76. data/ext/pg_query/include/catalog/pg_language_d.h +3 -1
  77. data/ext/pg_query/include/catalog/pg_namespace.h +7 -2
  78. data/ext/pg_query/include/catalog/pg_namespace_d.h +3 -1
  79. data/ext/pg_query/include/catalog/pg_opclass.h +8 -5
  80. data/ext/pg_query/include/catalog/pg_opclass_d.h +3 -1
  81. data/ext/pg_query/include/catalog/pg_operator.h +18 -15
  82. data/ext/pg_query/include/catalog/pg_operator_d.h +37 -1
  83. data/ext/pg_query/include/catalog/pg_opfamily.h +6 -3
  84. data/ext/pg_query/include/catalog/pg_opfamily_d.h +3 -1
  85. data/ext/pg_query/include/catalog/pg_parameter_acl.h +60 -0
  86. data/ext/pg_query/include/catalog/pg_parameter_acl_d.h +34 -0
  87. data/ext/pg_query/include/catalog/pg_partitioned_table.h +20 -9
  88. data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +2 -1
  89. data/ext/pg_query/include/catalog/pg_proc.h +20 -11
  90. data/ext/pg_query/include/catalog/pg_proc_d.h +10 -8
  91. data/ext/pg_query/include/catalog/pg_publication.h +50 -7
  92. data/ext/pg_query/include/catalog/pg_publication_d.h +3 -1
  93. data/ext/pg_query/include/catalog/pg_replication_origin.h +6 -1
  94. data/ext/pg_query/include/catalog/pg_replication_origin_d.h +5 -1
  95. data/ext/pg_query/include/catalog/pg_statistic.h +19 -12
  96. data/ext/pg_query/include/catalog/pg_statistic_d.h +2 -1
  97. data/ext/pg_query/include/catalog/pg_statistic_ext.h +19 -5
  98. data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +7 -2
  99. data/ext/pg_query/include/catalog/pg_transform.h +8 -5
  100. data/ext/pg_query/include/catalog/pg_transform_d.h +3 -1
  101. data/ext/pg_query/include/catalog/pg_trigger.h +24 -8
  102. data/ext/pg_query/include/catalog/pg_trigger_d.h +4 -1
  103. data/ext/pg_query/include/catalog/pg_ts_config.h +6 -3
  104. data/ext/pg_query/include/catalog/pg_ts_config_d.h +3 -1
  105. data/ext/pg_query/include/catalog/pg_ts_dict.h +8 -3
  106. data/ext/pg_query/include/catalog/pg_ts_dict_d.h +3 -1
  107. data/ext/pg_query/include/catalog/pg_ts_parser.h +6 -3
  108. data/ext/pg_query/include/catalog/pg_ts_parser_d.h +3 -1
  109. data/ext/pg_query/include/catalog/pg_ts_template.h +6 -3
  110. data/ext/pg_query/include/catalog/pg_ts_template_d.h +3 -1
  111. data/ext/pg_query/include/catalog/pg_type.h +55 -24
  112. data/ext/pg_query/include/catalog/pg_type_d.h +70 -31
  113. data/ext/pg_query/include/catalog/storage.h +5 -3
  114. data/ext/pg_query/include/commands/async.h +3 -4
  115. data/ext/pg_query/include/commands/dbcommands.h +2 -1
  116. data/ext/pg_query/include/commands/defrem.h +11 -24
  117. data/ext/pg_query/include/commands/event_trigger.h +2 -2
  118. data/ext/pg_query/include/commands/explain.h +1 -1
  119. data/ext/pg_query/include/commands/prepare.h +1 -1
  120. data/ext/pg_query/include/commands/tablespace.h +2 -2
  121. data/ext/pg_query/include/commands/trigger.h +18 -16
  122. data/ext/pg_query/include/commands/user.h +2 -2
  123. data/ext/pg_query/include/commands/vacuum.h +88 -41
  124. data/ext/pg_query/include/commands/variable.h +1 -1
  125. data/ext/pg_query/include/common/file_perm.h +4 -4
  126. data/ext/pg_query/include/common/hashfn.h +1 -1
  127. data/ext/pg_query/include/common/ip.h +1 -7
  128. data/ext/pg_query/include/common/keywords.h +2 -6
  129. data/ext/pg_query/include/common/kwlookup.h +1 -1
  130. data/ext/pg_query/include/common/pg_prng.h +60 -0
  131. data/ext/pg_query/include/common/relpath.h +2 -2
  132. data/ext/pg_query/include/common/string.h +24 -1
  133. data/ext/pg_query/include/common/unicode_combining_table.h +114 -2
  134. data/ext/pg_query/include/common/unicode_east_asian_fw_table.h +125 -0
  135. data/ext/pg_query/include/datatype/timestamp.h +40 -1
  136. data/ext/pg_query/include/executor/execdesc.h +1 -1
  137. data/ext/pg_query/include/executor/executor.h +65 -22
  138. data/ext/pg_query/include/executor/functions.h +17 -3
  139. data/ext/pg_query/include/executor/instrument.h +33 -16
  140. data/ext/pg_query/include/executor/spi.h +41 -3
  141. data/ext/pg_query/include/executor/tablefunc.h +1 -1
  142. data/ext/pg_query/include/executor/tuptable.h +1 -1
  143. data/ext/pg_query/include/fmgr.h +13 -7
  144. data/ext/pg_query/include/funcapi.h +16 -4
  145. data/ext/pg_query/include/getaddrinfo.h +1 -1
  146. data/ext/pg_query/include/jit/jit.h +11 -11
  147. data/ext/pg_query/include/kwlist_d.h +517 -494
  148. data/ext/pg_query/include/lib/dshash.h +112 -0
  149. data/ext/pg_query/include/lib/ilist.h +20 -1
  150. data/ext/pg_query/include/lib/pairingheap.h +1 -1
  151. data/ext/pg_query/include/lib/simplehash.h +140 -15
  152. data/ext/pg_query/include/lib/sort_template.h +432 -0
  153. data/ext/pg_query/include/lib/stringinfo.h +1 -1
  154. data/ext/pg_query/include/libpq/auth.h +6 -4
  155. data/ext/pg_query/include/libpq/crypt.h +5 -4
  156. data/ext/pg_query/include/libpq/hba.h +43 -4
  157. data/ext/pg_query/include/libpq/libpq-be.h +23 -6
  158. data/ext/pg_query/include/libpq/libpq.h +30 -20
  159. data/ext/pg_query/include/libpq/pqcomm.h +17 -31
  160. data/ext/pg_query/include/libpq/pqformat.h +1 -1
  161. data/ext/pg_query/include/libpq/pqsignal.h +4 -4
  162. data/ext/pg_query/include/mb/pg_wchar.h +105 -23
  163. data/ext/pg_query/include/mb/stringinfo_mb.h +1 -1
  164. data/ext/pg_query/include/miscadmin.h +47 -41
  165. data/ext/pg_query/include/nodes/bitmapset.h +1 -1
  166. data/ext/pg_query/include/nodes/execnodes.h +270 -78
  167. data/ext/pg_query/include/nodes/extensible.h +4 -2
  168. data/ext/pg_query/include/nodes/lockoptions.h +1 -1
  169. data/ext/pg_query/include/nodes/makefuncs.h +7 -6
  170. data/ext/pg_query/include/nodes/memnodes.h +5 -3
  171. data/ext/pg_query/include/nodes/nodeFuncs.h +1 -1
  172. data/ext/pg_query/include/nodes/nodes.h +30 -11
  173. data/ext/pg_query/include/nodes/params.h +1 -1
  174. data/ext/pg_query/include/nodes/parsenodes.h +322 -90
  175. data/ext/pg_query/include/nodes/pathnodes.h +243 -66
  176. data/ext/pg_query/include/nodes/pg_list.h +75 -69
  177. data/ext/pg_query/include/nodes/plannodes.h +111 -28
  178. data/ext/pg_query/include/nodes/primnodes.h +99 -47
  179. data/ext/pg_query/include/nodes/print.h +1 -1
  180. data/ext/pg_query/include/nodes/tidbitmap.h +1 -1
  181. data/ext/pg_query/include/nodes/value.h +58 -39
  182. data/ext/pg_query/include/optimizer/cost.h +9 -2
  183. data/ext/pg_query/include/optimizer/geqo.h +9 -7
  184. data/ext/pg_query/include/optimizer/geqo_gene.h +1 -1
  185. data/ext/pg_query/include/optimizer/optimizer.h +25 -17
  186. data/ext/pg_query/include/optimizer/paths.h +6 -6
  187. data/ext/pg_query/include/optimizer/planmain.h +15 -14
  188. data/ext/pg_query/include/parser/analyze.h +19 -5
  189. data/ext/pg_query/include/parser/gram.h +947 -913
  190. data/ext/pg_query/include/parser/gramparse.h +1 -1
  191. data/ext/pg_query/include/parser/kwlist.h +463 -453
  192. data/ext/pg_query/include/parser/parse_agg.h +2 -7
  193. data/ext/pg_query/include/parser/parse_coerce.h +3 -1
  194. data/ext/pg_query/include/parser/parse_expr.h +2 -3
  195. data/ext/pg_query/include/parser/parse_func.h +2 -1
  196. data/ext/pg_query/include/parser/parse_node.h +21 -9
  197. data/ext/pg_query/include/parser/parse_oper.h +1 -3
  198. data/ext/pg_query/include/parser/parse_relation.h +5 -4
  199. data/ext/pg_query/include/parser/parse_type.h +1 -1
  200. data/ext/pg_query/include/parser/parser.h +31 -4
  201. data/ext/pg_query/include/parser/parsetree.h +1 -1
  202. data/ext/pg_query/include/parser/scanner.h +1 -1
  203. data/ext/pg_query/include/parser/scansup.h +2 -5
  204. data/ext/pg_query/include/partitioning/partdefs.h +1 -1
  205. data/ext/pg_query/include/pg_config.h +83 -41
  206. data/ext/pg_query/include/pg_config_manual.h +74 -21
  207. data/ext/pg_query/include/pg_getopt.h +6 -6
  208. data/ext/pg_query/include/pg_query.h +5 -4
  209. data/ext/pg_query/include/pg_query_enum_defs.c +358 -241
  210. data/ext/pg_query/include/pg_query_fingerprint_conds.c +44 -7
  211. data/ext/pg_query/include/pg_query_fingerprint_defs.c +939 -113
  212. data/ext/pg_query/include/pg_query_outfuncs_conds.c +43 -13
  213. data/ext/pg_query/include/pg_query_outfuncs_defs.c +151 -26
  214. data/ext/pg_query/include/pg_query_readfuncs_conds.c +11 -2
  215. data/ext/pg_query/include/pg_query_readfuncs_defs.c +173 -30
  216. data/ext/pg_query/include/pg_trace.h +1 -1
  217. data/ext/pg_query/include/pgstat.h +449 -1238
  218. data/ext/pg_query/include/pgtime.h +14 -4
  219. data/ext/pg_query/include/pl_gram.h +126 -128
  220. data/ext/pg_query/include/pl_reserved_kwlist.h +1 -1
  221. data/ext/pg_query/include/pl_reserved_kwlist_d.h +10 -10
  222. data/ext/pg_query/include/pl_unreserved_kwlist.h +2 -3
  223. data/ext/pg_query/include/pl_unreserved_kwlist_d.h +54 -56
  224. data/ext/pg_query/include/plerrcodes.h +9 -1
  225. data/ext/pg_query/include/plpgsql.h +52 -54
  226. data/ext/pg_query/include/port/atomics/arch-arm.h +7 -1
  227. data/ext/pg_query/include/port/atomics/arch-ppc.h +1 -1
  228. data/ext/pg_query/include/port/atomics/arch-x86.h +1 -1
  229. data/ext/pg_query/include/port/atomics/fallback.h +1 -1
  230. data/ext/pg_query/include/port/atomics/generic-gcc.h +3 -3
  231. data/ext/pg_query/include/port/atomics/generic.h +1 -1
  232. data/ext/pg_query/include/port/atomics.h +1 -1
  233. data/ext/pg_query/include/port/pg_bitutils.h +40 -10
  234. data/ext/pg_query/include/port/pg_bswap.h +1 -1
  235. data/ext/pg_query/include/port/pg_crc32c.h +1 -1
  236. data/ext/pg_query/include/port.h +71 -46
  237. data/ext/pg_query/include/portability/instr_time.h +1 -1
  238. data/ext/pg_query/include/postgres.h +60 -16
  239. data/ext/pg_query/include/postmaster/autovacuum.h +17 -17
  240. data/ext/pg_query/include/postmaster/auxprocess.h +20 -0
  241. data/ext/pg_query/include/postmaster/bgworker.h +2 -1
  242. data/ext/pg_query/include/postmaster/bgworker_internals.h +2 -2
  243. data/ext/pg_query/include/postmaster/bgwriter.h +5 -5
  244. data/ext/pg_query/include/postmaster/fork_process.h +1 -1
  245. data/ext/pg_query/include/postmaster/interrupt.h +1 -1
  246. data/ext/pg_query/include/postmaster/pgarch.h +42 -8
  247. data/ext/pg_query/include/postmaster/postmaster.h +18 -17
  248. data/ext/pg_query/include/postmaster/startup.h +39 -0
  249. data/ext/pg_query/include/postmaster/syslogger.h +15 -10
  250. data/ext/pg_query/include/postmaster/walwriter.h +3 -3
  251. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +1419 -914
  252. data/ext/pg_query/include/protobuf/pg_query.pb.h +43678 -32769
  253. data/ext/pg_query/include/regex/regex.h +18 -16
  254. data/ext/pg_query/include/replication/logicallauncher.h +3 -5
  255. data/ext/pg_query/include/replication/logicalproto.h +161 -17
  256. data/ext/pg_query/include/replication/logicalworker.h +1 -1
  257. data/ext/pg_query/include/replication/origin.h +7 -7
  258. data/ext/pg_query/include/replication/reorderbuffer.h +259 -42
  259. data/ext/pg_query/include/replication/slot.h +22 -11
  260. data/ext/pg_query/include/replication/syncrep.h +5 -5
  261. data/ext/pg_query/include/replication/walreceiver.h +145 -13
  262. data/ext/pg_query/include/replication/walsender.h +8 -8
  263. data/ext/pg_query/include/rewrite/prs2lock.h +1 -1
  264. data/ext/pg_query/include/rewrite/rewriteHandler.h +1 -3
  265. data/ext/pg_query/include/rewrite/rewriteManip.h +1 -1
  266. data/ext/pg_query/include/rewrite/rewriteSupport.h +1 -1
  267. data/ext/pg_query/include/storage/backendid.h +3 -3
  268. data/ext/pg_query/include/storage/block.h +4 -10
  269. data/ext/pg_query/include/storage/buf.h +1 -1
  270. data/ext/pg_query/include/storage/bufmgr.h +19 -14
  271. data/ext/pg_query/include/storage/bufpage.h +6 -8
  272. data/ext/pg_query/include/storage/condition_variable.h +13 -2
  273. data/ext/pg_query/include/storage/dsm.h +4 -1
  274. data/ext/pg_query/include/storage/dsm_impl.h +3 -2
  275. data/ext/pg_query/include/storage/fd.h +33 -3
  276. data/ext/pg_query/include/storage/fileset.h +40 -0
  277. data/ext/pg_query/include/storage/ipc.h +4 -1
  278. data/ext/pg_query/include/storage/item.h +1 -1
  279. data/ext/pg_query/include/storage/itemid.h +1 -1
  280. data/ext/pg_query/include/storage/itemptr.h +3 -1
  281. data/ext/pg_query/include/storage/large_object.h +2 -2
  282. data/ext/pg_query/include/storage/latch.h +9 -13
  283. data/ext/pg_query/include/storage/lmgr.h +2 -1
  284. data/ext/pg_query/include/storage/lock.h +11 -8
  285. data/ext/pg_query/include/storage/lockdefs.h +2 -2
  286. data/ext/pg_query/include/storage/lwlock.h +5 -32
  287. data/ext/pg_query/include/storage/lwlocknames.h +0 -1
  288. data/ext/pg_query/include/storage/off.h +1 -1
  289. data/ext/pg_query/include/storage/pg_sema.h +1 -1
  290. data/ext/pg_query/include/storage/pg_shmem.h +9 -7
  291. data/ext/pg_query/include/storage/pmsignal.h +15 -4
  292. data/ext/pg_query/include/storage/predicate.h +4 -4
  293. data/ext/pg_query/include/storage/proc.h +173 -59
  294. data/ext/pg_query/include/storage/procarray.h +98 -0
  295. data/ext/pg_query/include/storage/proclist_types.h +1 -1
  296. data/ext/pg_query/include/storage/procsignal.h +3 -7
  297. data/ext/pg_query/include/storage/relfilenode.h +1 -1
  298. data/ext/pg_query/include/storage/s_lock.h +60 -21
  299. data/ext/pg_query/include/storage/sharedfileset.h +3 -11
  300. data/ext/pg_query/include/storage/shm_mq.h +5 -4
  301. data/ext/pg_query/include/storage/shm_toc.h +1 -1
  302. data/ext/pg_query/include/storage/shmem.h +1 -1
  303. data/ext/pg_query/include/storage/sinval.h +3 -3
  304. data/ext/pg_query/include/storage/sinvaladt.h +1 -1
  305. data/ext/pg_query/include/storage/smgr.h +10 -8
  306. data/ext/pg_query/include/storage/spin.h +2 -2
  307. data/ext/pg_query/include/storage/standby.h +13 -6
  308. data/ext/pg_query/include/storage/standbydefs.h +2 -2
  309. data/ext/pg_query/include/storage/sync.h +7 -3
  310. data/ext/pg_query/include/tcop/cmdtag.h +1 -1
  311. data/ext/pg_query/include/tcop/cmdtaglist.h +3 -2
  312. data/ext/pg_query/include/tcop/deparse_utility.h +1 -1
  313. data/ext/pg_query/include/tcop/dest.h +1 -1
  314. data/ext/pg_query/include/tcop/fastpath.h +1 -2
  315. data/ext/pg_query/include/tcop/pquery.h +1 -1
  316. data/ext/pg_query/include/tcop/tcopprot.h +19 -11
  317. data/ext/pg_query/include/tcop/utility.h +7 -3
  318. data/ext/pg_query/include/tsearch/ts_cache.h +2 -2
  319. data/ext/pg_query/include/utils/acl.h +24 -3
  320. data/ext/pg_query/include/utils/aclchk_internal.h +1 -1
  321. data/ext/pg_query/include/utils/array.h +7 -2
  322. data/ext/pg_query/include/utils/backend_progress.h +44 -0
  323. data/ext/pg_query/include/utils/backend_status.h +321 -0
  324. data/ext/pg_query/include/utils/builtins.h +10 -11
  325. data/ext/pg_query/include/utils/bytea.h +3 -2
  326. data/ext/pg_query/include/utils/catcache.h +1 -1
  327. data/ext/pg_query/include/utils/date.h +1 -1
  328. data/ext/pg_query/include/utils/datetime.h +8 -7
  329. data/ext/pg_query/include/utils/datum.h +9 -1
  330. data/ext/pg_query/include/utils/dsa.h +1 -1
  331. data/ext/pg_query/include/utils/dynahash.h +4 -3
  332. data/ext/pg_query/include/utils/elog.h +52 -21
  333. data/ext/pg_query/include/utils/errcodes.h +2 -0
  334. data/ext/pg_query/include/utils/expandeddatum.h +1 -1
  335. data/ext/pg_query/include/utils/expandedrecord.h +1 -1
  336. data/ext/pg_query/include/utils/float.h +7 -7
  337. data/ext/pg_query/include/utils/fmgroids.h +1300 -696
  338. data/ext/pg_query/include/utils/fmgrprotos.h +199 -16
  339. data/ext/pg_query/include/utils/fmgrtab.h +6 -5
  340. data/ext/pg_query/include/utils/guc.h +69 -43
  341. data/ext/pg_query/include/utils/guc_tables.h +23 -19
  342. data/ext/pg_query/include/utils/hsearch.h +15 -11
  343. data/ext/pg_query/include/utils/inval.h +4 -1
  344. data/ext/pg_query/include/utils/lsyscache.h +11 -1
  345. data/ext/pg_query/include/utils/memdebug.h +1 -1
  346. data/ext/pg_query/include/utils/memutils.h +8 -3
  347. data/ext/pg_query/include/utils/numeric.h +19 -5
  348. data/ext/pg_query/include/utils/palloc.h +25 -3
  349. data/ext/pg_query/include/utils/partcache.h +1 -1
  350. data/ext/pg_query/include/utils/pg_locale.h +17 -9
  351. data/ext/pg_query/include/utils/pg_lsn.h +1 -1
  352. data/ext/pg_query/include/utils/pgstat_internal.h +784 -0
  353. data/ext/pg_query/include/utils/pidfile.h +1 -1
  354. data/ext/pg_query/include/utils/plancache.h +6 -5
  355. data/ext/pg_query/include/utils/portal.h +10 -12
  356. data/ext/pg_query/include/utils/ps_status.h +1 -1
  357. data/ext/pg_query/include/utils/queryenvironment.h +1 -1
  358. data/ext/pg_query/include/utils/queryjumble.h +88 -0
  359. data/ext/pg_query/include/utils/regproc.h +14 -3
  360. data/ext/pg_query/include/utils/rel.h +71 -19
  361. data/ext/pg_query/include/utils/relcache.h +8 -5
  362. data/ext/pg_query/include/utils/reltrigger.h +1 -1
  363. data/ext/pg_query/include/utils/resowner.h +1 -1
  364. data/ext/pg_query/include/utils/rls.h +2 -2
  365. data/ext/pg_query/include/utils/ruleutils.h +4 -1
  366. data/ext/pg_query/include/utils/sharedtuplestore.h +1 -1
  367. data/ext/pg_query/include/utils/snapmgr.h +34 -14
  368. data/ext/pg_query/include/utils/snapshot.h +14 -1
  369. data/ext/pg_query/include/utils/sortsupport.h +117 -2
  370. data/ext/pg_query/include/utils/syscache.h +6 -1
  371. data/ext/pg_query/include/utils/timeout.h +11 -4
  372. data/ext/pg_query/include/utils/timestamp.h +6 -5
  373. data/ext/pg_query/include/utils/tuplesort.h +25 -11
  374. data/ext/pg_query/include/utils/tuplestore.h +2 -2
  375. data/ext/pg_query/include/utils/typcache.h +24 -17
  376. data/ext/pg_query/include/utils/tzparser.h +1 -1
  377. data/ext/pg_query/include/utils/varlena.h +5 -3
  378. data/ext/pg_query/include/utils/wait_event.h +289 -0
  379. data/ext/pg_query/include/utils/xml.h +4 -4
  380. data/ext/pg_query/pg_query.pb-c.c +4302 -2304
  381. data/ext/pg_query/pg_query_deparse.c +1106 -373
  382. data/ext/pg_query/pg_query_fingerprint.c +30 -10
  383. data/ext/pg_query/pg_query_json_plpgsql.c +0 -25
  384. data/ext/pg_query/pg_query_normalize.c +1 -1
  385. data/ext/pg_query/pg_query_outfuncs_json.c +54 -16
  386. data/ext/pg_query/pg_query_outfuncs_protobuf.c +70 -10
  387. data/ext/pg_query/pg_query_parse.c +1 -1
  388. data/ext/pg_query/pg_query_readfuncs_protobuf.c +42 -8
  389. data/ext/pg_query/pg_query_scan.c +2 -1
  390. data/ext/pg_query/pg_query_split.c +3 -2
  391. data/ext/pg_query/src_backend_catalog_namespace.c +20 -9
  392. data/ext/pg_query/src_backend_catalog_pg_proc.c +4 -1
  393. data/ext/pg_query/src_backend_commands_define.c +11 -1
  394. data/ext/pg_query/src_backend_nodes_bitmapset.c +3 -1
  395. data/ext/pg_query/src_backend_nodes_copyfuncs.c +401 -76
  396. data/ext/pg_query/src_backend_nodes_equalfuncs.c +290 -46
  397. data/ext/pg_query/src_backend_nodes_extensible.c +1 -1
  398. data/ext/pg_query/src_backend_nodes_list.c +74 -11
  399. data/ext/pg_query/src_backend_nodes_makefuncs.c +5 -4
  400. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +55 -12
  401. data/ext/pg_query/src_backend_nodes_value.c +28 -19
  402. data/ext/pg_query/src_backend_parser_gram.c +33874 -31261
  403. data/ext/pg_query/src_backend_parser_parser.c +26 -7
  404. data/ext/pg_query/src_backend_parser_scan.c +172 -209
  405. data/ext/pg_query/src_backend_parser_scansup.c +4 -28
  406. data/ext/pg_query/src_backend_postmaster_postmaster.c +77 -106
  407. data/ext/pg_query/src_backend_storage_ipc_ipc.c +13 -4
  408. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +5 -4
  409. data/ext/pg_query/src_backend_tcop_postgres.c +62 -23
  410. data/ext/pg_query/src_backend_utils_activity_pgstat_database.c +140 -0
  411. data/ext/pg_query/src_backend_utils_adt_datum.c +13 -1
  412. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +1 -1
  413. data/ext/pg_query/src_backend_utils_adt_format_type.c +6 -2
  414. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +71 -5
  415. data/ext/pg_query/src_backend_utils_error_assert.c +16 -14
  416. data/ext/pg_query/src_backend_utils_error_elog.c +172 -99
  417. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +12 -17
  418. data/ext/pg_query/src_backend_utils_hash_dynahash.c +40 -10
  419. data/ext/pg_query/src_backend_utils_init_globals.c +5 -5
  420. data/ext/pg_query/src_backend_utils_mb_mbutils.c +55 -66
  421. data/ext/pg_query/src_backend_utils_misc_guc.c +206 -45
  422. data/ext/pg_query/src_backend_utils_mmgr_aset.c +7 -5
  423. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +123 -35
  424. data/ext/pg_query/src_common_encnames.c +1 -1
  425. data/ext/pg_query/src_common_hashfn.c +3 -3
  426. data/ext/pg_query/src_common_keywords.c +15 -2
  427. data/ext/pg_query/src_common_kwlist_d.h +517 -494
  428. data/ext/pg_query/src_common_kwlookup.c +1 -1
  429. data/ext/pg_query/src_common_pg_prng.c +152 -0
  430. data/ext/pg_query/src_common_psprintf.c +1 -1
  431. data/ext/pg_query/src_common_string.c +7 -1
  432. data/ext/pg_query/src_common_stringinfo.c +1 -1
  433. data/ext/pg_query/src_common_wchar.c +701 -109
  434. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +45 -20
  435. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +1 -18
  436. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1233 -1259
  437. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +1 -1
  438. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +10 -10
  439. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +2 -2
  440. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +54 -56
  441. data/ext/pg_query/src_port_pg_bitutils.c +41 -31
  442. data/ext/pg_query/src_port_pgsleep.c +1 -1
  443. data/ext/pg_query/src_port_pgstrcasecmp.c +1 -1
  444. data/ext/pg_query/src_port_qsort.c +12 -224
  445. data/ext/pg_query/src_port_snprintf.c +37 -13
  446. data/ext/pg_query/src_port_strerror.c +9 -19
  447. data/ext/pg_query/src_port_strnlen.c +1 -1
  448. data/lib/pg_query/filter_columns.rb +1 -1
  449. data/lib/pg_query/fingerprint.rb +5 -1
  450. data/lib/pg_query/node.rb +2 -2
  451. data/lib/pg_query/param_refs.rb +1 -1
  452. data/lib/pg_query/parse.rb +18 -8
  453. data/lib/pg_query/pg_query_pb.rb +1108 -942
  454. data/lib/pg_query/truncate.rb +1 -1
  455. data/lib/pg_query/version.rb +1 -1
  456. metadata +28 -18
  457. data/ext/pg_query/include/access/xloginsert.h +0 -64
  458. data/ext/pg_query/include/bootstrap/bootstrap.h +0 -62
  459. data/ext/pg_query/include/parser/parse_clause.h +0 -54
  460. data/ext/pg_query/include/parser/parse_collate.h +0 -27
  461. data/ext/pg_query/include/parser/parse_target.h +0 -46
  462. data/ext/pg_query/pg_query_ruby_freebsd.sym +0 -2
  463. data/ext/pg_query/src_backend_libpq_pqcomm.c +0 -659
  464. data/ext/pg_query/src_backend_parser_parse_expr.c +0 -313
  465. data/ext/pg_query/src_port_erand48.c +0 -127
  466. data/ext/pg_query/src_port_random.c +0 -31
@@ -11,7 +11,6 @@
11
11
  #include "common/keywords.h"
12
12
  #include "common/kwlookup.h"
13
13
  #include "lib/stringinfo.h"
14
- #include "limits.h"
15
14
  #include "nodes/nodes.h"
16
15
  #include "nodes/parsenodes.h"
17
16
  #include "nodes/pg_list.h"
@@ -32,6 +31,7 @@ typedef enum DeparseNodeContext {
32
31
  DEPARSE_NODE_CONTEXT_XMLNAMESPACES,
33
32
  DEPARSE_NODE_CONTEXT_CREATE_TYPE,
34
33
  DEPARSE_NODE_CONTEXT_ALTER_TYPE,
34
+ DEPARSE_NODE_CONTEXT_SET_STATEMENT,
35
35
  // Identifier vs constant context
36
36
  DEPARSE_NODE_CONTEXT_IDENTIFIER,
37
37
  DEPARSE_NODE_CONTEXT_CONSTANT
@@ -160,8 +160,9 @@ static void deparseRangeSubselect(StringInfo str, RangeSubselect *range_subselec
160
160
  static void deparseRangeFunction(StringInfo str, RangeFunction *range_func);
161
161
  static void deparseAArrayExpr(StringInfo str, A_ArrayExpr * array_expr);
162
162
  static void deparseRowExpr(StringInfo str, RowExpr *row_expr);
163
- static void deparseTypeCast(StringInfo str, TypeCast *type_cast);
163
+ static void deparseTypeCast(StringInfo str, TypeCast *type_cast, DeparseNodeContext context);
164
164
  static void deparseTypeName(StringInfo str, TypeName *type_name);
165
+ static void deparseIntervalTypmods(StringInfo str, TypeName *type_name);
165
166
  static void deparseNullTest(StringInfo str, NullTest *null_test);
166
167
  static void deparseCaseExpr(StringInfo str, CaseExpr *case_expr);
167
168
  static void deparseCaseWhen(StringInfo str, CaseWhen *case_when);
@@ -204,7 +205,7 @@ static void deparsePreparableStmt(StringInfo str, Node *node);
204
205
  static void deparseRuleActionStmt(StringInfo str, Node *node);
205
206
  static void deparseExplainableStmt(StringInfo str, Node *node);
206
207
  static void deparseStmt(StringInfo str, Node *node);
207
- static void deparseValue(StringInfo str, Value *value, DeparseNodeContext context);
208
+ static void deparseValue(StringInfo str, union ValUnion *value, DeparseNodeContext context);
208
209
 
209
210
  // "any_name" in gram.y
210
211
  static void deparseAnyName(StringInfo str, List *parts)
@@ -249,6 +250,8 @@ static void deparseAnyNameSkipLast(StringInfo str, List *parts)
249
250
  // "a_expr" / "b_expr" in gram.y
250
251
  static void deparseExpr(StringInfo str, Node *node)
251
252
  {
253
+ if (node == NULL)
254
+ return;
252
255
  switch (nodeTag(node))
253
256
  {
254
257
  case T_FuncCall:
@@ -258,7 +261,7 @@ static void deparseExpr(StringInfo str, Node *node)
258
261
  deparseXmlExpr(str, castNode(XmlExpr, node));
259
262
  break;
260
263
  case T_TypeCast:
261
- deparseTypeCast(str, castNode(TypeCast, node));
264
+ deparseTypeCast(str, castNode(TypeCast, node), DEPARSE_NODE_CONTEXT_NONE);
262
265
  break;
263
266
  case T_A_Const:
264
267
  deparseAConst(str, castNode(A_Const, node));
@@ -339,7 +342,7 @@ static void deparseCExpr(StringInfo str, Node *node)
339
342
  deparseAConst(str, castNode(A_Const, node));
340
343
  break;
341
344
  case T_TypeCast:
342
- deparseTypeCast(str, castNode(TypeCast, node));
345
+ deparseTypeCast(str, castNode(TypeCast, node), DEPARSE_NODE_CONTEXT_NONE);
343
346
  break;
344
347
  case T_A_Expr:
345
348
  appendStringInfoChar(str, '(');
@@ -381,7 +384,6 @@ static void deparseCExpr(StringInfo str, Node *node)
381
384
  static void deparseExprList(StringInfo str, List *exprs)
382
385
  {
383
386
  ListCell *lc;
384
-
385
387
  foreach(lc, exprs)
386
388
  {
387
389
  deparseExpr(str, lfirst(lc));
@@ -460,15 +462,15 @@ static void deparseSimpleTypename(StringInfo str, Node *node)
460
462
  }
461
463
 
462
464
  // "NumericOnly" in gram.y
463
- static void deparseNumericOnly(StringInfo str, Value *value)
465
+ static void deparseNumericOnly(StringInfo str, union ValUnion *value)
464
466
  {
465
467
  switch (nodeTag(value))
466
468
  {
467
469
  case T_Integer:
468
- appendStringInfo(str, "%d", value->val.ival);
470
+ appendStringInfo(str, "%d", value->ival.ival);
469
471
  break;
470
472
  case T_Float:
471
- appendStringInfoString(str, value->val.str);
473
+ appendStringInfoString(str, value->sval.sval);
472
474
  break;
473
475
  default:
474
476
  Assert(false);
@@ -482,7 +484,7 @@ static void deparseNumericOnlyList(StringInfo str, List *l)
482
484
 
483
485
  foreach(lc, l)
484
486
  {
485
- deparseNumericOnly(str, (Value *) lfirst(lc));
487
+ deparseNumericOnly(str, (union ValUnion *) lfirst(lc));
486
488
  if (lnext(l, lc))
487
489
  appendStringInfoString(str, ", ");
488
490
  }
@@ -501,25 +503,25 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
501
503
  else if (strcmp(def_elem->defname, "cache") == 0)
502
504
  {
503
505
  appendStringInfoString(str, "CACHE ");
504
- deparseNumericOnly(str, (Value *) def_elem->arg);
506
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
505
507
  }
506
- else if (strcmp(def_elem->defname, "cycle") == 0 && intVal(def_elem->arg) == 1)
508
+ else if (strcmp(def_elem->defname, "cycle") == 0 && boolVal(def_elem->arg))
507
509
  {
508
510
  appendStringInfoString(str, "CYCLE");
509
511
  }
510
- else if (strcmp(def_elem->defname, "cycle") == 0 && intVal(def_elem->arg) == 0)
512
+ else if (strcmp(def_elem->defname, "cycle") == 0 && !boolVal(def_elem->arg))
511
513
  {
512
514
  appendStringInfoString(str, "NO CYCLE");
513
515
  }
514
516
  else if (strcmp(def_elem->defname, "increment") == 0)
515
517
  {
516
518
  appendStringInfoString(str, "INCREMENT ");
517
- deparseNumericOnly(str, (Value *) def_elem->arg);
519
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
518
520
  }
519
521
  else if (strcmp(def_elem->defname, "maxvalue") == 0 && def_elem->arg != NULL)
520
522
  {
521
523
  appendStringInfoString(str, "MAXVALUE ");
522
- deparseNumericOnly(str, (Value *) def_elem->arg);
524
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
523
525
  }
524
526
  else if (strcmp(def_elem->defname, "maxvalue") == 0 && def_elem->arg == NULL)
525
527
  {
@@ -528,7 +530,7 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
528
530
  else if (strcmp(def_elem->defname, "minvalue") == 0 && def_elem->arg != NULL)
529
531
  {
530
532
  appendStringInfoString(str, "MINVALUE ");
531
- deparseNumericOnly(str, (Value *) def_elem->arg);
533
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
532
534
  }
533
535
  else if (strcmp(def_elem->defname, "minvalue") == 0 && def_elem->arg == NULL)
534
536
  {
@@ -547,7 +549,7 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
547
549
  else if (strcmp(def_elem->defname, "start") == 0)
548
550
  {
549
551
  appendStringInfoString(str, "START ");
550
- deparseNumericOnly(str, (Value *) def_elem->arg);
552
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
551
553
  }
552
554
  else if (strcmp(def_elem->defname, "restart") == 0 && def_elem->arg == NULL)
553
555
  {
@@ -556,7 +558,7 @@ static void deparseSeqOptElem(StringInfo str, DefElem *def_elem)
556
558
  else if (strcmp(def_elem->defname, "restart") == 0 && def_elem->arg != NULL)
557
559
  {
558
560
  appendStringInfoString(str, "RESTART ");
559
- deparseNumericOnly(str, (Value *) def_elem->arg);
561
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
560
562
  }
561
563
  else
562
564
  {
@@ -711,7 +713,7 @@ static void deparseDefArg(StringInfo str, Node *arg, bool is_operator_def_arg)
711
713
  }
712
714
  else if (IsA(arg, Float) || IsA(arg, Integer)) // NumericOnly
713
715
  {
714
- deparseValue(str, (Value *) arg, DEPARSE_NODE_CONTEXT_NONE);
716
+ deparseValue(str, (union ValUnion *) arg, DEPARSE_NODE_CONTEXT_NONE);
715
717
  }
716
718
  else if (IsA(arg, String))
717
719
  {
@@ -792,11 +794,11 @@ static void deparseCreateGenericOptions(StringInfo str, List *options)
792
794
  // "common_func_opt_item" in gram.y
793
795
  static void deparseCommonFuncOptItem(StringInfo str, DefElem *def_elem)
794
796
  {
795
- if (strcmp(def_elem->defname, "strict") == 0 && intVal(def_elem->arg) == 1)
797
+ if (strcmp(def_elem->defname, "strict") == 0 && boolVal(def_elem->arg))
796
798
  {
797
799
  appendStringInfoString(str, "RETURNS NULL ON NULL INPUT");
798
800
  }
799
- else if (strcmp(def_elem->defname, "strict") == 0 && intVal(def_elem->arg) == 0)
801
+ else if (strcmp(def_elem->defname, "strict") == 0 && !boolVal(def_elem->arg))
800
802
  {
801
803
  appendStringInfoString(str, "CALLED ON NULL INPUT");
802
804
  }
@@ -812,31 +814,31 @@ static void deparseCommonFuncOptItem(StringInfo str, DefElem *def_elem)
812
814
  {
813
815
  appendStringInfoString(str, "VOLATILE");
814
816
  }
815
- else if (strcmp(def_elem->defname, "security") == 0 && intVal(def_elem->arg) == 1)
817
+ else if (strcmp(def_elem->defname, "security") == 0 && boolVal(def_elem->arg))
816
818
  {
817
819
  appendStringInfoString(str, "SECURITY DEFINER");
818
820
  }
819
- else if (strcmp(def_elem->defname, "security") == 0 && intVal(def_elem->arg) == 0)
821
+ else if (strcmp(def_elem->defname, "security") == 0 && !boolVal(def_elem->arg))
820
822
  {
821
823
  appendStringInfoString(str, "SECURITY INVOKER");
822
824
  }
823
- else if (strcmp(def_elem->defname, "leakproof") == 0 && intVal(def_elem->arg) == 1)
825
+ else if (strcmp(def_elem->defname, "leakproof") == 0 && boolVal(def_elem->arg))
824
826
  {
825
827
  appendStringInfoString(str, "LEAKPROOF");
826
828
  }
827
- else if (strcmp(def_elem->defname, "leakproof") == 0 && intVal(def_elem->arg) == 0)
829
+ else if (strcmp(def_elem->defname, "leakproof") == 0 && !boolVal(def_elem->arg))
828
830
  {
829
831
  appendStringInfoString(str, "NOT LEAKPROOF");
830
832
  }
831
833
  else if (strcmp(def_elem->defname, "cost") == 0)
832
834
  {
833
835
  appendStringInfoString(str, "COST ");
834
- deparseValue(str, (Value *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
836
+ deparseValue(str, (union ValUnion *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
835
837
  }
836
838
  else if (strcmp(def_elem->defname, "rows") == 0)
837
839
  {
838
840
  appendStringInfoString(str, "ROWS ");
839
- deparseValue(str, (Value *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
841
+ deparseValue(str, (union ValUnion *) def_elem->arg, DEPARSE_NODE_CONTEXT_NONE);
840
842
  }
841
843
  else if (strcmp(def_elem->defname, "support") == 0)
842
844
  {
@@ -993,19 +995,22 @@ static void deparseFuncName(StringInfo str, List *func_name)
993
995
  static void deparseFunctionWithArgtypes(StringInfo str, ObjectWithArgs *object_with_args)
994
996
  {
995
997
  ListCell *lc;
996
-
997
998
  deparseFuncName(str, object_with_args->objname);
998
999
 
999
1000
  if (!object_with_args->args_unspecified)
1000
1001
  {
1001
1002
  appendStringInfoChar(str, '(');
1002
- foreach(lc, object_with_args->objargs)
1003
+ List *objargs = object_with_args->objargs;
1004
+ if (object_with_args->objfuncargs)
1005
+ objargs = object_with_args->objfuncargs;
1006
+
1007
+ foreach(lc, objargs)
1003
1008
  {
1004
- if (IsA(lfirst(lc), TypeName))
1005
- deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1006
- else
1009
+ if (IsA(lfirst(lc), FunctionParameter))
1007
1010
  deparseFunctionParameter(str, castNode(FunctionParameter, lfirst(lc)));
1008
- if (lnext(object_with_args->objargs, lc))
1011
+ else
1012
+ deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1013
+ if (lnext(objargs, lc))
1009
1014
  appendStringInfoString(str, ", ");
1010
1015
  }
1011
1016
  appendStringInfoChar(str, ')');
@@ -1095,16 +1100,23 @@ static void deparseAggregateWithArgtypes(StringInfo str, ObjectWithArgs *object_
1095
1100
  deparseFuncName(str, object_with_args->objname);
1096
1101
 
1097
1102
  appendStringInfoChar(str, '(');
1098
- if (object_with_args->objargs == NULL)
1103
+ if (object_with_args->objargs == NULL && object_with_args->objfuncargs == NULL)
1099
1104
  {
1100
1105
  appendStringInfoChar(str, '*');
1101
1106
  }
1102
1107
  else
1103
1108
  {
1104
- foreach(lc, object_with_args->objargs)
1109
+ List *objargs = object_with_args->objargs;
1110
+ if (object_with_args->objfuncargs)
1111
+ objargs = object_with_args->objfuncargs;
1112
+
1113
+ foreach(lc, objargs)
1105
1114
  {
1106
- deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1107
- if (lnext(object_with_args->objargs, lc))
1115
+ if (IsA(lfirst(lc), FunctionParameter))
1116
+ deparseFunctionParameter(str, castNode(FunctionParameter, lfirst(lc)));
1117
+ else
1118
+ deparseTypeName(str, castNode(TypeName, lfirst(lc)));
1119
+ if (lnext(objargs, lc))
1108
1120
  appendStringInfoString(str, ", ");
1109
1121
  }
1110
1122
  }
@@ -1235,6 +1247,64 @@ static void deparseOptBooleanOrString(StringInfo str, char *s)
1235
1247
  deparseNonReservedWordOrSconst(str, s);
1236
1248
  }
1237
1249
 
1250
+ static void deparseOptBoolean(StringInfo str, Node *node)
1251
+ {
1252
+ if (node == NULL)
1253
+ {
1254
+ return;
1255
+ }
1256
+
1257
+ switch (nodeTag(node))
1258
+ {
1259
+ case T_String:
1260
+ appendStringInfo(str, " %s", strVal(node));
1261
+ break;
1262
+ case T_Integer:
1263
+ appendStringInfo(str, " %d", intVal(node));
1264
+ break;
1265
+ case T_Boolean:
1266
+ appendStringInfo(str, " %s", boolVal(node) ? "TRUE" : "FALSE");
1267
+ break;
1268
+ default:
1269
+ Assert(false);
1270
+ break;
1271
+ }
1272
+ }
1273
+
1274
+ bool optBooleanValue(Node *node)
1275
+ {
1276
+ if (node == NULL)
1277
+ {
1278
+ return true;
1279
+ }
1280
+
1281
+ switch (nodeTag(node))
1282
+ {
1283
+ case T_String: {
1284
+ // Longest valid string is "off\0"
1285
+ char lower[4];
1286
+ strncpy(lower, strVal(node), 4);
1287
+ lower[3] = 0;
1288
+
1289
+ if (strcmp(lower, "on") == 0) {
1290
+ return true;
1291
+ } else if (strcmp(lower, "off") == 0) {
1292
+ return false;
1293
+ }
1294
+
1295
+ // No sane way to handle this.
1296
+ return false;
1297
+ }
1298
+ case T_Integer:
1299
+ return intVal(node) != 0;
1300
+ case T_Boolean:
1301
+ return boolVal(node);
1302
+ default:
1303
+ Assert(false);
1304
+ return false;
1305
+ }
1306
+ }
1307
+
1238
1308
  // "var_name"
1239
1309
  //
1240
1310
  // Note this is kept separate from ColId in case we want to improve the
@@ -1259,12 +1329,16 @@ static void deparseVarList(StringInfo str, List *l)
1259
1329
  {
1260
1330
  A_Const *a_const = castNode(A_Const, lfirst(lc));
1261
1331
  if (IsA(&a_const->val, Integer) || IsA(&a_const->val, Float))
1262
- deparseNumericOnly(str, (Value *) &a_const->val);
1332
+ deparseNumericOnly(str, (union ValUnion *) &a_const->val);
1263
1333
  else if (IsA(&a_const->val, String))
1264
1334
  deparseOptBooleanOrString(str, strVal(&a_const->val));
1265
1335
  else
1266
1336
  Assert(false);
1267
1337
  }
1338
+ else if (IsA(lfirst(lc), TypeCast))
1339
+ {
1340
+ deparseTypeCast(str, castNode(TypeCast, lfirst(lc)), DEPARSE_NODE_CONTEXT_SET_STATEMENT);
1341
+ }
1268
1342
  else
1269
1343
  {
1270
1344
  Assert(false);
@@ -1340,7 +1414,7 @@ static void deparseAlterIdentityColumnOptionList(StringInfo str, List *l)
1340
1414
  else if (strcmp(def_elem->defname, "restart") == 0 && def_elem->arg != NULL)
1341
1415
  {
1342
1416
  appendStringInfoString(str, "RESTART ");
1343
- deparseNumericOnly(str, (Value *) def_elem->arg);
1417
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
1344
1418
  }
1345
1419
  else if (strcmp(def_elem->defname, "generated") == 0)
1346
1420
  {
@@ -1710,7 +1784,7 @@ static void deparseFuncExprWindowless(StringInfo str, Node* node)
1710
1784
  deparseSQLValueFunction(str, castNode(SQLValueFunction, node));
1711
1785
  break;
1712
1786
  case T_TypeCast:
1713
- deparseTypeCast(str, castNode(TypeCast, node));
1787
+ deparseTypeCast(str, castNode(TypeCast, node), DEPARSE_NODE_CONTEXT_NONE);
1714
1788
  break;
1715
1789
  case T_CoalesceExpr:
1716
1790
  deparseCoalesceExpr(str, castNode(CoalesceExpr, node));
@@ -2010,6 +2084,38 @@ static void deparseCreatedbOptList(StringInfo str, List *l)
2010
2084
  }
2011
2085
  }
2012
2086
 
2087
+ // "utility_option_list" in gram.y
2088
+ static void deparseUtilityOptionList(StringInfo str, List *options)
2089
+ {
2090
+ ListCell *lc = NULL;
2091
+ char *defname = NULL;
2092
+
2093
+ if (list_length(options) > 0)
2094
+ {
2095
+ appendStringInfoChar(str, '(');
2096
+ foreach(lc, options)
2097
+ {
2098
+ DefElem *def_elem = castNode(DefElem, lfirst(lc));
2099
+ deparseGenericDefElemName(str, def_elem->defname);
2100
+
2101
+ if (def_elem->arg != NULL)
2102
+ {
2103
+ appendStringInfoChar(str, ' ');
2104
+ if (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float))
2105
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
2106
+ else if (IsA(def_elem->arg, String))
2107
+ deparseOptBooleanOrString(str, strVal(def_elem->arg));
2108
+ else
2109
+ Assert(false);
2110
+ }
2111
+
2112
+ if (lnext(options, lc))
2113
+ appendStringInfoString(str, ", ");
2114
+ }
2115
+ appendStringInfoString(str, ") ");
2116
+ }
2117
+ }
2118
+
2013
2119
  static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2014
2120
  {
2015
2121
  const ListCell *lc = NULL;
@@ -2074,6 +2180,8 @@ static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2074
2180
  if (list_length(stmt->groupClause) > 0)
2075
2181
  {
2076
2182
  appendStringInfoString(str, "GROUP BY ");
2183
+ if (stmt->groupDistinct)
2184
+ appendStringInfoString(str, "DISTINCT ");
2077
2185
  deparseGroupByList(str, stmt->groupClause);
2078
2186
  appendStringInfoChar(str, ' ');
2079
2187
  }
@@ -2159,7 +2267,7 @@ static void deparseSelectStmt(StringInfo str, SelectStmt *stmt)
2159
2267
  else if (stmt->limitOption == LIMIT_OPTION_WITH_TIES)
2160
2268
  appendStringInfoString(str, "FETCH FIRST ");
2161
2269
 
2162
- if (IsA(stmt->limitCount, A_Const) && IsA(&castNode(A_Const, stmt->limitCount)->val, Null))
2270
+ if (IsA(stmt->limitCount, A_Const) && castNode(A_Const, stmt->limitCount)->isnull)
2163
2271
  appendStringInfoString(str, "ALL");
2164
2272
  else
2165
2273
  deparseCExpr(str, stmt->limitCount);
@@ -2295,7 +2403,8 @@ static void deparseAlias(StringInfo str, Alias *alias)
2295
2403
 
2296
2404
  static void deparseAConst(StringInfo str, A_Const *a_const)
2297
2405
  {
2298
- deparseValue(str, &a_const->val, DEPARSE_NODE_CONTEXT_CONSTANT);
2406
+ union ValUnion *val = a_const->isnull ? NULL : &a_const->val;
2407
+ deparseValue(str, val, DEPARSE_NODE_CONTEXT_CONSTANT);
2299
2408
  }
2300
2409
 
2301
2410
  static void deparseFuncCall(StringInfo str, FuncCall *func_call)
@@ -2323,8 +2432,217 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call)
2323
2432
  deparseExpr(str, lfourth(func_call->args));
2324
2433
  appendStringInfoChar(str, ')');
2325
2434
  return;
2326
- }
2435
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2436
+ list_length(func_call->funcname) == 2 &&
2437
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2438
+ strcmp(strVal(lsecond(func_call->funcname)), "substring") == 0)
2439
+ {
2440
+ /*
2441
+ * "SUBSTRING" is a keyword on its own merit, and only accepts the
2442
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.substring)
2443
+ */
2444
+ Assert(list_length(func_call->args) == 2 || list_length(func_call->args) == 3);
2445
+ appendStringInfoString(str, "SUBSTRING(");
2446
+ deparseExpr(str, linitial(func_call->args));
2447
+ appendStringInfoString(str, " FROM ");
2448
+ deparseExpr(str, lsecond(func_call->args));
2449
+ if (list_length(func_call->args) == 3)
2450
+ {
2451
+ appendStringInfoString(str, " FOR ");
2452
+ deparseExpr(str, lthird(func_call->args));
2453
+ }
2454
+ appendStringInfoChar(str, ')');
2455
+ return;
2456
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2457
+ list_length(func_call->funcname) == 2 &&
2458
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2459
+ strcmp(strVal(lsecond(func_call->funcname)), "position") == 0 &&
2460
+ list_length(func_call->args) == 2)
2461
+ {
2462
+ /*
2463
+ * "POSITION" is a keyword on its own merit, and only accepts the
2464
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.position)
2465
+ * Note that the first and second arguments are switched in this format
2466
+ */
2467
+ appendStringInfoString(str, "POSITION(");
2468
+ deparseExpr(str, lsecond(func_call->args));
2469
+ appendStringInfoString(str, " IN ");
2470
+ deparseExpr(str, linitial(func_call->args));
2471
+ appendStringInfoChar(str, ')');
2472
+ return;
2473
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2474
+ list_length(func_call->funcname) == 2 &&
2475
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2476
+ strcmp(strVal(lsecond(func_call->funcname)), "overlay") == 0 &&
2477
+ list_length(func_call->args) == 3)
2478
+ {
2479
+ /*
2480
+ * "OVERLAY" is a keyword on its own merit, and only accepts the
2481
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
2482
+ */
2483
+ appendStringInfoString(str, "overlay(");
2484
+ deparseExpr(str, linitial(func_call->args));
2485
+ appendStringInfoString(str, " placing ");
2486
+ deparseExpr(str, lsecond(func_call->args));
2487
+ appendStringInfoString(str, " from ");
2488
+ deparseExpr(str, lthird(func_call->args));
2489
+ appendStringInfoChar(str, ')');
2490
+ return;
2491
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2492
+ list_length(func_call->funcname) == 2 &&
2493
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2494
+ strcmp(strVal(lsecond(func_call->funcname)), "pg_collation_for") == 0 &&
2495
+ list_length(func_call->args) == 1)
2496
+ {
2497
+ /*
2498
+ * "collation for" is a keyword on its own merit, and only accepts the
2499
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlay)
2500
+ */
2501
+ appendStringInfoString(str, "collation for (");
2502
+ deparseExpr(str, linitial(func_call->args));
2503
+ appendStringInfoChar(str, ')');
2504
+ return;
2505
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2506
+ list_length(func_call->funcname) == 2 &&
2507
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2508
+ strcmp(strVal(lsecond(func_call->funcname)), "extract") == 0 &&
2509
+ list_length(func_call->args) == 2)
2510
+ {
2511
+ /*
2512
+ * "EXTRACT" is a keyword on its own merit, and only accepts the
2513
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.extract)
2514
+ */
2515
+ appendStringInfoString(str, "extract (");
2516
+ deparseExpr(str, linitial(func_call->args));
2517
+ appendStringInfoString(str, " FROM ");
2518
+ deparseExpr(str, lsecond(func_call->args));
2519
+ appendStringInfoChar(str, ')');
2520
+ return;
2521
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2522
+ list_length(func_call->funcname) == 2 &&
2523
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2524
+ strcmp(strVal(lsecond(func_call->funcname)), "overlaps") == 0 &&
2525
+ list_length(func_call->args) == 4)
2526
+ {
2527
+ /*
2528
+ * "OVERLAPS" is a keyword on its own merit, and only accepts the
2529
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.overlaps)
2530
+ * format: (start_1, end_1) overlaps (start_2, end_2)
2531
+ */
2532
+ appendStringInfoChar(str, '(');
2533
+ deparseExpr(str, linitial(func_call->args));
2534
+ appendStringInfoString(str, ", ");
2535
+ deparseExpr(str, lsecond(func_call->args));
2536
+ appendStringInfoString(str, ") ");
2537
+
2538
+ appendStringInfoString(str, "overlaps ");
2539
+ appendStringInfoChar(str, '(');
2540
+ deparseExpr(str, lthird(func_call->args));
2541
+ appendStringInfoString(str, ", ");
2542
+ deparseExpr(str, lfourth(func_call->args));
2543
+ appendStringInfoString(str, ") ");
2544
+ return;
2545
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2546
+ list_length(func_call->funcname) == 2 &&
2547
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2548
+ (
2549
+ strcmp(strVal(lsecond(func_call->funcname)), "ltrim") == 0 ||
2550
+ strcmp(strVal(lsecond(func_call->funcname)), "btrim") == 0 ||
2551
+ strcmp(strVal(lsecond(func_call->funcname)), "rtrim") == 0
2552
+ ))
2553
+ {
2554
+ /*
2555
+ * "TRIM " is a keyword on its own merit, and only accepts the
2556
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.ltrim)
2557
+ * Note that the first and second arguments are switched in this format
2558
+ */
2559
+ Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2560
+ appendStringInfoString(str, "TRIM (");
2561
+ if (strcmp(strVal(lsecond(func_call->funcname)), "ltrim") == 0)
2562
+ appendStringInfoString(str, "LEADING ");
2563
+ else if (strcmp(strVal(lsecond(func_call->funcname)), "btrim") == 0)
2564
+ appendStringInfoString(str, "BOTH ");
2565
+ else if (strcmp(strVal(lsecond(func_call->funcname)), "rtrim") == 0)
2566
+ appendStringInfoString(str, "TRAILING ");
2567
+
2568
+ if (list_length(func_call->args) == 2)
2569
+ deparseExpr(str, lsecond(func_call->args));
2570
+ appendStringInfoString(str, " FROM ");
2571
+ deparseExpr(str, linitial(func_call->args));
2572
+ appendStringInfoChar(str, ')');
2573
+ return;
2574
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2575
+ list_length(func_call->funcname) == 2 &&
2576
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2577
+ strcmp(strVal(lsecond(func_call->funcname)), "timezone") == 0 &&
2578
+ list_length(func_call->args) == 2)
2579
+ {
2580
+ /*
2581
+ * "AT TIME ZONE" is a keyword on its own merit, and only accepts the
2582
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.timezone)
2583
+ * Note that the arguments are swapped in this case
2584
+ */
2585
+ deparseExpr(str, lsecond(func_call->args));
2586
+ appendStringInfoString(str, " AT TIME ZONE ");
2587
+ deparseExpr(str, linitial(func_call->args));
2588
+ return;
2589
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2590
+ list_length(func_call->funcname) == 2 &&
2591
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2592
+ strcmp(strVal(lsecond(func_call->funcname)), "normalize") == 0)
2593
+ {
2594
+ /*
2595
+ * "NORMALIZE" is a keyword on its own merit, and only accepts the
2596
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.normalize)
2597
+ */
2598
+ Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2599
+ appendStringInfoString(str, "normalize (");
2600
+
2601
+ deparseExpr(str, linitial(func_call->args));
2602
+ if (list_length(func_call->args) == 2)
2603
+ {
2604
+ appendStringInfoString(str, ", ");
2605
+ Assert(IsA(lsecond(func_call->args), A_Const));
2606
+ A_Const *aconst = lsecond(func_call->args);
2607
+ deparseValue(str, &aconst->val, DEPARSE_NODE_CONTEXT_NONE);
2608
+ }
2609
+ appendStringInfoChar(str, ')');
2610
+ return;
2611
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2612
+ list_length(func_call->funcname) == 2 &&
2613
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2614
+ strcmp(strVal(lsecond(func_call->funcname)), "is_normalized") == 0)
2615
+ {
2616
+ /*
2617
+ * "IS NORMALIZED" is a keyword on its own merit, and only accepts the
2618
+ * keyword parameter style when its called as a keyword, not as a regular function (i.e. pg_catalog.is_normalized)
2619
+ */
2620
+ Assert(list_length(func_call->args) == 1 || list_length(func_call->args) == 2);
2327
2621
 
2622
+ deparseExpr(str, linitial(func_call->args));
2623
+ appendStringInfoString(str, " IS ");
2624
+ if (list_length(func_call->args) == 2)
2625
+ {
2626
+ Assert(IsA(lsecond(func_call->args), A_Const));
2627
+ A_Const *aconst = lsecond(func_call->args);
2628
+ deparseValue(str, &aconst->val, DEPARSE_NODE_CONTEXT_NONE);
2629
+ }
2630
+ appendStringInfoString(str, " NORMALIZED ");
2631
+ return;
2632
+ } else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
2633
+ list_length(func_call->funcname) == 2 &&
2634
+ strcmp(strVal(linitial(func_call->funcname)), "pg_catalog") == 0 &&
2635
+ strcmp(strVal(lsecond(func_call->funcname)), "xmlexists") == 0 &&
2636
+ list_length(func_call->args) == 2)
2637
+ {
2638
+ appendStringInfoString(str, "xmlexists (");
2639
+ deparseExpr(str, linitial(func_call->args));
2640
+ appendStringInfoString(str, " PASSING ");
2641
+ deparseExpr(str, lsecond(func_call->args));
2642
+ appendStringInfoChar(str, ')');
2643
+ return;
2644
+ }
2645
+
2328
2646
  deparseFuncName(str, func_call->funcname);
2329
2647
  appendStringInfoChar(str, '(');
2330
2648
 
@@ -2648,31 +2966,13 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2648
2966
  deparseExpr(str, a_expr->rexpr);
2649
2967
  appendStringInfoChar(str, ')');
2650
2968
  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
2969
  case AEXPR_IN: /* [NOT] IN - name must be "=" or "<>" */
2670
2970
  Assert(list_length(a_expr->name) == 1);
2671
2971
  Assert(IsA(linitial(a_expr->name), String));
2672
2972
  Assert(IsA(a_expr->rexpr, List));
2673
2973
  deparseExpr(str, a_expr->lexpr);
2674
2974
  appendStringInfoChar(str, ' ');
2675
- name = ((Value *) linitial(a_expr->name))->val.str;
2975
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2676
2976
  if (strcmp(name, "=") == 0) {
2677
2977
  appendStringInfoString(str, "IN ");
2678
2978
  } else if (strcmp(name, "<>") == 0) {
@@ -2693,7 +2993,7 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2693
2993
  deparseExpr(str, a_expr->lexpr);
2694
2994
  appendStringInfoChar(str, ' ');
2695
2995
 
2696
- name = ((Value *) linitial(a_expr->name))->val.str;
2996
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2697
2997
  if (strcmp(name, "~~") == 0) {
2698
2998
  appendStringInfoString(str, "LIKE ");
2699
2999
  } else if (strcmp(name, "!~~") == 0) {
@@ -2710,7 +3010,7 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2710
3010
  deparseExpr(str, a_expr->lexpr);
2711
3011
  appendStringInfoChar(str, ' ');
2712
3012
 
2713
- name = ((Value *) linitial(a_expr->name))->val.str;
3013
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2714
3014
  if (strcmp(name, "~~*") == 0) {
2715
3015
  appendStringInfoString(str, "ILIKE ");
2716
3016
  } else if (strcmp(name, "!~~*") == 0) {
@@ -2727,7 +3027,7 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2727
3027
  deparseExpr(str, a_expr->lexpr);
2728
3028
  appendStringInfoChar(str, ' ');
2729
3029
 
2730
- name = ((Value *) linitial(a_expr->name))->val.str;
3030
+ name = ((union ValUnion *) linitial(a_expr->name))->sval.sval;
2731
3031
  if (strcmp(name, "~") == 0) {
2732
3032
  appendStringInfoString(str, "SIMILAR TO ");
2733
3033
  } else if (strcmp(name, "!~") == 0) {
@@ -2769,10 +3069,6 @@ static void deparseAExpr(StringInfo str, A_Expr* a_expr, DeparseNodeContext cont
2769
3069
  appendStringInfoString(str, " AND ");
2770
3070
  }
2771
3071
  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
3072
  }
2777
3073
  }
2778
3074
 
@@ -3032,6 +3328,12 @@ static void deparseJoinExpr(StringInfo str, JoinExpr *join_expr)
3032
3328
  appendStringInfoString(str, "USING (");
3033
3329
  deparseNameList(str, join_expr->usingClause);
3034
3330
  appendStringInfoString(str, ") ");
3331
+
3332
+ if (join_expr->join_using_alias)
3333
+ {
3334
+ appendStringInfoString(str, "AS ");
3335
+ appendStringInfoString(str, join_expr->join_using_alias->aliasname);
3336
+ }
3035
3337
  }
3036
3338
 
3037
3339
  if (need_alias_parens)
@@ -3043,6 +3345,49 @@ static void deparseJoinExpr(StringInfo str, JoinExpr *join_expr)
3043
3345
  removeTrailingSpace(str);
3044
3346
  }
3045
3347
 
3348
+ static void deparseCTESearchClause(StringInfo str, CTESearchClause *search_clause)
3349
+ {
3350
+ appendStringInfoString(str, " SEARCH ");
3351
+ if (search_clause->search_breadth_first)
3352
+ appendStringInfoString(str, "BREADTH ");
3353
+ else
3354
+ appendStringInfoString(str, "DEPTH ");
3355
+
3356
+ appendStringInfoString(str, "FIRST BY ");
3357
+
3358
+ if (search_clause->search_col_list)
3359
+ deparseColumnList(str, search_clause->search_col_list);
3360
+
3361
+ appendStringInfoString(str, " SET ");
3362
+ appendStringInfoString(str, quote_identifier(search_clause->search_seq_column));
3363
+ }
3364
+
3365
+ static void deparseCTECycleClause(StringInfo str, CTECycleClause *cycle_clause)
3366
+ {
3367
+ appendStringInfoString(str, " CYCLE ");
3368
+
3369
+ if (cycle_clause->cycle_col_list)
3370
+ deparseColumnList(str, cycle_clause->cycle_col_list);
3371
+
3372
+ appendStringInfoString(str, " SET ");
3373
+ appendStringInfoString(str, quote_identifier(cycle_clause->cycle_mark_column));
3374
+
3375
+ if (cycle_clause->cycle_mark_value)
3376
+ {
3377
+ appendStringInfoString(str, " TO ");
3378
+ deparseExpr(str, cycle_clause->cycle_mark_value);
3379
+ }
3380
+
3381
+ if (cycle_clause->cycle_mark_default)
3382
+ {
3383
+ appendStringInfoString(str, " DEFAULT ");
3384
+ deparseExpr(str, cycle_clause->cycle_mark_default);
3385
+ }
3386
+
3387
+ appendStringInfoString(str, " USING ");
3388
+ appendStringInfoString(str, quote_identifier(cycle_clause->cycle_path_column));
3389
+ }
3390
+
3046
3391
  static void deparseCommonTableExpr(StringInfo str, CommonTableExpr *cte)
3047
3392
  {
3048
3393
  deparseColId(str, cte->ctename);
@@ -3070,6 +3415,11 @@ static void deparseCommonTableExpr(StringInfo str, CommonTableExpr *cte)
3070
3415
  appendStringInfoChar(str, '(');
3071
3416
  deparsePreparableStmt(str, cte->ctequery);
3072
3417
  appendStringInfoChar(str, ')');
3418
+
3419
+ if (cte->search_clause)
3420
+ deparseCTESearchClause(str, cte->search_clause);
3421
+ if (cte->cycle_clause)
3422
+ deparseCTECycleClause(str, cte->cycle_clause);
3073
3423
  }
3074
3424
 
3075
3425
  static void deparseRangeSubselect(StringInfo str, RangeSubselect *range_subselect)
@@ -3174,6 +3524,7 @@ static void deparseRowExpr(StringInfo str, RowExpr *row_expr)
3174
3524
  case COERCE_EXPLICIT_CALL:
3175
3525
  appendStringInfoString(str, "ROW");
3176
3526
  break;
3527
+ case COERCE_SQL_SYNTAX:
3177
3528
  case COERCE_EXPLICIT_CAST:
3178
3529
  // Not present in raw parser output
3179
3530
  Assert(false);
@@ -3188,7 +3539,7 @@ static void deparseRowExpr(StringInfo str, RowExpr *row_expr)
3188
3539
  appendStringInfoChar(str, ')');
3189
3540
  }
3190
3541
 
3191
- static void deparseTypeCast(StringInfo str, TypeCast *type_cast)
3542
+ static void deparseTypeCast(StringInfo str, TypeCast *type_cast, DeparseNodeContext context)
3192
3543
  {
3193
3544
  bool need_parens = false;
3194
3545
 
@@ -3236,6 +3587,13 @@ static void deparseTypeCast(StringInfo str, TypeCast *type_cast)
3236
3587
  return;
3237
3588
  }
3238
3589
  }
3590
+ else if (strcmp(typename, "interval") == 0 && context == DEPARSE_NODE_CONTEXT_SET_STATEMENT && IsA(&a_const->val, String))
3591
+ {
3592
+ appendStringInfoString(str, "interval ");
3593
+ deparseAConst(str, a_const);
3594
+ deparseIntervalTypmods(str, type_cast->typeName);
3595
+ return;
3596
+ }
3239
3597
  }
3240
3598
 
3241
3599
  // Ensure negative values have wrapping parentheses
@@ -3243,8 +3601,18 @@ static void deparseTypeCast(StringInfo str, TypeCast *type_cast)
3243
3601
  {
3244
3602
  need_parens = true;
3245
3603
  }
3604
+
3605
+ if (list_length(type_cast->typeName->names) == 1 &&
3606
+ strcmp(strVal(linitial(type_cast->typeName->names)), "point") == 0 &&
3607
+ a_const->location > type_cast->typeName->location)
3608
+ {
3609
+ appendStringInfoString(str, " point ");
3610
+ deparseAConst(str, a_const);
3611
+ return;
3612
+ }
3246
3613
  }
3247
3614
 
3615
+
3248
3616
  if (need_parens)
3249
3617
  appendStringInfoChar(str, '(');
3250
3618
  deparseExpr(str, type_cast->arg);
@@ -3350,70 +3718,9 @@ static void deparseTypeName(StringInfo str, TypeName *type_name)
3350
3718
  }
3351
3719
  else if (strcmp(name, "interval") == 0 && list_length(type_name->typmods) >= 1)
3352
3720
  {
3353
- Assert(IsA(linitial(type_name->typmods), A_Const));
3354
- Assert(IsA(&castNode(A_Const, linitial(type_name->typmods))->val, Integer));
3355
-
3356
- int fields = intVal(&castNode(A_Const, linitial(type_name->typmods))->val);
3357
-
3358
3721
  appendStringInfoString(str, "interval");
3722
+ deparseIntervalTypmods(str, type_name);
3359
3723
 
3360
- // This logic is based on intervaltypmodout in timestamp.c
3361
- switch (fields)
3362
- {
3363
- case INTERVAL_MASK(YEAR):
3364
- appendStringInfoString(str, " year");
3365
- break;
3366
- case INTERVAL_MASK(MONTH):
3367
- appendStringInfoString(str, " month");
3368
- break;
3369
- case INTERVAL_MASK(DAY):
3370
- appendStringInfoString(str, " day");
3371
- break;
3372
- case INTERVAL_MASK(HOUR):
3373
- appendStringInfoString(str, " hour");
3374
- break;
3375
- case INTERVAL_MASK(MINUTE):
3376
- appendStringInfoString(str, " minute");
3377
- break;
3378
- case INTERVAL_MASK(SECOND):
3379
- appendStringInfoString(str, " second");
3380
- break;
3381
- case INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH):
3382
- appendStringInfoString(str, " year to month");
3383
- break;
3384
- case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR):
3385
- appendStringInfoString(str, " day to hour");
3386
- break;
3387
- case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
3388
- appendStringInfoString(str, " day to minute");
3389
- break;
3390
- case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
3391
- appendStringInfoString(str, " day to second");
3392
- break;
3393
- case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
3394
- appendStringInfoString(str, " hour to minute");
3395
- break;
3396
- case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
3397
- appendStringInfoString(str, " hour to second");
3398
- break;
3399
- case INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
3400
- appendStringInfoString(str, " minute to second");
3401
- break;
3402
- case INTERVAL_FULL_RANGE:
3403
- // Nothing
3404
- break;
3405
- default:
3406
- Assert(false);
3407
- break;
3408
- }
3409
-
3410
- if (list_length(type_name->typmods) == 2)
3411
- {
3412
- int precision = intVal(&castNode(A_Const, lsecond(type_name->typmods))->val);
3413
- if (precision != INTERVAL_FULL_PRECISION)
3414
- appendStringInfo(str, "(%d)", precision);
3415
- }
3416
-
3417
3724
  skip_typmods = true;
3418
3725
  }
3419
3726
  else
@@ -3459,6 +3766,79 @@ static void deparseTypeName(StringInfo str, TypeName *type_name)
3459
3766
  appendStringInfoString(str, "%type");
3460
3767
  }
3461
3768
 
3769
+ // Handle typemods for Interval types separately
3770
+ // so that they can be applied appropriately for different contexts.
3771
+ // For example, when using `SET` a query like `INTERVAL 'x' hour TO minute`
3772
+ // the `INTERVAL` keyword is specified first.
3773
+ // In all other contexts, intervals use the `'x'::interval` style.
3774
+ static void deparseIntervalTypmods(StringInfo str, TypeName *type_name)
3775
+ {
3776
+ const char *name = strVal(lsecond(type_name->names));
3777
+ Assert(strcmp(name, "interval") == 0);
3778
+ Assert(list_length(type_name->typmods) >= 1);
3779
+ Assert(IsA(linitial(type_name->typmods), A_Const));
3780
+ Assert(IsA(&castNode(A_Const, linitial(type_name->typmods))->val, Integer));
3781
+
3782
+ int fields = intVal(&castNode(A_Const, linitial(type_name->typmods))->val);
3783
+
3784
+ // This logic is based on intervaltypmodout in timestamp.c
3785
+ switch (fields)
3786
+ {
3787
+ case INTERVAL_MASK(YEAR):
3788
+ appendStringInfoString(str, " year");
3789
+ break;
3790
+ case INTERVAL_MASK(MONTH):
3791
+ appendStringInfoString(str, " month");
3792
+ break;
3793
+ case INTERVAL_MASK(DAY):
3794
+ appendStringInfoString(str, " day");
3795
+ break;
3796
+ case INTERVAL_MASK(HOUR):
3797
+ appendStringInfoString(str, " hour");
3798
+ break;
3799
+ case INTERVAL_MASK(MINUTE):
3800
+ appendStringInfoString(str, " minute");
3801
+ break;
3802
+ case INTERVAL_MASK(SECOND):
3803
+ appendStringInfoString(str, " second");
3804
+ break;
3805
+ case INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH):
3806
+ appendStringInfoString(str, " year to month");
3807
+ break;
3808
+ case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR):
3809
+ appendStringInfoString(str, " day to hour");
3810
+ break;
3811
+ case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
3812
+ appendStringInfoString(str, " day to minute");
3813
+ break;
3814
+ case INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
3815
+ appendStringInfoString(str, " day to second");
3816
+ break;
3817
+ case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE):
3818
+ appendStringInfoString(str, " hour to minute");
3819
+ break;
3820
+ case INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
3821
+ appendStringInfoString(str, " hour to second");
3822
+ break;
3823
+ case INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND):
3824
+ appendStringInfoString(str, " minute to second");
3825
+ break;
3826
+ case INTERVAL_FULL_RANGE:
3827
+ // Nothing
3828
+ break;
3829
+ default:
3830
+ Assert(false);
3831
+ break;
3832
+ }
3833
+
3834
+ if (list_length(type_name->typmods) == 2)
3835
+ {
3836
+ int precision = intVal(&castNode(A_Const, lsecond(type_name->typmods))->val);
3837
+ if (precision != INTERVAL_FULL_PRECISION)
3838
+ appendStringInfo(str, "(%d)", precision);
3839
+ }
3840
+ }
3841
+
3462
3842
  static void deparseNullTest(StringInfo str, NullTest *null_test)
3463
3843
  {
3464
3844
  // argisrow is always false in raw parser output
@@ -3602,7 +3982,7 @@ static void deparseColumnDef(StringInfo str, ColumnDef *column_def)
3602
3982
 
3603
3983
  if (column_def->colname != NULL)
3604
3984
  {
3605
- appendStringInfoString(str, column_def->colname);
3985
+ appendStringInfoString(str, quote_identifier(column_def->colname));
3606
3986
  appendStringInfoChar(str, ' ');
3607
3987
  }
3608
3988
 
@@ -3639,6 +4019,22 @@ static void deparseColumnDef(StringInfo str, ColumnDef *column_def)
3639
4019
  removeTrailingSpace(str);
3640
4020
  }
3641
4021
 
4022
+ static void deparseInsertOverride(StringInfo str, OverridingKind override)
4023
+ {
4024
+ switch (override)
4025
+ {
4026
+ case OVERRIDING_NOT_SET:
4027
+ // Do nothing
4028
+ break;
4029
+ case OVERRIDING_USER_VALUE:
4030
+ appendStringInfoString(str, "OVERRIDING USER VALUE ");
4031
+ break;
4032
+ case OVERRIDING_SYSTEM_VALUE:
4033
+ appendStringInfoString(str, "OVERRIDING SYSTEM VALUE ");
4034
+ break;
4035
+ }
4036
+ }
4037
+
3642
4038
  static void deparseInsertStmt(StringInfo str, InsertStmt *insert_stmt)
3643
4039
  {
3644
4040
  ListCell *lc;
@@ -3661,18 +4057,7 @@ static void deparseInsertStmt(StringInfo str, InsertStmt *insert_stmt)
3661
4057
  appendStringInfoString(str, ") ");
3662
4058
  }
3663
4059
 
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
- }
4060
+ deparseInsertOverride(str, insert_stmt->override);
3676
4061
 
3677
4062
  if (insert_stmt->selectStmt != NULL)
3678
4063
  {
@@ -3799,6 +4184,90 @@ static void deparseUpdateStmt(StringInfo str, UpdateStmt *update_stmt)
3799
4184
  removeTrailingSpace(str);
3800
4185
  }
3801
4186
 
4187
+ static void deparseMergeStmt(StringInfo str, MergeStmt *merge_stmt)
4188
+ {
4189
+ if (merge_stmt->withClause != NULL)
4190
+ {
4191
+ deparseWithClause(str, merge_stmt->withClause);
4192
+ appendStringInfoChar(str, ' ');
4193
+ }
4194
+
4195
+ appendStringInfoString(str, "MERGE INTO ");
4196
+ deparseRangeVar(str, merge_stmt->relation, DEPARSE_NODE_CONTEXT_NONE);
4197
+ appendStringInfoChar(str, ' ');
4198
+
4199
+ appendStringInfoString(str, "USING ");
4200
+ deparseTableRef(str, merge_stmt->sourceRelation);
4201
+ appendStringInfoChar(str, ' ');
4202
+
4203
+ appendStringInfoString(str, "ON ");
4204
+ deparseExpr(str, merge_stmt->joinCondition);
4205
+ appendStringInfoChar(str, ' ');
4206
+
4207
+ ListCell *lc, *lc2;
4208
+ foreach (lc, merge_stmt->mergeWhenClauses)
4209
+ {
4210
+ MergeWhenClause *clause = castNode(MergeWhenClause, lfirst(lc));
4211
+
4212
+ appendStringInfoString(str, "WHEN ");
4213
+
4214
+ if (!clause->matched)
4215
+ {
4216
+ appendStringInfoString(str, "NOT ");
4217
+ }
4218
+
4219
+ appendStringInfoString(str, "MATCHED ");
4220
+
4221
+ if (clause->condition)
4222
+ {
4223
+ appendStringInfoString(str, "AND ");
4224
+ deparseExpr(str, clause->condition);
4225
+ appendStringInfoChar(str, ' ');
4226
+ }
4227
+
4228
+ appendStringInfoString(str, "THEN ");
4229
+
4230
+ switch (clause->commandType) {
4231
+ case CMD_INSERT:
4232
+ appendStringInfoString(str, "INSERT ");
4233
+
4234
+ if (clause->targetList) {
4235
+ appendStringInfoChar(str, '(');
4236
+ deparseInsertColumnList(str, clause->targetList);
4237
+ appendStringInfoString(str, ") ");
4238
+ }
4239
+
4240
+ deparseInsertOverride(str, clause->override);
4241
+
4242
+ if (clause->values) {
4243
+ appendStringInfoString(str, "VALUES (");
4244
+ deparseExprList(str, clause->values);
4245
+ appendStringInfoString(str, ")");
4246
+ } else {
4247
+ appendStringInfoString(str, "DEFAULT VALUES ");
4248
+ }
4249
+
4250
+ break;
4251
+ case CMD_UPDATE:
4252
+ appendStringInfoString(str, "UPDATE SET ");
4253
+ deparseSetClauseList(str, clause->targetList);
4254
+ break;
4255
+ case CMD_DELETE:
4256
+ appendStringInfoString(str, "DELETE");
4257
+ break;
4258
+ case CMD_NOTHING:
4259
+ appendStringInfoString(str, "DO NOTHING");
4260
+ break;
4261
+ default:
4262
+ elog(ERROR, "deparse: unpermitted command type in merge statement: %d", clause->commandType);
4263
+ break;
4264
+ }
4265
+
4266
+ if (lfirst(lc) != llast(merge_stmt->mergeWhenClauses))
4267
+ appendStringInfoChar(str, ' ');
4268
+ }
4269
+ }
4270
+
3802
4271
  static void deparseDeleteStmt(StringInfo str, DeleteStmt *delete_stmt)
3803
4272
  {
3804
4273
  if (delete_stmt->withClause != NULL)
@@ -3914,6 +4383,10 @@ static void deparseCreateCastStmt(StringInfo str, CreateCastStmt *create_cast_st
3914
4383
  case COERCION_ASSIGNMENT:
3915
4384
  appendStringInfoString(str, "AS ASSIGNMENT");
3916
4385
  break;
4386
+ case COERCION_PLPGSQL:
4387
+ // Not present in raw parser output
4388
+ Assert(false);
4389
+ break;
3917
4390
  case COERCION_EXPLICIT:
3918
4391
  // Default
3919
4392
  break;
@@ -4294,10 +4767,24 @@ static void deparseConstraint(StringInfo str, Constraint *constraint)
4294
4767
  appendStringInfoString(str, "ON DELETE CASCADE ");
4295
4768
  break;
4296
4769
  case FKCONSTR_ACTION_SETNULL:
4297
- appendStringInfoString(str, "ON DELETE SET NULL ");
4298
- break;
4299
4770
  case FKCONSTR_ACTION_SETDEFAULT:
4300
- appendStringInfoString(str, "ON DELETE SET DEFAULT ");
4771
+ appendStringInfoString(str, "ON DELETE SET ");
4772
+
4773
+ switch (constraint->fk_del_action) {
4774
+ case FKCONSTR_ACTION_SETDEFAULT: appendStringInfoString(str, "DEFAULT "); break;
4775
+ case FKCONSTR_ACTION_SETNULL: appendStringInfoString(str, "NULL "); break;
4776
+ }
4777
+
4778
+ if (constraint->fk_del_set_cols) {
4779
+ appendStringInfoString(str, "(");
4780
+ ListCell *lc;
4781
+ foreach (lc, constraint->fk_del_set_cols) {
4782
+ appendStringInfoString(str, strVal(lfirst(lc)));
4783
+ if (lfirst(lc) != llast(constraint->fk_del_set_cols))
4784
+ appendStringInfoString(str, ", ");
4785
+ }
4786
+ appendStringInfoString(str, ")");
4787
+ }
4301
4788
  break;
4302
4789
  default:
4303
4790
  // Not specified
@@ -4332,6 +4819,12 @@ static void deparseConstraint(StringInfo str, Constraint *constraint)
4332
4819
  removeTrailingSpace(str);
4333
4820
  }
4334
4821
 
4822
+ static void deparseReturnStmt(StringInfo str, ReturnStmt *return_stmt)
4823
+ {
4824
+ appendStringInfoString(str, "RETURN ");
4825
+ deparseExpr(str, return_stmt->returnval);
4826
+ }
4827
+
4335
4828
  static void deparseCreateFunctionStmt(StringInfo str, CreateFunctionStmt *create_function_stmt)
4336
4829
  {
4337
4830
  ListCell *lc;
@@ -4392,6 +4885,20 @@ static void deparseCreateFunctionStmt(StringInfo str, CreateFunctionStmt *create
4392
4885
  appendStringInfoChar(str, ' ');
4393
4886
  }
4394
4887
 
4888
+ if (create_function_stmt->sql_body)
4889
+ {
4890
+ /* RETURN or BEGIN ... END
4891
+ */
4892
+ if (IsA(create_function_stmt->sql_body, ReturnStmt))
4893
+ deparseReturnStmt(str, castNode(ReturnStmt, create_function_stmt->sql_body));
4894
+ else
4895
+ {
4896
+ appendStringInfoString(str, "BEGIN ATOMIC ");
4897
+ deparseExprList(str, castNode(List, create_function_stmt->sql_body));
4898
+ appendStringInfoString(str, "END ");
4899
+ }
4900
+ }
4901
+
4395
4902
  removeTrailingSpace(str);
4396
4903
  }
4397
4904
 
@@ -4400,7 +4907,7 @@ static void deparseFunctionParameter(StringInfo str, FunctionParameter *function
4400
4907
  switch (function_parameter->mode)
4401
4908
  {
4402
4909
  case FUNC_PARAM_IN: /* input only */
4403
- // Default
4910
+ appendStringInfoString(str, "IN ");
4404
4911
  break;
4405
4912
  case FUNC_PARAM_OUT: /* output only */
4406
4913
  appendStringInfoString(str, "OUT ");
@@ -4415,6 +4922,9 @@ static void deparseFunctionParameter(StringInfo str, FunctionParameter *function
4415
4922
  // No special annotation, the caller is expected to correctly put
4416
4923
  // this into the RETURNS part of the CREATE FUNCTION statement
4417
4924
  break;
4925
+ case FUNC_PARAM_DEFAULT:
4926
+ // Default
4927
+ break;
4418
4928
  default:
4419
4929
  Assert(false);
4420
4930
  break;
@@ -4446,7 +4956,6 @@ static void deparseCheckPointStmt(StringInfo str, CheckPointStmt *check_point_st
4446
4956
  static void deparseCreateSchemaStmt(StringInfo str, CreateSchemaStmt *create_schema_stmt)
4447
4957
  {
4448
4958
  ListCell *lc;
4449
-
4450
4959
  appendStringInfoString(str, "CREATE SCHEMA ");
4451
4960
 
4452
4961
  if (create_schema_stmt->if_not_exists)
@@ -4465,11 +4974,14 @@ static void deparseCreateSchemaStmt(StringInfo str, CreateSchemaStmt *create_sch
4465
4974
  appendStringInfoChar(str, ' ');
4466
4975
  }
4467
4976
 
4468
- foreach(lc, create_schema_stmt->schemaElts)
4977
+ if (create_schema_stmt->schemaElts)
4469
4978
  {
4470
- deparseSchemaStmt(str, lfirst(lc));
4471
- if (lnext(create_schema_stmt->schemaElts, lc))
4472
- appendStringInfoChar(str, ' ');
4979
+ foreach(lc, create_schema_stmt->schemaElts)
4980
+ {
4981
+ deparseSchemaStmt(str, lfirst(lc));
4982
+ if (lnext(create_schema_stmt->schemaElts, lc))
4983
+ appendStringInfoChar(str, ' ');
4984
+ }
4473
4985
  }
4474
4986
 
4475
4987
  removeTrailingSpace(str);
@@ -4523,6 +5035,9 @@ static void deparseRoleSpec(StringInfo str, RoleSpec *role_spec)
4523
5035
  Assert(role_spec->rolename != NULL);
4524
5036
  appendStringInfoString(str, quote_identifier(role_spec->rolename));
4525
5037
  break;
5038
+ case ROLESPEC_CURRENT_ROLE:
5039
+ appendStringInfoString(str, "CURRENT_ROLE");
5040
+ break;
4526
5041
  case ROLESPEC_CURRENT_USER:
4527
5042
  appendStringInfoString(str, "CURRENT_USER");
4528
5043
  break;
@@ -4619,6 +5134,8 @@ static void deparsePartitionCmd(StringInfo str, PartitionCmd *partition_cmd)
4619
5134
  appendStringInfoChar(str, ' ');
4620
5135
  deparsePartitionBoundSpec(str, partition_cmd->bound);
4621
5136
  }
5137
+ if (partition_cmd->concurrent)
5138
+ appendStringInfoString(str, " CONCURRENTLY ");
4622
5139
  }
4623
5140
 
4624
5141
  // "TableElement" in gram.y
@@ -4983,7 +5500,7 @@ static void deparseSecLabelStmt(StringInfo str, SecLabelStmt *sec_label_stmt)
4983
5500
  break;
4984
5501
  case OBJECT_LARGEOBJECT:
4985
5502
  appendStringInfoString(str, "LARGE OBJECT ");
4986
- deparseValue(str, (Value *) sec_label_stmt->object, DEPARSE_NODE_CONTEXT_CONSTANT);
5503
+ deparseValue(str, (union ValUnion *) sec_label_stmt->object, DEPARSE_NODE_CONTEXT_CONSTANT);
4987
5504
  break;
4988
5505
  case OBJECT_PROCEDURE:
4989
5506
  appendStringInfoString(str, "PROCEDURE ");
@@ -5067,7 +5584,7 @@ static void deparseCreateTableAsStmt(StringInfo str, CreateTableAsStmt *create_t
5067
5584
 
5068
5585
  deparseOptTemp(str, create_table_as_stmt->into->rel->relpersistence);
5069
5586
 
5070
- switch (create_table_as_stmt->relkind)
5587
+ switch (create_table_as_stmt->objtype)
5071
5588
  {
5072
5589
  case OBJECT_TABLE:
5073
5590
  appendStringInfoString(str, "TABLE ");
@@ -5340,7 +5857,7 @@ static void deparseDropStmt(StringInfo str, DropStmt *drop_stmt)
5340
5857
  appendStringInfoChar(str, ' ');
5341
5858
  break;
5342
5859
  case OBJECT_LANGUAGE:
5343
- deparseStringLiteral(str, strVal(linitial(drop_stmt->objects)));
5860
+ deparseNameList(str, drop_stmt->objects);
5344
5861
  appendStringInfoChar(str, ' ');
5345
5862
  break;
5346
5863
  case OBJECT_TYPE:
@@ -5471,8 +5988,7 @@ static void deparseAlterObjectDependsStmt(StringInfo str, AlterObjectDependsStmt
5471
5988
  if (alter_object_depends_stmt->remove)
5472
5989
  appendStringInfoString(str, "NO ");
5473
5990
 
5474
- appendStringInfoString(str, "DEPENDS ON EXTENSION ");
5475
- deparseColId(str, strVal(alter_object_depends_stmt->extname));
5991
+ appendStringInfo(str, "DEPENDS ON EXTENSION %s", alter_object_depends_stmt->extname->sval);
5476
5992
  }
5477
5993
 
5478
5994
  static void deparseAlterObjectSchemaStmt(StringInfo str, AlterObjectSchemaStmt *alter_object_schema_stmt)
@@ -5662,6 +6178,10 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5662
6178
  appendStringInfoString(str, "ALTER COLUMN ");
5663
6179
  options = "SET STORAGE";
5664
6180
  break;
6181
+ case AT_SetCompression: /* alter column set compression */
6182
+ appendStringInfoString(str, "ALTER COLUMN ");
6183
+ options = "SET COMPRESSION";
6184
+ break;
5665
6185
  case AT_DropColumn: /* drop column */
5666
6186
  if (context == DEPARSE_NODE_CONTEXT_ALTER_TYPE)
5667
6187
  appendStringInfoString(str, "DROP ATTRIBUTE ");
@@ -5709,6 +6229,7 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5709
6229
  Assert(false);
5710
6230
  break;
5711
6231
  case AT_ReAddComment: /* internal to commands/tablecmds.c */
6232
+ case AT_ReAddStatistics: /* internal to commands/tablecmds.c */
5712
6233
  Assert(false);
5713
6234
  break;
5714
6235
  case AT_AlterColumnType: /* alter column type */
@@ -5747,6 +6268,9 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5747
6268
  case AT_SetRelOptions: /* SET (...) -- AM specific parameters */
5748
6269
  appendStringInfoString(str, "SET ");
5749
6270
  break;
6271
+ case AT_SetAccessMethod:
6272
+ appendStringInfo(str, "SET ACCESS METHOD ");
6273
+ break;
5750
6274
  case AT_ResetRelOptions: /* RESET (...) -- AM specific parameters */
5751
6275
  appendStringInfoString(str, "RESET ");
5752
6276
  break;
@@ -5826,6 +6350,9 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5826
6350
  case AT_DetachPartition: /* DETACH PARTITION */
5827
6351
  appendStringInfoString(str, "DETACH PARTITION ");
5828
6352
  break;
6353
+ case AT_DetachPartitionFinalize: /* DETACH PARTITION FINALIZE */
6354
+ appendStringInfoString(str, "DETACH PARTITION ");
6355
+ break;
5829
6356
  case AT_AddIdentity: /* ADD IDENTITY */
5830
6357
  appendStringInfoString(str, "ALTER ");
5831
6358
  options = "ADD";
@@ -5874,6 +6401,10 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5874
6401
  deparsePartitionCmd(str, castNode(PartitionCmd, alter_table_cmd->def));
5875
6402
  appendStringInfoChar(str, ' ');
5876
6403
  break;
6404
+ case AT_DetachPartitionFinalize:
6405
+ deparsePartitionCmd(str, castNode(PartitionCmd, alter_table_cmd->def));
6406
+ appendStringInfoString(str, "FINALIZE ");
6407
+ break;
5877
6408
  case AT_AddColumn:
5878
6409
  case AT_AlterColumnType:
5879
6410
  deparseColumnDef(str, castNode(ColumnDef, alter_table_cmd->def));
@@ -5901,6 +6432,13 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5901
6432
  deparseColId(str, strVal(alter_table_cmd->def));
5902
6433
  appendStringInfoChar(str, ' ');
5903
6434
  break;
6435
+ case AT_SetCompression:
6436
+ if (strcmp(strVal(alter_table_cmd->def), "default") == 0)
6437
+ appendStringInfoString(str, "DEFAULT");
6438
+ else
6439
+ deparseColId(str, strVal(alter_table_cmd->def));
6440
+ appendStringInfoChar(str, ' ');
6441
+ break;
5904
6442
  case AT_AddIdentity:
5905
6443
  case AT_AddConstraint:
5906
6444
  case AT_AlterConstraint:
@@ -5939,14 +6477,9 @@ static void deparseAlterTableCmd(StringInfo str, AlterTableCmd *alter_table_cmd,
5939
6477
  removeTrailingSpace(str);
5940
6478
  }
5941
6479
 
5942
- static void deparseAlterTableStmt(StringInfo str, AlterTableStmt *alter_table_stmt)
6480
+ static DeparseNodeContext deparseAlterTableObjType(StringInfo str, ObjectType type)
5943
6481
  {
5944
- ListCell *lc;
5945
- DeparseNodeContext context = DEPARSE_NODE_CONTEXT_NONE;
5946
-
5947
- appendStringInfoString(str, "ALTER ");
5948
-
5949
- switch (alter_table_stmt->relkind)
6482
+ switch (type)
5950
6483
  {
5951
6484
  case OBJECT_TABLE:
5952
6485
  appendStringInfoString(str, "TABLE ");
@@ -5968,13 +6501,49 @@ static void deparseAlterTableStmt(StringInfo str, AlterTableStmt *alter_table_st
5968
6501
  break;
5969
6502
  case OBJECT_TYPE:
5970
6503
  appendStringInfoString(str, "TYPE ");
5971
- context = DEPARSE_NODE_CONTEXT_ALTER_TYPE;
6504
+ return DEPARSE_NODE_CONTEXT_ALTER_TYPE;
5972
6505
  break;
5973
6506
  default:
5974
6507
  Assert(false);
5975
6508
  break;
5976
6509
  }
5977
6510
 
6511
+ return DEPARSE_NODE_CONTEXT_NONE;
6512
+ }
6513
+
6514
+ static void deparseAlterTableMoveAllStmt(StringInfo str, AlterTableMoveAllStmt *move_all_stmt)
6515
+ {
6516
+ appendStringInfoString(str, "ALTER ");
6517
+ deparseAlterTableObjType(str, move_all_stmt->objtype);
6518
+
6519
+ appendStringInfoString(str, "ALL IN TABLESPACE ");
6520
+ appendStringInfoString(str, move_all_stmt->orig_tablespacename);
6521
+ appendStringInfoChar(str, ' ');
6522
+
6523
+ if (move_all_stmt->roles)
6524
+ {
6525
+ appendStringInfoString(str, "OWNED BY ");
6526
+ deparseRoleList(str, move_all_stmt->roles);
6527
+ appendStringInfoChar(str, ' ');
6528
+ }
6529
+
6530
+ appendStringInfoString(str, "SET TABLESPACE ");
6531
+ appendStringInfoString(str, move_all_stmt->new_tablespacename);
6532
+ appendStringInfoChar(str, ' ');
6533
+
6534
+ if (move_all_stmt->nowait)
6535
+ {
6536
+ appendStringInfoString(str, "NOWAIT");
6537
+ }
6538
+ }
6539
+
6540
+ static void deparseAlterTableStmt(StringInfo str, AlterTableStmt *alter_table_stmt)
6541
+ {
6542
+ ListCell *lc;
6543
+
6544
+ appendStringInfoString(str, "ALTER ");
6545
+ DeparseNodeContext context = deparseAlterTableObjType(str, alter_table_stmt->objtype);
6546
+
5978
6547
  if (alter_table_stmt->missing_ok)
5979
6548
  appendStringInfoString(str, "IF EXISTS ");
5980
6549
 
@@ -6354,6 +6923,22 @@ static void deparseTransactionStmt(StringInfo str, TransactionStmt *transaction_
6354
6923
  removeTrailingSpace(str);
6355
6924
  }
6356
6925
 
6926
+ // Determine if we hit SET TIME ZONE INTERVAL, that has special syntax not
6927
+ // supported for other SET statements
6928
+ static bool isSetTimeZoneInterval(VariableSetStmt* stmt)
6929
+ {
6930
+ if (!(strcmp(stmt->name, "timezone") == 0 &&
6931
+ list_length(stmt->args) == 1 &&
6932
+ IsA(linitial(stmt->args), TypeCast)))
6933
+ return false;
6934
+
6935
+ TypeName* typeName = castNode(TypeCast, linitial(stmt->args))->typeName;
6936
+
6937
+ return (list_length(typeName->names) == 2 &&
6938
+ strcmp(strVal(linitial(typeName->names)), "pg_catalog") == 0 &&
6939
+ strcmp(strVal(llast(typeName->names)), "interval") == 0);
6940
+ }
6941
+
6357
6942
  static void deparseVariableSetStmt(StringInfo str, VariableSetStmt* variable_set_stmt)
6358
6943
  {
6359
6944
  ListCell *lc;
@@ -6364,9 +6949,17 @@ static void deparseVariableSetStmt(StringInfo str, VariableSetStmt* variable_set
6364
6949
  appendStringInfoString(str, "SET ");
6365
6950
  if (variable_set_stmt->is_local)
6366
6951
  appendStringInfoString(str, "LOCAL ");
6367
- deparseVarName(str, variable_set_stmt->name);
6368
- appendStringInfoString(str, " TO ");
6369
- deparseVarList(str, variable_set_stmt->args);
6952
+ if (isSetTimeZoneInterval(variable_set_stmt))
6953
+ {
6954
+ appendStringInfoString(str, "TIME ZONE ");
6955
+ deparseVarList(str, variable_set_stmt->args);
6956
+ }
6957
+ else
6958
+ {
6959
+ deparseVarName(str, variable_set_stmt->name);
6960
+ appendStringInfoString(str, " TO ");
6961
+ deparseVarList(str, variable_set_stmt->args);
6962
+ }
6370
6963
  break;
6371
6964
  case VAR_SET_DEFAULT: /* SET var TO DEFAULT */
6372
6965
  appendStringInfoString(str, "SET ");
@@ -6458,28 +7051,7 @@ static void deparseVacuumStmt(StringInfo str, VacuumStmt *vacuum_stmt)
6458
7051
  else
6459
7052
  appendStringInfoString(str, "ANALYZE ");
6460
7053
 
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
- }
7054
+ deparseUtilityOptionList(str, vacuum_stmt->options);
6483
7055
 
6484
7056
  foreach(lc, vacuum_stmt->rels)
6485
7057
  {
@@ -6590,31 +7162,7 @@ static void deparseExplainStmt(StringInfo str, ExplainStmt *explain_stmt)
6590
7162
 
6591
7163
  appendStringInfoString(str, "EXPLAIN ");
6592
7164
 
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
- }
7165
+ deparseUtilityOptionList(str, explain_stmt->options);
6618
7166
 
6619
7167
  deparseExplainableStmt(str, explain_stmt->query);
6620
7168
  }
@@ -6668,130 +7216,194 @@ static void deparseCopyStmt(StringInfo str, CopyStmt *copy_stmt)
6668
7216
 
6669
7217
  if (list_length(copy_stmt->options) > 0)
6670
7218
  {
6671
- appendStringInfoString(str, "WITH (");
7219
+ // In some cases, equivalent expressions may have slightly different parse trees for `COPY`
7220
+ // statements. For example the following two statements result in different (but equivalent) parse
7221
+ // trees:
7222
+ //
7223
+ // - COPY foo FROM STDIN CSV FREEZE
7224
+ // - COPY foo FROM STDIN WITH (FORMAT CSV, FREEZE)
7225
+ //
7226
+ // In order to make sure we deparse to the "correct" version, we always try to deparse to the older
7227
+ // compact syntax first.
7228
+ //
7229
+ // The old syntax can be seen here in the Postgres 8.4 Reference:
7230
+ // https://www.postgresql.org/docs/8.4/sql-copy.html
7231
+
7232
+ bool old_fmt = true;
7233
+
7234
+ // Loop over the options to see if any require the new `WITH (...)` syntax.
6672
7235
  foreach(lc, copy_stmt->options)
6673
7236
  {
6674
7237
  DefElem *def_elem = castNode(DefElem, lfirst(lc));
6675
7238
 
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)
7239
+ if (strcmp(def_elem->defname, "freeze") == 0 && optBooleanValue(def_elem->arg))
7240
+ {}
7241
+ else if (strcmp(def_elem->defname, "header") == 0 && def_elem->arg && optBooleanValue(def_elem->arg))
7242
+ {}
7243
+ else if (strcmp(def_elem->defname, "format") == 0 && strcmp(strVal(def_elem->arg), "csv") == 0)
7244
+ {}
7245
+ else if (strcmp(def_elem->defname, "force_quote") == 0 && def_elem->arg && nodeTag(def_elem->arg) == T_List)
7246
+ {}
7247
+ else
6716
7248
  {
6717
- appendStringInfoString(str, "ESCAPE ");
6718
- deparseStringLiteral(str, strVal(def_elem->arg));
7249
+ old_fmt = false;
7250
+ break;
6719
7251
  }
6720
- else if (strcmp(def_elem->defname, "force_quote") == 0)
7252
+ }
7253
+
7254
+ // Branch to differing output modes, depending on if we can use the old syntax.
7255
+ if (old_fmt) {
7256
+ foreach(lc, copy_stmt->options)
6721
7257
  {
6722
- appendStringInfoString(str, "FORCE_QUOTE ");
6723
- if (IsA(def_elem->arg, A_Star))
7258
+ DefElem *def_elem = castNode(DefElem, lfirst(lc));
7259
+
7260
+ if (strcmp(def_elem->defname, "freeze") == 0 && optBooleanValue(def_elem->arg))
6724
7261
  {
6725
- appendStringInfoChar(str, '*');
7262
+ appendStringInfoString(str, "FREEZE ");
6726
7263
  }
6727
- else if (IsA(def_elem->arg, List))
7264
+ else if (strcmp(def_elem->defname, "header") == 0 && def_elem->arg && optBooleanValue(def_elem->arg))
6728
7265
  {
6729
- appendStringInfoChar(str, '(');
7266
+ appendStringInfoString(str, "HEADER ");
7267
+ }
7268
+ else if (strcmp(def_elem->defname, "format") == 0 && strcmp(strVal(def_elem->arg), "csv") == 0)
7269
+ {
7270
+ appendStringInfoString(str, "CSV ");
7271
+ }
7272
+ else if (strcmp(def_elem->defname, "force_quote") == 0 && def_elem->arg && nodeTag(def_elem->arg) == T_List)
7273
+ {
7274
+ appendStringInfoString(str, "FORCE QUOTE ");
6730
7275
  deparseColumnList(str, castNode(List, def_elem->arg));
6731
- appendStringInfoChar(str, ')');
6732
7276
  }
6733
7277
  else
6734
7278
  {
7279
+ // This isn't reachable, the conditions here are exactly the same as the first loop above.
6735
7280
  Assert(false);
6736
7281
  }
6737
7282
  }
6738
- else if (strcmp(def_elem->defname, "force_not_null") == 0)
6739
- {
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
7283
+ } else {
7284
+ appendStringInfoString(str, "WITH (");
7285
+ foreach(lc, copy_stmt->options)
6756
7286
  {
6757
- appendStringInfoString(str, quote_identifier(def_elem->defname));
6758
- if (def_elem->arg != NULL)
6759
- appendStringInfoChar(str, ' ');
6760
-
6761
- if (def_elem->arg == NULL)
7287
+ DefElem *def_elem = castNode(DefElem, lfirst(lc));
7288
+
7289
+ if (strcmp(def_elem->defname, "format") == 0)
7290
+ {
7291
+ appendStringInfoString(str, "FORMAT ");
7292
+
7293
+ char *format = strVal(def_elem->arg);
7294
+ if (strcmp(format, "binary") == 0)
7295
+ appendStringInfoString(str, "BINARY");
7296
+ else if (strcmp(format, "csv") == 0)
7297
+ appendStringInfoString(str, "CSV");
7298
+ else
7299
+ Assert(false);
7300
+ }
7301
+ else if (strcmp(def_elem->defname, "freeze") == 0)
6762
7302
  {
6763
- // Nothing
7303
+ appendStringInfoString(str, "FREEZE");
7304
+ deparseOptBoolean(str, def_elem->arg);
6764
7305
  }
6765
- else if (IsA(def_elem->arg, String))
7306
+ else if (strcmp(def_elem->defname, "delimiter") == 0)
6766
7307
  {
6767
- deparseOptBooleanOrString(str, strVal(def_elem->arg));
7308
+ appendStringInfoString(str, "DELIMITER ");
7309
+ deparseStringLiteral(str, strVal(def_elem->arg));
6768
7310
  }
6769
- else if (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float))
7311
+ else if (strcmp(def_elem->defname, "null") == 0)
6770
7312
  {
6771
- deparseNumericOnly(str, (Value *) def_elem->arg);
7313
+ appendStringInfoString(str, "NULL ");
7314
+ deparseStringLiteral(str, strVal(def_elem->arg));
6772
7315
  }
6773
- else if (IsA(def_elem->arg, A_Star))
7316
+ else if (strcmp(def_elem->defname, "header") == 0)
6774
7317
  {
6775
- deparseAStar(str, castNode(A_Star, def_elem->arg));
7318
+ appendStringInfoString(str, "HEADER");
7319
+ deparseOptBoolean(str, def_elem->arg);
6776
7320
  }
6777
- else if (IsA(def_elem->arg, List))
7321
+ else if (strcmp(def_elem->defname, "quote") == 0)
6778
7322
  {
6779
- List *l = castNode(List, def_elem->arg);
6780
- appendStringInfoChar(str, '(');
6781
- foreach(lc2, l)
7323
+ appendStringInfoString(str, "QUOTE ");
7324
+ deparseStringLiteral(str, strVal(def_elem->arg));
7325
+ }
7326
+ else if (strcmp(def_elem->defname, "escape") == 0)
7327
+ {
7328
+ appendStringInfoString(str, "ESCAPE ");
7329
+ deparseStringLiteral(str, strVal(def_elem->arg));
7330
+ }
7331
+ else if (strcmp(def_elem->defname, "force_quote") == 0)
7332
+ {
7333
+ appendStringInfoString(str, "FORCE_QUOTE ");
7334
+ if (IsA(def_elem->arg, A_Star))
7335
+ {
7336
+ appendStringInfoChar(str, '*');
7337
+ }
7338
+ else if (IsA(def_elem->arg, List))
7339
+ {
7340
+ appendStringInfoChar(str, '(');
7341
+ deparseColumnList(str, castNode(List, def_elem->arg));
7342
+ appendStringInfoChar(str, ')');
7343
+ }
7344
+ else
6782
7345
  {
6783
- deparseOptBooleanOrString(str, strVal(lfirst(lc2)));
6784
- if (lnext(l, lc2))
6785
- appendStringInfoString(str, ", ");
7346
+ Assert(false);
6786
7347
  }
7348
+ }
7349
+ else if (strcmp(def_elem->defname, "force_not_null") == 0)
7350
+ {
7351
+ appendStringInfoString(str, "FORCE_NOT_NULL (");
7352
+ deparseColumnList(str, castNode(List, def_elem->arg));
6787
7353
  appendStringInfoChar(str, ')');
6788
7354
  }
6789
- }
7355
+ else if (strcmp(def_elem->defname, "force_null") == 0)
7356
+ {
7357
+ appendStringInfoString(str, "FORCE_NULL (");
7358
+ deparseColumnList(str, castNode(List, def_elem->arg));
7359
+ appendStringInfoChar(str, ')');
7360
+ }
7361
+ else if (strcmp(def_elem->defname, "encoding") == 0)
7362
+ {
7363
+ appendStringInfoString(str, "ENCODING ");
7364
+ deparseStringLiteral(str, strVal(def_elem->arg));
7365
+ }
7366
+ else
7367
+ {
7368
+ appendStringInfoString(str, quote_identifier(def_elem->defname));
7369
+ if (def_elem->arg != NULL)
7370
+ appendStringInfoChar(str, ' ');
7371
+
7372
+ if (def_elem->arg == NULL)
7373
+ {
7374
+ // Nothing
7375
+ }
7376
+ else if (IsA(def_elem->arg, String))
7377
+ {
7378
+ deparseOptBooleanOrString(str, strVal(def_elem->arg));
7379
+ }
7380
+ else if (IsA(def_elem->arg, Integer) || IsA(def_elem->arg, Float))
7381
+ {
7382
+ deparseNumericOnly(str, (union ValUnion *) def_elem->arg);
7383
+ }
7384
+ else if (IsA(def_elem->arg, A_Star))
7385
+ {
7386
+ deparseAStar(str, castNode(A_Star, def_elem->arg));
7387
+ }
7388
+ else if (IsA(def_elem->arg, List))
7389
+ {
7390
+ List *l = castNode(List, def_elem->arg);
7391
+ appendStringInfoChar(str, '(');
7392
+ foreach(lc2, l)
7393
+ {
7394
+ deparseOptBooleanOrString(str, strVal(lfirst(lc2)));
7395
+ if (lnext(l, lc2))
7396
+ appendStringInfoString(str, ", ");
7397
+ }
7398
+ appendStringInfoChar(str, ')');
7399
+ }
7400
+ }
6790
7401
 
6791
- if (lnext(copy_stmt->options, lc))
6792
- appendStringInfoString(str, ", ");
7402
+ if (lnext(copy_stmt->options, lc))
7403
+ appendStringInfoString(str, ", ");
7404
+ }
7405
+ appendStringInfoString(str, ") ");
6793
7406
  }
6794
- appendStringInfoString(str, ") ");
6795
7407
  }
6796
7408
 
6797
7409
  deparseWhereClause(str, copy_stmt->whereClause);
@@ -7248,7 +7860,6 @@ static void deparseAccessPriv(StringInfo str, AccessPriv *access_priv)
7248
7860
  static void deparseGrantStmt(StringInfo str, GrantStmt *grant_stmt)
7249
7861
  {
7250
7862
  ListCell *lc;
7251
-
7252
7863
  if (grant_stmt->is_grant)
7253
7864
  appendStringInfoString(str, "GRANT ");
7254
7865
  else
@@ -7295,6 +7906,12 @@ static void deparseGrantStmt(StringInfo str, GrantStmt *grant_stmt)
7295
7906
 
7296
7907
  deparseOptDropBehavior(str, grant_stmt->behavior);
7297
7908
 
7909
+ if (grant_stmt->grantor)
7910
+ {
7911
+ appendStringInfoString(str, "GRANTED BY ");
7912
+ deparseRoleSpec(str, castNode(RoleSpec, grant_stmt->grantor));
7913
+ }
7914
+
7298
7915
  removeTrailingSpace(str);
7299
7916
  }
7300
7917
 
@@ -7307,6 +7924,9 @@ static void deparseGrantRoleStmt(StringInfo str, GrantRoleStmt *grant_role_stmt)
7307
7924
  else
7308
7925
  appendStringInfoString(str, "REVOKE ");
7309
7926
 
7927
+ if (!grant_role_stmt->is_grant && grant_role_stmt->admin_opt)
7928
+ appendStringInfoString(str, "ADMIN OPTION FOR ");
7929
+
7310
7930
  foreach(lc, grant_role_stmt->granted_roles)
7311
7931
  {
7312
7932
  deparseAccessPriv(str, castNode(AccessPriv, lfirst(lc)));
@@ -7323,9 +7943,15 @@ static void deparseGrantRoleStmt(StringInfo str, GrantRoleStmt *grant_role_stmt)
7323
7943
  deparseRoleList(str, grant_role_stmt->grantee_roles);
7324
7944
  appendStringInfoChar(str, ' ');
7325
7945
 
7326
- if (grant_role_stmt->admin_opt)
7946
+ if (grant_role_stmt->is_grant && grant_role_stmt->admin_opt)
7327
7947
  appendStringInfoString(str, "WITH ADMIN OPTION ");
7328
7948
 
7949
+ if (grant_role_stmt->grantor)
7950
+ {
7951
+ appendStringInfoString(str, "GRANTED BY ");
7952
+ deparseRoleSpec(str, castNode(RoleSpec, grant_role_stmt->grantor));
7953
+ }
7954
+
7329
7955
  removeTrailingSpace(str);
7330
7956
  }
7331
7957
 
@@ -7360,7 +7986,7 @@ static void deparseIndexStmt(StringInfo str, IndexStmt *index_stmt)
7360
7986
 
7361
7987
  if (index_stmt->idxname != NULL)
7362
7988
  {
7363
- appendStringInfoString(str, index_stmt->idxname);
7989
+ appendStringInfoString(str, quote_identifier(index_stmt->idxname));
7364
7990
  appendStringInfoChar(str, ' ');
7365
7991
  }
7366
7992
 
@@ -7396,6 +8022,11 @@ static void deparseIndexStmt(StringInfo str, IndexStmt *index_stmt)
7396
8022
  appendStringInfoString(str, ") ");
7397
8023
  }
7398
8024
 
8025
+ if (index_stmt->nulls_not_distinct)
8026
+ {
8027
+ appendStringInfoString(str, "NULLS NOT DISTINCT ");
8028
+ }
8029
+
7399
8030
  deparseOptWith(str, index_stmt->options);
7400
8031
 
7401
8032
  if (index_stmt->tableSpace != NULL)
@@ -7499,59 +8130,59 @@ static void deparseAlterRoleElem(StringInfo str, DefElem *def_elem)
7499
8130
  appendStringInfoString(str, "VALID UNTIL ");
7500
8131
  deparseStringLiteral(str, strVal(def_elem->arg));
7501
8132
  }
7502
- else if (strcmp(def_elem->defname, "superuser") == 0 && intVal(def_elem->arg) == 1)
8133
+ else if (strcmp(def_elem->defname, "superuser") == 0 && boolVal(def_elem->arg))
7503
8134
  {
7504
8135
  appendStringInfoString(str, "SUPERUSER");
7505
8136
  }
7506
- else if (strcmp(def_elem->defname, "superuser") == 0 && intVal(def_elem->arg) == 0)
8137
+ else if (strcmp(def_elem->defname, "superuser") == 0 && !boolVal(def_elem->arg))
7507
8138
  {
7508
8139
  appendStringInfoString(str, "NOSUPERUSER");
7509
8140
  }
7510
- else if (strcmp(def_elem->defname, "createrole") == 0 && intVal(def_elem->arg) == 1)
8141
+ else if (strcmp(def_elem->defname, "createrole") == 0 && boolVal(def_elem->arg))
7511
8142
  {
7512
8143
  appendStringInfoString(str, "CREATEROLE");
7513
8144
  }
7514
- else if (strcmp(def_elem->defname, "createrole") == 0 && intVal(def_elem->arg) == 0)
8145
+ else if (strcmp(def_elem->defname, "createrole") == 0 && !boolVal(def_elem->arg))
7515
8146
  {
7516
8147
  appendStringInfoString(str, "NOCREATEROLE");
7517
8148
  }
7518
- else if (strcmp(def_elem->defname, "isreplication") == 0 && intVal(def_elem->arg) == 1)
8149
+ else if (strcmp(def_elem->defname, "isreplication") == 0 && boolVal(def_elem->arg))
7519
8150
  {
7520
8151
  appendStringInfoString(str, "REPLICATION");
7521
8152
  }
7522
- else if (strcmp(def_elem->defname, "isreplication") == 0 && intVal(def_elem->arg) == 0)
8153
+ else if (strcmp(def_elem->defname, "isreplication") == 0 && !boolVal(def_elem->arg))
7523
8154
  {
7524
8155
  appendStringInfoString(str, "NOREPLICATION");
7525
8156
  }
7526
- else if (strcmp(def_elem->defname, "createdb") == 0 && intVal(def_elem->arg) == 1)
8157
+ else if (strcmp(def_elem->defname, "createdb") == 0 && boolVal(def_elem->arg))
7527
8158
  {
7528
8159
  appendStringInfoString(str, "CREATEDB");
7529
8160
  }
7530
- else if (strcmp(def_elem->defname, "createdb") == 0 && intVal(def_elem->arg) == 0)
8161
+ else if (strcmp(def_elem->defname, "createdb") == 0 && !boolVal(def_elem->arg))
7531
8162
  {
7532
8163
  appendStringInfoString(str, "NOCREATEDB");
7533
8164
  }
7534
- else if (strcmp(def_elem->defname, "canlogin") == 0 && intVal(def_elem->arg) == 1)
8165
+ else if (strcmp(def_elem->defname, "canlogin") == 0 && boolVal(def_elem->arg))
7535
8166
  {
7536
8167
  appendStringInfoString(str, "LOGIN");
7537
8168
  }
7538
- else if (strcmp(def_elem->defname, "canlogin") == 0 && intVal(def_elem->arg) == 0)
8169
+ else if (strcmp(def_elem->defname, "canlogin") == 0 && !boolVal(def_elem->arg))
7539
8170
  {
7540
8171
  appendStringInfoString(str, "NOLOGIN");
7541
8172
  }
7542
- else if (strcmp(def_elem->defname, "bypassrls") == 0 && intVal(def_elem->arg) == 1)
8173
+ else if (strcmp(def_elem->defname, "bypassrls") == 0 && boolVal(def_elem->arg))
7543
8174
  {
7544
8175
  appendStringInfoString(str, "BYPASSRLS");
7545
8176
  }
7546
- else if (strcmp(def_elem->defname, "bypassrls") == 0 && intVal(def_elem->arg) == 0)
8177
+ else if (strcmp(def_elem->defname, "bypassrls") == 0 && !boolVal(def_elem->arg))
7547
8178
  {
7548
8179
  appendStringInfoString(str, "NOBYPASSRLS");
7549
8180
  }
7550
- else if (strcmp(def_elem->defname, "inherit") == 0 && intVal(def_elem->arg) == 1)
8181
+ else if (strcmp(def_elem->defname, "inherit") == 0 && boolVal(def_elem->arg))
7551
8182
  {
7552
8183
  appendStringInfoString(str, "INHERIT");
7553
8184
  }
7554
- else if (strcmp(def_elem->defname, "inherit") == 0 && intVal(def_elem->arg) == 0)
8185
+ else if (strcmp(def_elem->defname, "inherit") == 0 && !boolVal(def_elem->arg))
7555
8186
  {
7556
8187
  appendStringInfoString(str, "NOINHERIT");
7557
8188
  }
@@ -7824,8 +8455,7 @@ static void deparseReindexStmt(StringInfo str, ReindexStmt *reindex_stmt)
7824
8455
  {
7825
8456
  appendStringInfoString(str, "REINDEX ");
7826
8457
 
7827
- if (reindex_stmt->options & REINDEXOPT_VERBOSE)
7828
- appendStringInfoString(str, "(VERBOSE) ");
8458
+ deparseUtilityOptionList(str, reindex_stmt->params);
7829
8459
 
7830
8460
  switch (reindex_stmt->kind)
7831
8461
  {
@@ -7846,9 +8476,6 @@ static void deparseReindexStmt(StringInfo str, ReindexStmt *reindex_stmt)
7846
8476
  break;
7847
8477
  }
7848
8478
 
7849
- if (reindex_stmt->concurrent)
7850
- appendStringInfoString(str, "CONCURRENTLY ");
7851
-
7852
8479
  if (reindex_stmt->relation != NULL)
7853
8480
  {
7854
8481
  deparseRangeVar(str, reindex_stmt->relation, DEPARSE_NODE_CONTEXT_NONE);
@@ -7892,6 +8519,9 @@ static void deparseRuleStmt(StringInfo str, RuleStmt* rule_stmt)
7892
8519
  case CMD_DELETE:
7893
8520
  appendStringInfoString(str, "DELETE ");
7894
8521
  break;
8522
+ case CMD_MERGE:
8523
+ appendStringInfoString(str, "MERGE ");
8524
+ break;
7895
8525
  }
7896
8526
 
7897
8527
  appendStringInfoString(str, "TO ");
@@ -8214,7 +8844,12 @@ static void deparseCreateTableSpaceStmt(StringInfo str, CreateTableSpaceStmt *cr
8214
8844
  }
8215
8845
 
8216
8846
  appendStringInfoString(str, "LOCATION ");
8217
- deparseStringLiteral(str, create_table_space_stmt->location);
8847
+
8848
+ if (create_table_space_stmt->location != NULL)
8849
+ deparseStringLiteral(str, create_table_space_stmt->location);
8850
+ else
8851
+ appendStringInfoString(str, "''");
8852
+
8218
8853
  appendStringInfoChar(str, ' ');
8219
8854
 
8220
8855
  deparseOptWith(str, create_table_space_stmt->options);
@@ -8277,6 +8912,50 @@ static void deparseCreateAmStmt(StringInfo str, CreateAmStmt *create_am_stmt)
8277
8912
  deparseHandlerName(str, create_am_stmt->handler_name);
8278
8913
  }
8279
8914
 
8915
+ static void deparsePublicationObjectList(StringInfo str, List *pubobjects) {
8916
+ const ListCell *lc;
8917
+ foreach(lc, pubobjects) {
8918
+ PublicationObjSpec *obj = lfirst(lc);
8919
+
8920
+ switch (obj->pubobjtype) {
8921
+ case PUBLICATIONOBJ_TABLE:
8922
+ appendStringInfoString(str, "TABLE ");
8923
+ deparseRangeVar(str, obj->pubtable->relation, DEPARSE_NODE_CONTEXT_NONE);
8924
+
8925
+ if (obj->pubtable->columns)
8926
+ {
8927
+ appendStringInfoChar(str, '(');
8928
+ deparseColumnList(str, obj->pubtable->columns);
8929
+ appendStringInfoChar(str, ')');
8930
+ }
8931
+
8932
+ if (obj->pubtable->whereClause)
8933
+ {
8934
+ appendStringInfoString(str, " WHERE (");
8935
+ deparseExpr(str, obj->pubtable->whereClause);
8936
+ appendStringInfoString(str, ")");
8937
+ }
8938
+
8939
+ break;
8940
+ case PUBLICATIONOBJ_TABLES_IN_SCHEMA:
8941
+ appendStringInfoString(str, "TABLES IN SCHEMA ");
8942
+ appendStringInfoString(str, quote_identifier(obj->name));
8943
+ break;
8944
+ case PUBLICATIONOBJ_TABLES_IN_CUR_SCHEMA:
8945
+ appendStringInfoString(str, "TABLES IN SCHEMA CURRENT_SCHEMA");
8946
+ break;
8947
+ case PUBLICATIONOBJ_CONTINUATION:
8948
+ // This should be unreachable, the parser merges these before we can even get here.
8949
+ Assert(false);
8950
+ break;
8951
+ }
8952
+
8953
+ if (lnext(pubobjects, lc)) {
8954
+ appendStringInfoString(str, ", ");
8955
+ }
8956
+ }
8957
+ }
8958
+
8280
8959
  static void deparseCreatePublicationStmt(StringInfo str, CreatePublicationStmt *create_publication_stmt)
8281
8960
  {
8282
8961
  ListCell *lc = NULL;
@@ -8285,10 +8964,10 @@ static void deparseCreatePublicationStmt(StringInfo str, CreatePublicationStmt *
8285
8964
  appendStringInfoString(str, quote_identifier(create_publication_stmt->pubname));
8286
8965
  appendStringInfoChar(str, ' ');
8287
8966
 
8288
- if (list_length(create_publication_stmt->tables) > 0)
8967
+ if (list_length(create_publication_stmt->pubobjects) > 0)
8289
8968
  {
8290
- appendStringInfoString(str, "FOR TABLE ");
8291
- deparseRelationExprList(str, create_publication_stmt->tables);
8969
+ appendStringInfoString(str, "FOR ");
8970
+ deparsePublicationObjectList(str, create_publication_stmt->pubobjects);
8292
8971
  appendStringInfoChar(str, ' ');
8293
8972
  }
8294
8973
  else if (create_publication_stmt->for_all_tables)
@@ -8306,25 +8985,22 @@ static void deparseAlterPublicationStmt(StringInfo str, AlterPublicationStmt *al
8306
8985
  deparseColId(str, alter_publication_stmt->pubname);
8307
8986
  appendStringInfoChar(str, ' ');
8308
8987
 
8309
- if (list_length(alter_publication_stmt->tables) > 0)
8988
+ if (list_length(alter_publication_stmt->pubobjects) > 0)
8310
8989
  {
8311
- switch (alter_publication_stmt->tableAction)
8990
+ switch (alter_publication_stmt->action)
8312
8991
  {
8313
- case DEFELEM_SET:
8314
- appendStringInfoString(str, "SET TABLE ");
8315
- break;
8316
- case DEFELEM_ADD:
8317
- appendStringInfoString(str, "ADD TABLE ");
8992
+ case AP_SetObjects:
8993
+ appendStringInfoString(str, "SET ");
8318
8994
  break;
8319
- case DEFELEM_DROP:
8320
- appendStringInfoString(str, "DROP TABLE ");
8995
+ case AP_AddObjects:
8996
+ appendStringInfoString(str, "ADD ");
8321
8997
  break;
8322
- case DEFELEM_UNSPEC:
8323
- Assert(false);
8998
+ case AP_DropObjects:
8999
+ appendStringInfoString(str, "DROP ");
8324
9000
  break;
8325
9001
  }
8326
9002
 
8327
- deparseRelationExprList(str, alter_publication_stmt->tables);
9003
+ deparsePublicationObjectList(str, alter_publication_stmt->pubobjects);
8328
9004
  }
8329
9005
  else if (list_length(alter_publication_stmt->options) > 0)
8330
9006
  {
@@ -8581,7 +9257,7 @@ static void deparseCommentStmt(StringInfo str, CommentStmt *comment_stmt)
8581
9257
  appendStringInfoString(str, quote_identifier(strVal(linitial(l))));
8582
9258
  break;
8583
9259
  case OBJECT_LARGEOBJECT:
8584
- deparseValue(str, (Value *) comment_stmt->object, DEPARSE_NODE_CONTEXT_NONE);
9260
+ deparseValue(str, (union ValUnion *) comment_stmt->object, DEPARSE_NODE_CONTEXT_NONE);
8585
9261
  break;
8586
9262
  case OBJECT_CAST:
8587
9263
  l = castNode(List, comment_stmt->object);
@@ -8605,6 +9281,19 @@ static void deparseCommentStmt(StringInfo str, CommentStmt *comment_stmt)
8605
9281
  appendStringInfoString(str, "NULL");
8606
9282
  }
8607
9283
 
9284
+ static void deparseStatsElem(StringInfo str, StatsElem *stats_elem)
9285
+ {
9286
+ // only one of stats_elem->name or stats_elem->expr can be non-null
9287
+ if (stats_elem->name)
9288
+ appendStringInfoString(str, stats_elem->name);
9289
+ else if (stats_elem->expr)
9290
+ {
9291
+ appendStringInfoChar(str, '(');
9292
+ deparseExpr(str, stats_elem->expr);
9293
+ appendStringInfoChar(str, ')');
9294
+ }
9295
+ }
9296
+
8608
9297
  static void deparseCreateStatsStmt(StringInfo str, CreateStatsStmt *create_stats_stmt)
8609
9298
  {
8610
9299
  ListCell *lc;
@@ -8625,7 +9314,12 @@ static void deparseCreateStatsStmt(StringInfo str, CreateStatsStmt *create_stats
8625
9314
  }
8626
9315
 
8627
9316
  appendStringInfoString(str, "ON ");
8628
- deparseExprList(str, create_stats_stmt->exprs);
9317
+ foreach (lc, create_stats_stmt->exprs)
9318
+ {
9319
+ deparseStatsElem(str, lfirst(lc));
9320
+ if (lnext(create_stats_stmt->exprs, lc))
9321
+ appendStringInfoString(str, ", ");
9322
+ }
8629
9323
 
8630
9324
  appendStringInfoString(str, " FROM ");
8631
9325
  deparseFromList(str, create_stats_stmt->relations);
@@ -8737,7 +9431,7 @@ static void deparseVariableShowStmt(StringInfo str, VariableShowStmt *variable_s
8737
9431
  else if (strcmp(variable_show_stmt->name, "all") == 0)
8738
9432
  appendStringInfoString(str, "SESSION ALL");
8739
9433
  else
8740
- appendStringInfoString(str, variable_show_stmt->name);
9434
+ appendStringInfoString(str, quote_identifier(variable_show_stmt->name));
8741
9435
  }
8742
9436
 
8743
9437
  static void deparseRangeTableSample(StringInfo str, RangeTableSample *range_table_sample)
@@ -8802,6 +9496,10 @@ static void deparseAlterSubscriptionStmt(StringInfo str, AlterSubscriptionStmt *
8802
9496
  appendStringInfoString(str, "SET ");
8803
9497
  deparseDefinition(str, alter_subscription_stmt->options);
8804
9498
  break;
9499
+ case ALTER_SUBSCRIPTION_SKIP:
9500
+ appendStringInfoString(str, "SKIP ");
9501
+ deparseDefinition(str, alter_subscription_stmt->options);
9502
+ break;
8805
9503
  case ALTER_SUBSCRIPTION_CONNECTION:
8806
9504
  appendStringInfoString(str, "CONNECTION ");
8807
9505
  deparseStringLiteral(str, alter_subscription_stmt->conninfo);
@@ -8811,7 +9509,29 @@ static void deparseAlterSubscriptionStmt(StringInfo str, AlterSubscriptionStmt *
8811
9509
  appendStringInfoString(str, "REFRESH PUBLICATION ");
8812
9510
  deparseOptDefinition(str, alter_subscription_stmt->options);
8813
9511
  break;
8814
- case ALTER_SUBSCRIPTION_PUBLICATION:
9512
+ case ALTER_SUBSCRIPTION_ADD_PUBLICATION:
9513
+ appendStringInfoString(str, "ADD PUBLICATION ");
9514
+ foreach(lc, alter_subscription_stmt->publication)
9515
+ {
9516
+ deparseColLabel(str, strVal(lfirst(lc)));
9517
+ if (lnext(alter_subscription_stmt->publication, lc))
9518
+ appendStringInfoString(str, ", ");
9519
+ }
9520
+ appendStringInfoChar(str, ' ');
9521
+ deparseOptDefinition(str, alter_subscription_stmt->options);
9522
+ break;
9523
+ case ALTER_SUBSCRIPTION_DROP_PUBLICATION:
9524
+ appendStringInfoString(str, "DROP PUBLICATION ");
9525
+ foreach(lc, alter_subscription_stmt->publication)
9526
+ {
9527
+ deparseColLabel(str, strVal(lfirst(lc)));
9528
+ if (lnext(alter_subscription_stmt->publication, lc))
9529
+ appendStringInfoString(str, ", ");
9530
+ }
9531
+ appendStringInfoChar(str, ' ');
9532
+ deparseOptDefinition(str, alter_subscription_stmt->options);
9533
+ break;
9534
+ case ALTER_SUBSCRIPTION_SET_PUBLICATION:
8815
9535
  appendStringInfoString(str, "SET PUBLICATION ");
8816
9536
  foreach(lc, alter_subscription_stmt->publication)
8817
9537
  {
@@ -8826,17 +9546,13 @@ static void deparseAlterSubscriptionStmt(StringInfo str, AlterSubscriptionStmt *
8826
9546
  Assert(list_length(alter_subscription_stmt->options) == 1);
8827
9547
  DefElem *defelem = castNode(DefElem, linitial(alter_subscription_stmt->options));
8828
9548
  Assert(strcmp(defelem->defname, "enabled") == 0);
8829
- if (intVal(defelem->arg) == 1)
9549
+ if (optBooleanValue(defelem->arg))
8830
9550
  {
8831
9551
  appendStringInfoString(str, " ENABLE ");
8832
9552
  }
8833
- else if (intVal(defelem->arg) == 0)
8834
- {
8835
- appendStringInfoString(str, " DISABLE ");
8836
- }
8837
9553
  else
8838
9554
  {
8839
- Assert(false);
9555
+ appendStringInfoString(str, " DISABLE ");
8840
9556
  }
8841
9557
  break;
8842
9558
  }
@@ -8898,7 +9614,7 @@ static void deparseAlterOwnerStmt(StringInfo str, AlterOwnerStmt *alter_owner_st
8898
9614
  break;
8899
9615
  case OBJECT_LARGEOBJECT:
8900
9616
  appendStringInfoString(str, "LARGE OBJECT ");
8901
- deparseNumericOnly(str, (Value *) alter_owner_stmt->object);
9617
+ deparseNumericOnly(str, (union ValUnion *) alter_owner_stmt->object);
8902
9618
  break;
8903
9619
  case OBJECT_OPERATOR:
8904
9620
  appendStringInfoString(str, "OPERATOR ");
@@ -9061,6 +9777,8 @@ static void deparseCreateTrigStmt(StringInfo str, CreateTrigStmt *create_trig_st
9061
9777
  bool skip_events_or = true;
9062
9778
 
9063
9779
  appendStringInfoString(str, "CREATE ");
9780
+ if (create_trig_stmt->replace)
9781
+ appendStringInfoString(str, "OR REPLACE ");
9064
9782
  if (create_trig_stmt->isconstraint)
9065
9783
  appendStringInfoString(str, "CONSTRAINT ");
9066
9784
  appendStringInfoString(str, "TRIGGER ");
@@ -9224,8 +9942,6 @@ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
9224
9942
  Assert(false);
9225
9943
  }
9226
9944
  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
9945
  appendStringInfoChar(str, ')');
9230
9946
  break;
9231
9947
  case IS_XMLPI: /* XMLPI(name [, args]) */
@@ -9242,7 +9958,7 @@ static void deparseXmlExpr(StringInfo str, XmlExpr* xml_expr)
9242
9958
  appendStringInfoString(str, "xmlroot(");
9243
9959
  deparseExpr(str, linitial(xml_expr->args));
9244
9960
  appendStringInfoString(str, ", version ");
9245
- if (nodeTag(&castNode(A_Const, lsecond(xml_expr->args))->val) == T_Null)
9961
+ if (castNode(A_Const, lsecond(xml_expr->args))->isnull)
9246
9962
  appendStringInfoString(str, "NO VALUE");
9247
9963
  else
9248
9964
  deparseExpr(str, lsecond(xml_expr->args));
@@ -9372,8 +10088,8 @@ static void deparseGroupingFunc(StringInfo str, GroupingFunc *grouping_func)
9372
10088
  static void deparseClusterStmt(StringInfo str, ClusterStmt *cluster_stmt)
9373
10089
  {
9374
10090
  appendStringInfoString(str, "CLUSTER ");
9375
- if (cluster_stmt->options & CLUOPT_VERBOSE)
9376
- appendStringInfoString(str, "VERBOSE ");
10091
+
10092
+ deparseUtilityOptionList(str, cluster_stmt->params);
9377
10093
 
9378
10094
  if (cluster_stmt->relation != NULL)
9379
10095
  {
@@ -9391,42 +10107,47 @@ static void deparseClusterStmt(StringInfo str, ClusterStmt *cluster_stmt)
9391
10107
  removeTrailingSpace(str);
9392
10108
  }
9393
10109
 
9394
- static void deparseValue(StringInfo str, Value *value, DeparseNodeContext context)
10110
+ static void deparseValue(StringInfo str, union ValUnion *value, DeparseNodeContext context)
9395
10111
  {
10112
+ if (!value) {
10113
+ appendStringInfoString(str, "NULL");
10114
+ return;
10115
+ }
10116
+
9396
10117
  switch (nodeTag(value))
9397
10118
  {
9398
10119
  case T_Integer:
9399
10120
  case T_Float:
9400
10121
  deparseNumericOnly(str, value);
9401
10122
  break;
10123
+ case T_Boolean:
10124
+ appendStringInfoString(str, value->boolval.boolval ? "true" : "false");
10125
+ break;
9402
10126
  case T_String:
9403
10127
  if (context == DEPARSE_NODE_CONTEXT_IDENTIFIER) {
9404
- appendStringInfoString(str, quote_identifier(value->val.str));
10128
+ appendStringInfoString(str, quote_identifier(value->sval.sval));
9405
10129
  } else if (context == DEPARSE_NODE_CONTEXT_CONSTANT) {
9406
- deparseStringLiteral(str, value->val.str);
10130
+ deparseStringLiteral(str, value->sval.sval);
9407
10131
  } else {
9408
- appendStringInfoString(str, value->val.str);
10132
+ appendStringInfoString(str, value->sval.sval);
9409
10133
  }
9410
10134
  break;
9411
10135
  case T_BitString:
9412
- if (strlen(value->val.str) >= 1 && value->val.str[0] == 'x')
10136
+ if (strlen(value->sval.sval) >= 1 && value->sval.sval[0] == 'x')
9413
10137
  {
9414
10138
  appendStringInfoChar(str, 'x');
9415
- deparseStringLiteral(str, value->val.str + 1);
10139
+ deparseStringLiteral(str, value->sval.sval + 1);
9416
10140
  }
9417
- else if (strlen(value->val.str) >= 1 && value->val.str[0] == 'b')
10141
+ else if (strlen(value->sval.sval) >= 1 && value->sval.sval[0] == 'b')
9418
10142
  {
9419
10143
  appendStringInfoChar(str, 'b');
9420
- deparseStringLiteral(str, value->val.str + 1);
10144
+ deparseStringLiteral(str, value->sval.sval + 1);
9421
10145
  }
9422
10146
  else
9423
10147
  {
9424
10148
  Assert(false);
9425
10149
  }
9426
10150
  break;
9427
- case T_Null:
9428
- appendStringInfoString(str, "NULL");
9429
- break;
9430
10151
  default:
9431
10152
  elog(ERROR, "deparse: unrecognized value node type: %d",
9432
10153
  (int) nodeTag(value));
@@ -9451,6 +10172,9 @@ static void deparsePreparableStmt(StringInfo str, Node *node)
9451
10172
  case T_DeleteStmt:
9452
10173
  deparseDeleteStmt(str, castNode(DeleteStmt, node));
9453
10174
  break;
10175
+ case T_MergeStmt:
10176
+ deparseMergeStmt(str, castNode(MergeStmt, node));
10177
+ break;
9454
10178
  default:
9455
10179
  Assert(false);
9456
10180
  }
@@ -9510,6 +10234,9 @@ static void deparseExplainableStmt(StringInfo str, Node *node)
9510
10234
  case T_ExecuteStmt:
9511
10235
  deparseExecuteStmt(str, castNode(ExecuteStmt, node));
9512
10236
  break;
10237
+ case T_MergeStmt:
10238
+ deparseMergeStmt(str, castNode(MergeStmt, node));
10239
+ break;
9513
10240
  default:
9514
10241
  Assert(false);
9515
10242
  }
@@ -9632,6 +10359,9 @@ static void deparseStmt(StringInfo str, Node *node)
9632
10359
  case T_AlterSystemStmt:
9633
10360
  deparseAlterSystemStmt(str, castNode(AlterSystemStmt, node));
9634
10361
  break;
10362
+ case T_AlterTableMoveAllStmt:
10363
+ deparseAlterTableMoveAllStmt(str, castNode(AlterTableMoveAllStmt, node));
10364
+ break;
9635
10365
  case T_AlterTableStmt:
9636
10366
  deparseAlterTableStmt(str, castNode(AlterTableStmt, node));
9637
10367
  break;
@@ -9842,6 +10572,9 @@ static void deparseStmt(StringInfo str, Node *node)
9842
10572
  case T_LockStmt:
9843
10573
  deparseLockStmt(str, castNode(LockStmt, node));
9844
10574
  break;
10575
+ case T_MergeStmt:
10576
+ deparseMergeStmt(str, castNode(MergeStmt, node));
10577
+ break;
9845
10578
  case T_NotifyStmt:
9846
10579
  deparseNotifyStmt(str, castNode(NotifyStmt, node));
9847
10580
  break;