pg_query 2.2.0 → 4.2.0

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