pg_query 2.1.0 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +104 -0
  3. data/README.md +59 -31
  4. data/Rakefile +2 -2
  5. data/ext/pg_query/extconf.rb +8 -2
  6. data/ext/pg_query/include/access/amapi.h +45 -1
  7. data/ext/pg_query/include/access/attmap.h +1 -1
  8. data/ext/pg_query/include/access/attnum.h +2 -2
  9. data/ext/pg_query/include/access/clog.h +4 -2
  10. data/ext/pg_query/include/access/commit_ts.h +6 -9
  11. data/ext/pg_query/include/access/detoast.h +1 -11
  12. data/ext/pg_query/include/access/genam.h +15 -12
  13. data/ext/pg_query/include/access/gin.h +2 -2
  14. data/ext/pg_query/include/access/htup.h +1 -1
  15. data/ext/pg_query/include/access/htup_details.h +75 -87
  16. data/ext/pg_query/include/access/itup.h +7 -1
  17. data/ext/pg_query/include/access/parallel.h +2 -2
  18. data/ext/pg_query/include/access/printtup.h +1 -1
  19. data/ext/pg_query/include/access/relation.h +1 -1
  20. data/ext/pg_query/include/access/relscan.h +17 -2
  21. data/ext/pg_query/include/access/rmgr.h +30 -3
  22. data/ext/pg_query/include/access/rmgrlist.h +23 -23
  23. data/ext/pg_query/include/access/sdir.h +1 -1
  24. data/ext/pg_query/include/access/skey.h +1 -1
  25. data/ext/pg_query/include/access/stratnum.h +4 -2
  26. data/ext/pg_query/include/access/sysattr.h +1 -1
  27. data/ext/pg_query/include/access/table.h +2 -1
  28. data/ext/pg_query/include/access/tableam.h +272 -20
  29. data/ext/pg_query/include/access/toast_compression.h +73 -0
  30. data/ext/pg_query/include/access/transam.h +123 -13
  31. data/ext/pg_query/include/access/tupconvert.h +1 -1
  32. data/ext/pg_query/include/access/tupdesc.h +1 -1
  33. data/ext/pg_query/include/access/tupmacs.h +3 -3
  34. data/ext/pg_query/include/access/twophase.h +5 -1
  35. data/ext/pg_query/include/access/xact.h +79 -19
  36. data/ext/pg_query/include/access/xlog.h +60 -155
  37. data/ext/pg_query/include/access/xlog_internal.h +50 -14
  38. data/ext/pg_query/include/access/xlogdefs.h +8 -16
  39. data/ext/pg_query/include/access/xlogprefetcher.h +55 -0
  40. data/ext/pg_query/include/access/xlogreader.h +148 -32
  41. data/ext/pg_query/include/access/xlogrecord.h +18 -9
  42. data/ext/pg_query/include/access/xlogrecovery.h +157 -0
  43. data/ext/pg_query/include/c.h +101 -44
  44. data/ext/pg_query/include/catalog/catalog.h +3 -1
  45. data/ext/pg_query/include/catalog/catversion.h +2 -2
  46. data/ext/pg_query/include/catalog/dependency.h +10 -16
  47. data/ext/pg_query/include/catalog/genbki.h +83 -5
  48. data/ext/pg_query/include/catalog/index.h +18 -3
  49. data/ext/pg_query/include/catalog/indexing.h +12 -324
  50. data/ext/pg_query/include/catalog/namespace.h +4 -2
  51. data/ext/pg_query/include/catalog/objectaccess.h +70 -2
  52. data/ext/pg_query/include/catalog/objectaddress.h +11 -6
  53. data/ext/pg_query/include/catalog/pg_aggregate.h +14 -10
  54. data/ext/pg_query/include/catalog/pg_aggregate_d.h +2 -1
  55. data/ext/pg_query/include/catalog/pg_am.h +4 -1
  56. data/ext/pg_query/include/catalog/pg_am_d.h +3 -1
  57. data/ext/pg_query/include/catalog/pg_attribute.h +27 -10
  58. data/ext/pg_query/include/catalog/pg_attribute_d.h +21 -18
  59. data/ext/pg_query/include/catalog/pg_authid.h +7 -2
  60. data/ext/pg_query/include/catalog/pg_authid_d.h +17 -9
  61. data/ext/pg_query/include/catalog/pg_class.h +45 -15
  62. data/ext/pg_query/include/catalog/pg_class_d.h +31 -2
  63. data/ext/pg_query/include/catalog/pg_collation.h +33 -8
  64. data/ext/pg_query/include/catalog/pg_collation_d.h +20 -3
  65. data/ext/pg_query/include/catalog/pg_constraint.h +38 -12
  66. data/ext/pg_query/include/catalog/pg_constraint_d.h +10 -4
  67. data/ext/pg_query/include/catalog/pg_control.h +5 -5
  68. data/ext/pg_query/include/catalog/pg_conversion.h +7 -4
  69. data/ext/pg_query/include/catalog/pg_conversion_d.h +4 -1
  70. data/ext/pg_query/include/catalog/pg_depend.h +11 -7
  71. data/ext/pg_query/include/catalog/pg_depend_d.h +3 -1
  72. data/ext/pg_query/include/catalog/pg_event_trigger.h +9 -3
  73. data/ext/pg_query/include/catalog/pg_event_trigger_d.h +3 -1
  74. data/ext/pg_query/include/catalog/pg_index.h +17 -7
  75. data/ext/pg_query/include/catalog/pg_index_d.h +20 -17
  76. data/ext/pg_query/include/catalog/pg_language.h +10 -5
  77. data/ext/pg_query/include/catalog/pg_language_d.h +3 -1
  78. data/ext/pg_query/include/catalog/pg_namespace.h +7 -2
  79. data/ext/pg_query/include/catalog/pg_namespace_d.h +3 -1
  80. data/ext/pg_query/include/catalog/pg_opclass.h +8 -5
  81. data/ext/pg_query/include/catalog/pg_opclass_d.h +3 -1
  82. data/ext/pg_query/include/catalog/pg_operator.h +21 -16
  83. data/ext/pg_query/include/catalog/pg_operator_d.h +37 -1
  84. data/ext/pg_query/include/catalog/pg_opfamily.h +6 -3
  85. data/ext/pg_query/include/catalog/pg_opfamily_d.h +3 -1
  86. data/ext/pg_query/include/catalog/pg_parameter_acl.h +60 -0
  87. data/ext/pg_query/include/catalog/pg_parameter_acl_d.h +34 -0
  88. data/ext/pg_query/include/catalog/pg_partitioned_table.h +20 -9
  89. data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +2 -1
  90. data/ext/pg_query/include/catalog/pg_proc.h +20 -11
  91. data/ext/pg_query/include/catalog/pg_proc_d.h +10 -8
  92. data/ext/pg_query/include/catalog/pg_publication.h +50 -4
  93. data/ext/pg_query/include/catalog/pg_publication_d.h +3 -1
  94. data/ext/pg_query/include/catalog/pg_replication_origin.h +6 -1
  95. data/ext/pg_query/include/catalog/pg_replication_origin_d.h +5 -1
  96. data/ext/pg_query/include/catalog/pg_statistic.h +19 -12
  97. data/ext/pg_query/include/catalog/pg_statistic_d.h +2 -1
  98. data/ext/pg_query/include/catalog/pg_statistic_ext.h +19 -5
  99. data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +7 -2
  100. data/ext/pg_query/include/catalog/pg_transform.h +8 -5
  101. data/ext/pg_query/include/catalog/pg_transform_d.h +3 -1
  102. data/ext/pg_query/include/catalog/pg_trigger.h +24 -8
  103. data/ext/pg_query/include/catalog/pg_trigger_d.h +4 -1
  104. data/ext/pg_query/include/catalog/pg_ts_config.h +6 -3
  105. data/ext/pg_query/include/catalog/pg_ts_config_d.h +3 -1
  106. data/ext/pg_query/include/catalog/pg_ts_dict.h +8 -3
  107. data/ext/pg_query/include/catalog/pg_ts_dict_d.h +3 -1
  108. data/ext/pg_query/include/catalog/pg_ts_parser.h +6 -3
  109. data/ext/pg_query/include/catalog/pg_ts_parser_d.h +3 -1
  110. data/ext/pg_query/include/catalog/pg_ts_template.h +6 -3
  111. data/ext/pg_query/include/catalog/pg_ts_template_d.h +3 -1
  112. data/ext/pg_query/include/catalog/pg_type.h +56 -24
  113. data/ext/pg_query/include/catalog/pg_type_d.h +70 -31
  114. data/ext/pg_query/include/catalog/storage.h +5 -3
  115. data/ext/pg_query/include/commands/async.h +4 -5
  116. data/ext/pg_query/include/commands/dbcommands.h +2 -1
  117. data/ext/pg_query/include/commands/defrem.h +11 -24
  118. data/ext/pg_query/include/commands/event_trigger.h +2 -2
  119. data/ext/pg_query/include/commands/explain.h +1 -1
  120. data/ext/pg_query/include/commands/prepare.h +1 -1
  121. data/ext/pg_query/include/commands/tablespace.h +3 -1
  122. data/ext/pg_query/include/commands/trigger.h +27 -17
  123. data/ext/pg_query/include/commands/user.h +2 -2
  124. data/ext/pg_query/include/commands/vacuum.h +88 -41
  125. data/ext/pg_query/include/commands/variable.h +1 -1
  126. data/ext/pg_query/include/common/file_perm.h +4 -4
  127. data/ext/pg_query/include/common/hashfn.h +1 -1
  128. data/ext/pg_query/include/common/ip.h +1 -7
  129. data/ext/pg_query/include/common/keywords.h +2 -6
  130. data/ext/pg_query/include/common/kwlookup.h +1 -1
  131. data/ext/pg_query/include/common/pg_prng.h +60 -0
  132. data/ext/pg_query/include/common/relpath.h +2 -2
  133. data/ext/pg_query/include/common/string.h +24 -1
  134. data/ext/pg_query/include/common/unicode_combining_table.h +114 -2
  135. data/ext/pg_query/include/common/unicode_east_asian_fw_table.h +125 -0
  136. data/ext/pg_query/include/datatype/timestamp.h +40 -1
  137. data/ext/pg_query/include/executor/execdesc.h +1 -1
  138. data/ext/pg_query/include/executor/executor.h +65 -22
  139. data/ext/pg_query/include/executor/functions.h +17 -3
  140. data/ext/pg_query/include/executor/instrument.h +33 -16
  141. data/ext/pg_query/include/executor/spi.h +41 -3
  142. data/ext/pg_query/include/executor/tablefunc.h +1 -1
  143. data/ext/pg_query/include/executor/tuptable.h +1 -1
  144. data/ext/pg_query/include/fmgr.h +13 -7
  145. data/ext/pg_query/include/funcapi.h +16 -4
  146. data/ext/pg_query/include/getaddrinfo.h +1 -1
  147. data/ext/pg_query/include/jit/jit.h +11 -11
  148. data/ext/pg_query/include/kwlist_d.h +517 -494
  149. data/ext/pg_query/include/lib/dshash.h +112 -0
  150. data/ext/pg_query/include/lib/ilist.h +20 -1
  151. data/ext/pg_query/include/lib/pairingheap.h +1 -1
  152. data/ext/pg_query/include/lib/simplehash.h +150 -25
  153. data/ext/pg_query/include/lib/sort_template.h +432 -0
  154. data/ext/pg_query/include/lib/stringinfo.h +1 -1
  155. data/ext/pg_query/include/libpq/auth.h +6 -4
  156. data/ext/pg_query/include/libpq/crypt.h +5 -4
  157. data/ext/pg_query/include/libpq/hba.h +43 -4
  158. data/ext/pg_query/include/libpq/libpq-be.h +23 -6
  159. data/ext/pg_query/include/libpq/libpq.h +31 -20
  160. data/ext/pg_query/include/libpq/pqcomm.h +17 -31
  161. data/ext/pg_query/include/libpq/pqformat.h +1 -1
  162. data/ext/pg_query/include/libpq/pqsignal.h +4 -4
  163. data/ext/pg_query/include/mb/pg_wchar.h +106 -23
  164. data/ext/pg_query/include/mb/stringinfo_mb.h +1 -1
  165. data/ext/pg_query/include/miscadmin.h +71 -52
  166. data/ext/pg_query/include/nodes/bitmapset.h +1 -1
  167. data/ext/pg_query/include/nodes/execnodes.h +272 -80
  168. data/ext/pg_query/include/nodes/extensible.h +4 -2
  169. data/ext/pg_query/include/nodes/lockoptions.h +1 -1
  170. data/ext/pg_query/include/nodes/makefuncs.h +7 -6
  171. data/ext/pg_query/include/nodes/memnodes.h +5 -3
  172. data/ext/pg_query/include/nodes/nodeFuncs.h +1 -1
  173. data/ext/pg_query/include/nodes/nodes.h +30 -11
  174. data/ext/pg_query/include/nodes/params.h +1 -1
  175. data/ext/pg_query/include/nodes/parsenodes.h +327 -94
  176. data/ext/pg_query/include/nodes/pathnodes.h +245 -67
  177. data/ext/pg_query/include/nodes/pg_list.h +75 -68
  178. data/ext/pg_query/include/nodes/plannodes.h +128 -30
  179. data/ext/pg_query/include/nodes/primnodes.h +99 -47
  180. data/ext/pg_query/include/nodes/print.h +1 -1
  181. data/ext/pg_query/include/nodes/tidbitmap.h +1 -1
  182. data/ext/pg_query/include/nodes/value.h +58 -39
  183. data/ext/pg_query/include/optimizer/cost.h +9 -2
  184. data/ext/pg_query/include/optimizer/geqo.h +9 -7
  185. data/ext/pg_query/include/optimizer/geqo_gene.h +1 -1
  186. data/ext/pg_query/include/optimizer/optimizer.h +25 -22
  187. data/ext/pg_query/include/optimizer/paths.h +6 -6
  188. data/ext/pg_query/include/optimizer/planmain.h +15 -14
  189. data/ext/pg_query/include/parser/analyze.h +19 -5
  190. data/ext/pg_query/include/parser/gram.h +947 -913
  191. data/ext/pg_query/include/parser/gramparse.h +1 -1
  192. data/ext/pg_query/include/parser/kwlist.h +463 -453
  193. data/ext/pg_query/include/parser/parse_agg.h +2 -7
  194. data/ext/pg_query/include/parser/parse_coerce.h +4 -1
  195. data/ext/pg_query/include/parser/parse_expr.h +2 -3
  196. data/ext/pg_query/include/parser/parse_func.h +2 -1
  197. data/ext/pg_query/include/parser/parse_node.h +21 -9
  198. data/ext/pg_query/include/parser/parse_oper.h +1 -3
  199. data/ext/pg_query/include/parser/parse_relation.h +5 -4
  200. data/ext/pg_query/include/parser/parse_type.h +1 -1
  201. data/ext/pg_query/include/parser/parser.h +31 -4
  202. data/ext/pg_query/include/parser/parsetree.h +1 -1
  203. data/ext/pg_query/include/parser/scanner.h +1 -1
  204. data/ext/pg_query/include/parser/scansup.h +2 -5
  205. data/ext/pg_query/include/partitioning/partdefs.h +1 -1
  206. data/ext/pg_query/include/pg_config.h +94 -46
  207. data/ext/pg_query/include/pg_config_manual.h +74 -21
  208. data/ext/pg_query/include/pg_getopt.h +6 -6
  209. data/ext/pg_query/include/pg_query.h +5 -4
  210. data/ext/pg_query/include/pg_query_enum_defs.c +358 -241
  211. data/ext/pg_query/include/pg_query_fingerprint_conds.c +44 -7
  212. data/ext/pg_query/include/pg_query_fingerprint_defs.c +1220 -422
  213. data/ext/pg_query/include/pg_query_outfuncs_conds.c +43 -13
  214. data/ext/pg_query/include/pg_query_outfuncs_defs.c +152 -26
  215. data/ext/pg_query/include/pg_query_readfuncs_conds.c +11 -2
  216. data/ext/pg_query/include/pg_query_readfuncs_defs.c +174 -30
  217. data/ext/pg_query/include/pg_trace.h +1 -1
  218. data/ext/pg_query/include/pgstat.h +449 -1237
  219. data/ext/pg_query/include/pgtime.h +14 -4
  220. data/ext/pg_query/include/pl_gram.h +126 -128
  221. data/ext/pg_query/include/pl_reserved_kwlist.h +1 -1
  222. data/ext/pg_query/include/pl_reserved_kwlist_d.h +10 -10
  223. data/ext/pg_query/include/pl_unreserved_kwlist.h +2 -3
  224. data/ext/pg_query/include/pl_unreserved_kwlist_d.h +54 -56
  225. data/ext/pg_query/include/plerrcodes.h +9 -1
  226. data/ext/pg_query/include/plpgsql.h +52 -54
  227. data/ext/pg_query/include/port/atomics/arch-arm.h +7 -1
  228. data/ext/pg_query/include/port/atomics/arch-ppc.h +1 -1
  229. data/ext/pg_query/include/port/atomics/arch-x86.h +1 -1
  230. data/ext/pg_query/include/port/atomics/fallback.h +1 -1
  231. data/ext/pg_query/include/port/atomics/generic-gcc.h +3 -3
  232. data/ext/pg_query/include/port/atomics/generic.h +1 -1
  233. data/ext/pg_query/include/port/atomics.h +1 -1
  234. data/ext/pg_query/include/port/pg_bitutils.h +88 -12
  235. data/ext/pg_query/include/port/pg_bswap.h +1 -1
  236. data/ext/pg_query/include/port/pg_crc32c.h +1 -1
  237. data/ext/pg_query/include/port.h +72 -43
  238. data/ext/pg_query/include/portability/instr_time.h +1 -1
  239. data/ext/pg_query/include/postgres.h +60 -16
  240. data/ext/pg_query/include/postmaster/autovacuum.h +17 -17
  241. data/ext/pg_query/include/postmaster/auxprocess.h +20 -0
  242. data/ext/pg_query/include/postmaster/bgworker.h +2 -1
  243. data/ext/pg_query/include/postmaster/bgworker_internals.h +2 -2
  244. data/ext/pg_query/include/postmaster/bgwriter.h +5 -5
  245. data/ext/pg_query/include/postmaster/fork_process.h +1 -1
  246. data/ext/pg_query/include/postmaster/interrupt.h +1 -1
  247. data/ext/pg_query/include/postmaster/pgarch.h +42 -8
  248. data/ext/pg_query/include/postmaster/postmaster.h +18 -17
  249. data/ext/pg_query/include/postmaster/startup.h +39 -0
  250. data/ext/pg_query/include/postmaster/syslogger.h +15 -10
  251. data/ext/pg_query/include/postmaster/walwriter.h +3 -3
  252. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +1422 -916
  253. data/ext/pg_query/include/protobuf/pg_query.pb.h +43678 -32769
  254. data/ext/pg_query/include/regex/regex.h +18 -16
  255. data/ext/pg_query/include/replication/logicallauncher.h +3 -5
  256. data/ext/pg_query/include/replication/logicalproto.h +161 -17
  257. data/ext/pg_query/include/replication/logicalworker.h +1 -1
  258. data/ext/pg_query/include/replication/origin.h +7 -7
  259. data/ext/pg_query/include/replication/reorderbuffer.h +262 -44
  260. data/ext/pg_query/include/replication/slot.h +23 -12
  261. data/ext/pg_query/include/replication/syncrep.h +5 -5
  262. data/ext/pg_query/include/replication/walreceiver.h +145 -13
  263. data/ext/pg_query/include/replication/walsender.h +8 -8
  264. data/ext/pg_query/include/rewrite/prs2lock.h +1 -1
  265. data/ext/pg_query/include/rewrite/rewriteHandler.h +1 -3
  266. data/ext/pg_query/include/rewrite/rewriteManip.h +1 -1
  267. data/ext/pg_query/include/rewrite/rewriteSupport.h +1 -1
  268. data/ext/pg_query/include/storage/backendid.h +3 -3
  269. data/ext/pg_query/include/storage/block.h +4 -10
  270. data/ext/pg_query/include/storage/buf.h +1 -1
  271. data/ext/pg_query/include/storage/bufmgr.h +19 -14
  272. data/ext/pg_query/include/storage/bufpage.h +6 -8
  273. data/ext/pg_query/include/storage/condition_variable.h +13 -2
  274. data/ext/pg_query/include/storage/dsm.h +4 -1
  275. data/ext/pg_query/include/storage/dsm_impl.h +3 -2
  276. data/ext/pg_query/include/storage/fd.h +33 -3
  277. data/ext/pg_query/include/storage/fileset.h +40 -0
  278. data/ext/pg_query/include/storage/ipc.h +4 -1
  279. data/ext/pg_query/include/storage/item.h +1 -1
  280. data/ext/pg_query/include/storage/itemid.h +1 -1
  281. data/ext/pg_query/include/storage/itemptr.h +3 -1
  282. data/ext/pg_query/include/storage/large_object.h +2 -2
  283. data/ext/pg_query/include/storage/latch.h +9 -13
  284. data/ext/pg_query/include/storage/lmgr.h +2 -1
  285. data/ext/pg_query/include/storage/lock.h +17 -13
  286. data/ext/pg_query/include/storage/lockdefs.h +2 -2
  287. data/ext/pg_query/include/storage/lwlock.h +6 -32
  288. data/ext/pg_query/include/storage/lwlocknames.h +0 -1
  289. data/ext/pg_query/include/storage/off.h +1 -1
  290. data/ext/pg_query/include/storage/pg_sema.h +1 -1
  291. data/ext/pg_query/include/storage/pg_shmem.h +9 -7
  292. data/ext/pg_query/include/storage/pmsignal.h +15 -4
  293. data/ext/pg_query/include/storage/predicate.h +4 -4
  294. data/ext/pg_query/include/storage/proc.h +183 -55
  295. data/ext/pg_query/include/storage/procarray.h +98 -0
  296. data/ext/pg_query/include/storage/proclist_types.h +1 -1
  297. data/ext/pg_query/include/storage/procsignal.h +3 -7
  298. data/ext/pg_query/include/storage/relfilenode.h +1 -1
  299. data/ext/pg_query/include/storage/s_lock.h +67 -4
  300. data/ext/pg_query/include/storage/sharedfileset.h +3 -11
  301. data/ext/pg_query/include/storage/shm_mq.h +5 -4
  302. data/ext/pg_query/include/storage/shm_toc.h +1 -1
  303. data/ext/pg_query/include/storage/shmem.h +1 -1
  304. data/ext/pg_query/include/storage/sinval.h +3 -3
  305. data/ext/pg_query/include/storage/sinvaladt.h +1 -1
  306. data/ext/pg_query/include/storage/smgr.h +10 -8
  307. data/ext/pg_query/include/storage/spin.h +2 -2
  308. data/ext/pg_query/include/storage/standby.h +13 -6
  309. data/ext/pg_query/include/storage/standbydefs.h +2 -2
  310. data/ext/pg_query/include/storage/sync.h +7 -3
  311. data/ext/pg_query/include/tcop/cmdtag.h +1 -1
  312. data/ext/pg_query/include/tcop/cmdtaglist.h +3 -2
  313. data/ext/pg_query/include/tcop/deparse_utility.h +1 -1
  314. data/ext/pg_query/include/tcop/dest.h +1 -1
  315. data/ext/pg_query/include/tcop/fastpath.h +1 -2
  316. data/ext/pg_query/include/tcop/pquery.h +7 -1
  317. data/ext/pg_query/include/tcop/tcopprot.h +19 -11
  318. data/ext/pg_query/include/tcop/utility.h +7 -3
  319. data/ext/pg_query/include/tsearch/ts_cache.h +2 -2
  320. data/ext/pg_query/include/utils/acl.h +24 -3
  321. data/ext/pg_query/include/utils/aclchk_internal.h +1 -1
  322. data/ext/pg_query/include/utils/array.h +7 -2
  323. data/ext/pg_query/include/utils/backend_progress.h +44 -0
  324. data/ext/pg_query/include/utils/backend_status.h +321 -0
  325. data/ext/pg_query/include/utils/builtins.h +11 -11
  326. data/ext/pg_query/include/utils/bytea.h +3 -2
  327. data/ext/pg_query/include/utils/catcache.h +1 -1
  328. data/ext/pg_query/include/utils/date.h +1 -1
  329. data/ext/pg_query/include/utils/datetime.h +8 -7
  330. data/ext/pg_query/include/utils/datum.h +9 -1
  331. data/ext/pg_query/include/utils/dsa.h +1 -1
  332. data/ext/pg_query/include/utils/dynahash.h +4 -3
  333. data/ext/pg_query/include/utils/elog.h +52 -21
  334. data/ext/pg_query/include/utils/errcodes.h +2 -0
  335. data/ext/pg_query/include/utils/expandeddatum.h +1 -1
  336. data/ext/pg_query/include/utils/expandedrecord.h +1 -1
  337. data/ext/pg_query/include/utils/float.h +7 -7
  338. data/ext/pg_query/include/utils/fmgroids.h +1300 -696
  339. data/ext/pg_query/include/utils/fmgrprotos.h +199 -16
  340. data/ext/pg_query/include/utils/fmgrtab.h +6 -5
  341. data/ext/pg_query/include/utils/guc.h +69 -43
  342. data/ext/pg_query/include/utils/guc_tables.h +23 -19
  343. data/ext/pg_query/include/utils/hsearch.h +15 -11
  344. data/ext/pg_query/include/utils/inval.h +5 -1
  345. data/ext/pg_query/include/utils/lsyscache.h +11 -1
  346. data/ext/pg_query/include/utils/memdebug.h +1 -1
  347. data/ext/pg_query/include/utils/memutils.h +8 -3
  348. data/ext/pg_query/include/utils/numeric.h +19 -5
  349. data/ext/pg_query/include/utils/palloc.h +25 -3
  350. data/ext/pg_query/include/utils/partcache.h +1 -1
  351. data/ext/pg_query/include/utils/pg_locale.h +17 -9
  352. data/ext/pg_query/include/utils/pg_lsn.h +1 -1
  353. data/ext/pg_query/include/utils/pgstat_internal.h +784 -0
  354. data/ext/pg_query/include/utils/pidfile.h +1 -1
  355. data/ext/pg_query/include/utils/plancache.h +6 -5
  356. data/ext/pg_query/include/utils/portal.h +12 -1
  357. data/ext/pg_query/include/utils/ps_status.h +1 -1
  358. data/ext/pg_query/include/utils/queryenvironment.h +1 -1
  359. data/ext/pg_query/include/utils/queryjumble.h +88 -0
  360. data/ext/pg_query/include/utils/regproc.h +14 -3
  361. data/ext/pg_query/include/utils/rel.h +71 -20
  362. data/ext/pg_query/include/utils/relcache.h +9 -7
  363. data/ext/pg_query/include/utils/reltrigger.h +1 -1
  364. data/ext/pg_query/include/utils/resowner.h +1 -1
  365. data/ext/pg_query/include/utils/rls.h +2 -2
  366. data/ext/pg_query/include/utils/ruleutils.h +4 -1
  367. data/ext/pg_query/include/utils/sharedtuplestore.h +1 -1
  368. data/ext/pg_query/include/utils/snapmgr.h +35 -14
  369. data/ext/pg_query/include/utils/snapshot.h +14 -1
  370. data/ext/pg_query/include/utils/sortsupport.h +117 -2
  371. data/ext/pg_query/include/utils/syscache.h +6 -1
  372. data/ext/pg_query/include/utils/timeout.h +11 -4
  373. data/ext/pg_query/include/utils/timestamp.h +6 -5
  374. data/ext/pg_query/include/utils/tuplesort.h +25 -11
  375. data/ext/pg_query/include/utils/tuplestore.h +2 -2
  376. data/ext/pg_query/include/utils/typcache.h +24 -17
  377. data/ext/pg_query/include/utils/tzparser.h +1 -1
  378. data/ext/pg_query/include/utils/varlena.h +5 -3
  379. data/ext/pg_query/include/utils/wait_event.h +289 -0
  380. data/ext/pg_query/include/utils/xml.h +4 -4
  381. data/ext/pg_query/pg_query.pb-c.c +4318 -2307
  382. data/ext/pg_query/pg_query_deparse.c +1114 -381
  383. data/ext/pg_query/pg_query_fingerprint.c +46 -10
  384. data/ext/pg_query/pg_query_fingerprint.h +3 -1
  385. data/ext/pg_query/pg_query_json_plpgsql.c +55 -12
  386. data/ext/pg_query/pg_query_normalize.c +163 -20
  387. data/ext/pg_query/pg_query_outfuncs.h +1 -0
  388. data/ext/pg_query/pg_query_outfuncs_json.c +65 -16
  389. data/ext/pg_query/pg_query_outfuncs_protobuf.c +70 -10
  390. data/ext/pg_query/pg_query_parse.c +1 -1
  391. data/ext/pg_query/pg_query_parse_plpgsql.c +79 -16
  392. data/ext/pg_query/pg_query_readfuncs_protobuf.c +42 -8
  393. data/ext/pg_query/pg_query_ruby.c +1 -1
  394. data/ext/pg_query/pg_query_scan.c +2 -1
  395. data/ext/pg_query/pg_query_split.c +3 -2
  396. data/ext/pg_query/src_backend_catalog_namespace.c +21 -9
  397. data/ext/pg_query/src_backend_catalog_pg_proc.c +4 -1
  398. data/ext/pg_query/src_backend_commands_define.c +11 -1
  399. data/ext/pg_query/src_backend_nodes_bitmapset.c +3 -1
  400. data/ext/pg_query/src_backend_nodes_copyfuncs.c +424 -109
  401. data/ext/pg_query/src_backend_nodes_equalfuncs.c +291 -46
  402. data/ext/pg_query/src_backend_nodes_extensible.c +1 -1
  403. data/ext/pg_query/src_backend_nodes_list.c +86 -11
  404. data/ext/pg_query/src_backend_nodes_makefuncs.c +5 -4
  405. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +55 -12
  406. data/ext/pg_query/src_backend_nodes_value.c +28 -19
  407. data/ext/pg_query/src_backend_parser_gram.c +33890 -31262
  408. data/ext/pg_query/src_backend_parser_parser.c +26 -7
  409. data/ext/pg_query/src_backend_parser_scan.c +644 -441
  410. data/ext/pg_query/src_backend_parser_scansup.c +4 -28
  411. data/ext/pg_query/src_backend_postmaster_postmaster.c +77 -106
  412. data/ext/pg_query/src_backend_storage_ipc_ipc.c +13 -4
  413. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +5 -4
  414. data/ext/pg_query/src_backend_tcop_postgres.c +73 -24
  415. data/ext/pg_query/src_backend_utils_activity_pgstat_database.c +140 -0
  416. data/ext/pg_query/src_backend_utils_adt_datum.c +13 -1
  417. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +1 -1
  418. data/ext/pg_query/src_backend_utils_adt_format_type.c +6 -2
  419. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +109 -15
  420. data/ext/pg_query/src_backend_utils_error_assert.c +16 -14
  421. data/ext/pg_query/src_backend_utils_error_elog.c +172 -99
  422. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +12 -17
  423. data/ext/pg_query/src_backend_utils_hash_dynahash.c +40 -10
  424. data/ext/pg_query/src_backend_utils_init_globals.c +5 -5
  425. data/ext/pg_query/src_backend_utils_mb_mbutils.c +55 -66
  426. data/ext/pg_query/src_backend_utils_misc_guc.c +207 -45
  427. data/ext/pg_query/src_backend_utils_mmgr_aset.c +7 -5
  428. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +123 -35
  429. data/ext/pg_query/src_common_encnames.c +1 -1
  430. data/ext/pg_query/src_common_hashfn.c +3 -3
  431. data/ext/pg_query/src_common_keywords.c +15 -2
  432. data/ext/pg_query/src_common_kwlist_d.h +517 -494
  433. data/ext/pg_query/src_common_kwlookup.c +1 -1
  434. data/ext/pg_query/src_common_pg_prng.c +152 -0
  435. data/ext/pg_query/src_common_psprintf.c +1 -1
  436. data/ext/pg_query/src_common_string.c +7 -1
  437. data/ext/pg_query/src_common_stringinfo.c +1 -1
  438. data/ext/pg_query/src_common_wchar.c +712 -109
  439. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +49 -22
  440. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +1 -18
  441. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1235 -1261
  442. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +1 -1
  443. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +10 -10
  444. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +2 -2
  445. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +54 -56
  446. data/ext/pg_query/src_port_pg_bitutils.c +41 -52
  447. data/ext/pg_query/src_port_pgsleep.c +1 -1
  448. data/ext/pg_query/src_port_pgstrcasecmp.c +1 -1
  449. data/ext/pg_query/src_port_qsort.c +12 -224
  450. data/ext/pg_query/src_port_snprintf.c +46 -20
  451. data/ext/pg_query/src_port_strerror.c +9 -19
  452. data/ext/pg_query/src_port_strnlen.c +1 -1
  453. data/lib/pg_query/deparse.rb +7 -1
  454. data/lib/pg_query/filter_columns.rb +6 -4
  455. data/lib/pg_query/fingerprint.rb +18 -3
  456. data/lib/pg_query/node.rb +2 -2
  457. data/lib/pg_query/param_refs.rb +1 -1
  458. data/lib/pg_query/parse.rb +87 -51
  459. data/lib/pg_query/pg_query_pb.rb +1109 -942
  460. data/lib/pg_query/treewalker.rb +6 -0
  461. data/lib/pg_query/truncate.rb +54 -8
  462. data/lib/pg_query/version.rb +1 -1
  463. metadata +29 -18
  464. data/ext/pg_query/include/access/xloginsert.h +0 -64
  465. data/ext/pg_query/include/bootstrap/bootstrap.h +0 -62
  466. data/ext/pg_query/include/parser/parse_clause.h +0 -54
  467. data/ext/pg_query/include/parser/parse_collate.h +0 -27
  468. data/ext/pg_query/include/parser/parse_target.h +0 -46
  469. data/ext/pg_query/src_backend_libpq_pqcomm.c +0 -651
  470. data/ext/pg_query/src_backend_parser_parse_expr.c +0 -313
  471. data/ext/pg_query/src_port_erand48.c +0 -127
  472. data/ext/pg_query/src_port_random.c +0 -31
@@ -93,34 +93,48 @@ _fingerprintString(FingerprintContext *ctx, const char *str)
93
93
  }
94
94
 
95
95
  static void
96
- _fingerprintInteger(FingerprintContext *ctx, const Value *node)
96
+ _fingerprintInteger(FingerprintContext *ctx, const union ValUnion *value)
97
97
  {
98
- if (node->val.ival != 0) {
98
+ if (value->ival.ival != 0) {
99
99
  _fingerprintString(ctx, "Integer");
100
100
  _fingerprintString(ctx, "ival");
101
101
  char buffer[50];
102
- sprintf(buffer, "%d", node->val.ival);
102
+ sprintf(buffer, "%d", value->ival.ival);
103
103
  _fingerprintString(ctx, buffer);
104
104
  }
105
105
  }
106
106
 
107
107
  static void
108
- _fingerprintFloat(FingerprintContext *ctx, const Value *node)
108
+ _fingerprintFloat(FingerprintContext *ctx, const union ValUnion *value)
109
109
  {
110
- if (node->val.str != NULL) {
110
+ if (value->fval.fval != NULL) {
111
+ // NB: We output `str` here intentionally, to match the output format from libpg_query 14
112
+ // and below. This results in stable fingerprints, despite the field name being changed in
113
+ // PG15 to `fval`.
111
114
  _fingerprintString(ctx, "Float");
112
115
  _fingerprintString(ctx, "str");
113
- _fingerprintString(ctx, node->val.str);
116
+ _fingerprintString(ctx, value->fval.fval);
114
117
  }
115
118
  }
116
119
 
117
120
  static void
118
- _fingerprintBitString(FingerprintContext *ctx, const Value *node)
121
+ _fingerprintBoolean(FingerprintContext *ctx, const union ValUnion *value)
119
122
  {
120
- if (node->val.str != NULL) {
123
+ _fingerprintString(ctx, "Boolean");
124
+ _fingerprintString(ctx, "boolval");
125
+ _fingerprintString(ctx, value->boolval.boolval ? "true" : "false");
126
+ }
127
+
128
+ static void
129
+ _fingerprintBitString(FingerprintContext *ctx, const union ValUnion *value)
130
+ {
131
+ if (value->bsval.bsval != NULL) {
132
+ // NB: We output `str` here intentionally, to match the output format from libpg_query 14
133
+ // and below. This results in stable fingerprints, despite the field name being changed in
134
+ // PG15 to `bsval`.
121
135
  _fingerprintString(ctx, "BitString");
122
136
  _fingerprintString(ctx, "str");
123
- _fingerprintString(ctx, node->val.str);
137
+ _fingerprintString(ctx, value->bsval.bsval);
124
138
  }
125
139
  }
126
140
 
@@ -272,10 +286,16 @@ _fingerprintNode(FingerprintContext *ctx, const void *obj, const void *parent, c
272
286
  case T_Float:
273
287
  _fingerprintFloat(ctx, obj);
274
288
  break;
289
+ case T_Boolean:
290
+ _fingerprintBoolean(ctx, obj);
291
+ break;
275
292
  case T_String:
293
+ // NB: We output `str` here intentionally, to match the output format from libpg_query
294
+ // 14 and below. This results in stable fingerprints, despite the field name being
295
+ // changed in PG15 to `sval`.
276
296
  _fingerprintString(ctx, "String");
277
297
  _fingerprintString(ctx, "str");
278
- _fingerprintString(ctx, ((Value*) obj)->val.str);
298
+ _fingerprintString(ctx, ((union ValUnion*) obj)->sval.sval);
279
299
  break;
280
300
  case T_BitString:
281
301
  _fingerprintBitString(ctx, obj);
@@ -291,6 +311,21 @@ _fingerprintNode(FingerprintContext *ctx, const void *obj, const void *parent, c
291
311
  }
292
312
  }
293
313
 
314
+ uint64_t pg_query_fingerprint_node(const void *node)
315
+ {
316
+ FingerprintContext ctx;
317
+ uint64 result;
318
+
319
+ _fingerprintInitContext(&ctx, NULL, false);
320
+ _fingerprintNode(&ctx, node, NULL, NULL, 0);
321
+
322
+ result = XXH3_64bits_digest(ctx.xxh_state);
323
+
324
+ _fingerprintFreeContext(&ctx);
325
+
326
+ return result;
327
+ }
328
+
294
329
  PgQueryFingerprintResult pg_query_fingerprint_with_opts(const char* input, bool printTokens)
295
330
  {
296
331
  MemoryContext ctx = NULL;
@@ -359,6 +394,7 @@ void pg_query_free_fingerprint_result(PgQueryFingerprintResult result)
359
394
  if (result.error) {
360
395
  free(result.error->message);
361
396
  free(result.error->filename);
397
+ free(result.error->funcname);
362
398
  free(result.error);
363
399
  }
364
400
 
@@ -3,6 +3,8 @@
3
3
 
4
4
  #include <stdbool.h>
5
5
 
6
- PgQueryFingerprintResult pg_query_fingerprint_with_opts(const char* input, bool printTokens);
6
+ extern PgQueryFingerprintResult pg_query_fingerprint_with_opts(const char* input, bool printTokens);
7
+
8
+ extern uint64_t pg_query_fingerprint_node(const void * node);
7
9
 
8
10
  #endif
@@ -96,7 +96,6 @@ static void dump_row(StringInfo out, PLpgSQL_row *stmt);
96
96
  static void dump_var(StringInfo out, PLpgSQL_var *stmt);
97
97
  static void dump_variable(StringInfo out, PLpgSQL_variable *stmt);
98
98
  static void dump_record_field(StringInfo out, PLpgSQL_recfield *node);
99
- static void dump_array_elem(StringInfo out, PLpgSQL_arrayelem *node);
100
99
  static void dump_stmt(StringInfo out, PLpgSQL_stmt *stmt);
101
100
  static void dump_block(StringInfo out, PLpgSQL_stmt_block *block);
102
101
  static void dump_exception_block(StringInfo out, PLpgSQL_exception_block *node);
@@ -117,6 +116,7 @@ static void dump_return_next(StringInfo out, PLpgSQL_stmt_return_next *stmt);
117
116
  static void dump_return_query(StringInfo out, PLpgSQL_stmt_return_query *stmt);
118
117
  static void dump_raise(StringInfo out, PLpgSQL_stmt_raise *stmt);
119
118
  static void dump_raise_option(StringInfo out, PLpgSQL_raise_option *node);
119
+ static void dump_assert(StringInfo out, PLpgSQL_stmt_assert *stmt);
120
120
  static void dump_execsql(StringInfo out, PLpgSQL_stmt_execsql *stmt);
121
121
  static void dump_dynexecute(StringInfo out, PLpgSQL_stmt_dynexecute *stmt);
122
122
  static void dump_dynfors(StringInfo out, PLpgSQL_stmt_dynfors *stmt);
@@ -126,6 +126,9 @@ static void dump_open(StringInfo out, PLpgSQL_stmt_open *stmt);
126
126
  static void dump_fetch(StringInfo out, PLpgSQL_stmt_fetch *stmt);
127
127
  static void dump_close(StringInfo out, PLpgSQL_stmt_close *stmt);
128
128
  static void dump_perform(StringInfo out, PLpgSQL_stmt_perform *stmt);
129
+ static void dump_call(StringInfo out, PLpgSQL_stmt_call *stmt);
130
+ static void dump_commit(StringInfo out, PLpgSQL_stmt_commit *stmt);
131
+ static void dump_rollback(StringInfo out, PLpgSQL_stmt_rollback *stmt);
129
132
  static void dump_expr(StringInfo out, PLpgSQL_expr *expr);
130
133
  static void dump_function(StringInfo out, PLpgSQL_function *func);
131
134
  static void dump_exception(StringInfo out, PLpgSQL_exception *node);
@@ -183,6 +186,9 @@ dump_stmt(StringInfo out, PLpgSQL_stmt *node)
183
186
  case PLPGSQL_STMT_RAISE:
184
187
  dump_raise(out, (PLpgSQL_stmt_raise *) node);
185
188
  break;
189
+ case PLPGSQL_STMT_ASSERT:
190
+ dump_assert(out, (PLpgSQL_stmt_assert *) node);
191
+ break;
186
192
  case PLPGSQL_STMT_EXECSQL:
187
193
  dump_execsql(out, (PLpgSQL_stmt_execsql *) node);
188
194
  break;
@@ -207,6 +213,15 @@ dump_stmt(StringInfo out, PLpgSQL_stmt *node)
207
213
  case PLPGSQL_STMT_PERFORM:
208
214
  dump_perform(out, (PLpgSQL_stmt_perform *) node);
209
215
  break;
216
+ case PLPGSQL_STMT_CALL:
217
+ dump_call(out, (PLpgSQL_stmt_call *) node);
218
+ break;
219
+ case PLPGSQL_STMT_COMMIT:
220
+ dump_commit(out, (PLpgSQL_stmt_commit *) node);
221
+ break;
222
+ case PLPGSQL_STMT_ROLLBACK:
223
+ dump_rollback(out, (PLpgSQL_stmt_rollback *) node);
224
+ break;
210
225
  default:
211
226
  elog(ERROR, "unrecognized cmd_type: %d", node->cmd_type);
212
227
  break;
@@ -444,6 +459,35 @@ dump_perform(StringInfo out, PLpgSQL_stmt_perform *node)
444
459
  WRITE_EXPR_FIELD(expr);
445
460
  }
446
461
 
462
+ static void
463
+ dump_call(StringInfo out, PLpgSQL_stmt_call *node)
464
+ {
465
+ WRITE_NODE_TYPE("PLpgSQL_stmt_call");
466
+
467
+ WRITE_INT_FIELD(lineno, lineno, lineno);
468
+ WRITE_EXPR_FIELD(expr);
469
+ WRITE_BOOL_FIELD(is_call, is_call, is_call);
470
+ WRITE_VARIABLE_FIELD(target);
471
+ }
472
+
473
+ static void
474
+ dump_commit(StringInfo out, PLpgSQL_stmt_commit *node)
475
+ {
476
+ WRITE_NODE_TYPE("PLpgSQL_stmt_commit");
477
+
478
+ WRITE_INT_FIELD(lineno, lineno, lineno);
479
+ WRITE_BOOL_FIELD(chain, chain, chain);
480
+ }
481
+
482
+ static void
483
+ dump_rollback(StringInfo out, PLpgSQL_stmt_rollback *node)
484
+ {
485
+ WRITE_NODE_TYPE("PLpgSQL_stmt_rollback");
486
+
487
+ WRITE_INT_FIELD(lineno, lineno, lineno);
488
+ WRITE_BOOL_FIELD(chain, chain, chain);
489
+ }
490
+
447
491
  static void
448
492
  dump_exit(StringInfo out, PLpgSQL_stmt_exit *node)
449
493
  {
@@ -508,6 +552,16 @@ dump_raise_option(StringInfo out, PLpgSQL_raise_option *node)
508
552
  WRITE_EXPR_FIELD(expr);
509
553
  }
510
554
 
555
+ static void
556
+ dump_assert(StringInfo out, PLpgSQL_stmt_assert *node)
557
+ {
558
+ WRITE_NODE_TYPE("PLpgSQL_stmt_assert");
559
+
560
+ WRITE_INT_FIELD(lineno, lineno, lineno);
561
+ WRITE_EXPR_FIELD(cond);
562
+ WRITE_EXPR_FIELD(message);
563
+ }
564
+
511
565
  static void
512
566
  dump_execsql(StringInfo out, PLpgSQL_stmt_execsql *node)
513
567
  {
@@ -605,9 +659,6 @@ dump_function(StringInfo out, PLpgSQL_function *node)
605
659
  case PLPGSQL_DTYPE_RECFIELD:
606
660
  dump_record_field(out, (PLpgSQL_recfield *) d);
607
661
  break;
608
- case PLPGSQL_DTYPE_ARRAYELEM:
609
- dump_array_elem(out, (PLpgSQL_arrayelem *) d);
610
- break;
611
662
  default:
612
663
  elog(WARNING, "could not dump unrecognized dtype: %d",
613
664
  (int) d->dtype);
@@ -712,14 +763,6 @@ dump_record_field(StringInfo out, PLpgSQL_recfield *node) {
712
763
  WRITE_INT_FIELD(recparentno, recparentno, recparentno);
713
764
  }
714
765
 
715
- static void
716
- dump_array_elem(StringInfo out, PLpgSQL_arrayelem *node) {
717
- WRITE_NODE_TYPE("PLpgSQL_arrayelem");
718
-
719
- WRITE_EXPR_FIELD(subscript);
720
- WRITE_INT_FIELD(arrayparentno, arrayparentno, arrayparentno);
721
- }
722
-
723
766
  char *
724
767
  plpgsqlToJSON(PLpgSQL_function *func)
725
768
  {
@@ -1,5 +1,6 @@
1
1
  #include "pg_query.h"
2
2
  #include "pg_query_internal.h"
3
+ #include "pg_query_fingerprint.h"
3
4
 
4
5
  #include "parser/parser.h"
5
6
  #include "parser/scanner.h"
@@ -7,6 +8,8 @@
7
8
  #include "mb/pg_wchar.h"
8
9
  #include "nodes/nodeFuncs.h"
9
10
 
11
+ #include "pg_query_outfuncs.h"
12
+
10
13
  /*
11
14
  * Struct for tracking locations/lengths of constants during normalization
12
15
  */
@@ -14,6 +17,7 @@ typedef struct pgssLocationLen
14
17
  {
15
18
  int location; /* start offset in query text */
16
19
  int length; /* length in bytes, or -1 to ignore */
20
+ int param_id; /* Param id to use - if negative prefix, need to abs(..) and add highest_extern_param_id */
17
21
  } pgssLocationLen;
18
22
 
19
23
  /*
@@ -30,14 +34,32 @@ typedef struct pgssConstLocations
30
34
  /* Current number of valid entries in clocations array */
31
35
  int clocations_count;
32
36
 
37
+ /* highest Param id we have assigned, not yet taking into account external param refs */
38
+ int highest_normalize_param_id;
39
+
33
40
  /* highest Param id we've seen, in order to start normalization correctly */
34
41
  int highest_extern_param_id;
35
42
 
36
43
  /* query text */
37
44
  const char * query;
38
45
  int query_len;
46
+
47
+ /* optional recording of assigned or discovered param refs, only active if param_refs is not NULL */
48
+ int *param_refs;
49
+ int param_refs_buf_size;
50
+ int param_refs_count;
39
51
  } pgssConstLocations;
40
52
 
53
+ /*
54
+ * Intermediate working state struct to remember param refs for individual target list elements
55
+ */
56
+ typedef struct FpAndParamRefs
57
+ {
58
+ uint64_t fp;
59
+ int* param_refs;
60
+ int param_refs_count;
61
+ } FpAndParamRefs;
62
+
41
63
  /*
42
64
  * comp_location: comparator for qsorting pgssLocationLen structs by location
43
65
  */
@@ -230,7 +252,8 @@ generate_normalized_query(pgssConstLocations *jstate, int query_loc, int* query_
230
252
  for (i = 0; i < jstate->clocations_count; i++)
231
253
  {
232
254
  int off, /* Offset from start for cur tok */
233
- tok_len; /* Length (in bytes) of that tok */
255
+ tok_len, /* Length (in bytes) of that tok */
256
+ param_id; /* Param ID to be assigned */
234
257
 
235
258
  off = jstate->clocations[i].location;
236
259
  /* Adjust recorded location if we're dealing with partial string */
@@ -250,8 +273,10 @@ generate_normalized_query(pgssConstLocations *jstate, int query_loc, int* query_
250
273
  n_quer_loc += len_to_wrt;
251
274
 
252
275
  /* And insert a param symbol in place of the constant token */
253
- n_quer_loc += sprintf(norm_query + n_quer_loc, "$%d",
254
- i + 1 + jstate->highest_extern_param_id);
276
+ param_id = (jstate->clocations[i].param_id < 0) ?
277
+ jstate->highest_extern_param_id + abs(jstate->clocations[i].param_id) :
278
+ jstate->clocations[i].param_id;
279
+ n_quer_loc += sprintf(norm_query + n_quer_loc, "$%d", param_id);
255
280
 
256
281
  quer_loc = off + tok_len;
257
282
  last_off = off;
@@ -292,10 +317,43 @@ static void RecordConstLocation(pgssConstLocations *jstate, int location)
292
317
  jstate->clocations[jstate->clocations_count].location = location;
293
318
  /* initialize lengths to -1 to simplify fill_in_constant_lengths */
294
319
  jstate->clocations[jstate->clocations_count].length = -1;
320
+ /* by default we assume that we need a new param ref */
321
+ jstate->clocations[jstate->clocations_count].param_id = - jstate->highest_normalize_param_id;
322
+ jstate->highest_normalize_param_id++;
323
+ /* record param ref number if requested */
324
+ if (jstate->param_refs != NULL) {
325
+ jstate->param_refs[jstate->param_refs_count] = jstate->clocations[jstate->clocations_count].param_id;
326
+ jstate->param_refs_count++;
327
+ if (jstate->param_refs_count >= jstate->param_refs_buf_size) {
328
+ jstate->param_refs_buf_size *= 2;
329
+ jstate->param_refs = (int *) repalloc(jstate->param_refs, jstate->param_refs_buf_size * sizeof(int));
330
+ }
331
+ }
295
332
  jstate->clocations_count++;
296
333
  }
297
334
  }
298
335
 
336
+ static void record_defelem_arg_location(pgssConstLocations *jstate, int location)
337
+ {
338
+ for (int i = location; i < jstate->query_len; i++) {
339
+ if (jstate->query[i] == '\'' || jstate->query[i] == '$') {
340
+ RecordConstLocation(jstate, i);
341
+ break;
342
+ }
343
+ }
344
+ }
345
+
346
+ static void record_matching_string(pgssConstLocations *jstate, const char *str)
347
+ {
348
+ char *loc = NULL;
349
+ if (str == NULL)
350
+ return;
351
+
352
+ loc = strstr(jstate->query, str);
353
+ if (loc != NULL)
354
+ RecordConstLocation(jstate, loc - jstate->query - 1);
355
+ }
356
+
299
357
  static bool const_record_walker(Node *node, pgssConstLocations *jstate)
300
358
  {
301
359
  bool result;
@@ -313,18 +371,26 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate)
313
371
  /* Track the highest ParamRef number */
314
372
  if (((ParamRef *) node)->number > jstate->highest_extern_param_id)
315
373
  jstate->highest_extern_param_id = castNode(ParamRef, node)->number;
374
+
375
+ if (jstate->param_refs != NULL) {
376
+ jstate->param_refs[jstate->param_refs_count] = ((ParamRef *) node)->number;
377
+ jstate->param_refs_count++;
378
+ if (jstate->param_refs_count >= jstate->param_refs_buf_size) {
379
+ jstate->param_refs_buf_size *= 2;
380
+ jstate->param_refs = (int *) repalloc(jstate->param_refs, jstate->param_refs_buf_size * sizeof(int));
381
+ }
382
+ }
316
383
  }
317
384
  break;
318
385
  case T_DefElem:
319
386
  {
320
387
  DefElem * defElem = (DefElem *) node;
321
- if (defElem->arg != NULL && IsA(defElem->arg, String)) {
322
- for (int i = defElem->location; i < jstate->query_len; i++) {
323
- if (jstate->query[i] == '\'') {
324
- RecordConstLocation(jstate, i);
325
- break;
326
- }
327
- }
388
+ if (defElem->arg == NULL) {
389
+ // No argument
390
+ } else if (IsA(defElem->arg, String)) {
391
+ record_defelem_arg_location(jstate, defElem->location);
392
+ } else if (IsA(defElem->arg, List) && list_length((List *) defElem->arg) == 1 && IsA(linitial((List *) defElem->arg), String)) {
393
+ record_defelem_arg_location(jstate, defElem->location);
328
394
  }
329
395
  return const_record_walker((Node *) ((DefElem *) node)->arg, jstate);
330
396
  }
@@ -343,39 +409,109 @@ static bool const_record_walker(Node *node, pgssConstLocations *jstate)
343
409
  return const_record_walker((Node *) ((AlterRoleStmt *) node)->options, jstate);
344
410
  case T_DeclareCursorStmt:
345
411
  return const_record_walker((Node *) ((DeclareCursorStmt *) node)->query, jstate);
412
+ case T_CreateFunctionStmt:
413
+ return const_record_walker((Node *) ((CreateFunctionStmt *) node)->options, jstate);
414
+ case T_DoStmt:
415
+ return const_record_walker((Node *) ((DoStmt *) node)->args, jstate);
416
+ case T_CreateSubscriptionStmt:
417
+ record_matching_string(jstate, ((CreateSubscriptionStmt *) node)->conninfo);
418
+ break;
419
+ case T_AlterSubscriptionStmt:
420
+ record_matching_string(jstate, ((CreateSubscriptionStmt *) node)->conninfo);
421
+ break;
422
+ case T_CreateUserMappingStmt:
423
+ return const_record_walker((Node *) ((CreateUserMappingStmt *) node)->options, jstate);
424
+ case T_AlterUserMappingStmt:
425
+ return const_record_walker((Node *) ((AlterUserMappingStmt *) node)->options, jstate);
426
+ case T_TypeName:
427
+ /* Don't normalize constants in typmods or arrayBounds */
428
+ return false;
346
429
  case T_SelectStmt:
347
430
  {
348
431
  SelectStmt *stmt = (SelectStmt *) node;
349
432
  ListCell *lc;
433
+ List *fp_and_param_refs_list = NIL;
350
434
 
351
435
  if (const_record_walker((Node *) stmt->distinctClause, jstate))
352
436
  return true;
353
437
  if (const_record_walker((Node *) stmt->intoClause, jstate))
354
438
  return true;
355
- if (const_record_walker((Node *) stmt->targetList, jstate))
356
- return true;
439
+ foreach(lc, stmt->targetList)
440
+ {
441
+ ResTarget *res_target = lfirst_node(ResTarget, lc);
442
+ FpAndParamRefs *fp_and_param_refs = palloc0(sizeof(FpAndParamRefs));
443
+
444
+ /* Save all param refs we encounter or assign */
445
+ jstate->param_refs = palloc0(1 * sizeof(int));
446
+ jstate->param_refs_buf_size = 1;
447
+ jstate->param_refs_count = 0;
448
+
449
+ /* Walk the element */
450
+ if (const_record_walker((Node *) res_target, jstate))
451
+ return true;
452
+
453
+ /* Remember fingerprint and param refs for later */
454
+ fp_and_param_refs->fp = pg_query_fingerprint_node(res_target->val);
455
+ fp_and_param_refs->param_refs = jstate->param_refs;
456
+ fp_and_param_refs->param_refs_count = jstate->param_refs_count;
457
+ fp_and_param_refs_list = lappend(fp_and_param_refs_list, fp_and_param_refs);
458
+
459
+ /* Reset for next element, or stop recording if this is the last element */
460
+ jstate->param_refs = NULL;
461
+ jstate->param_refs_buf_size = 0;
462
+ jstate->param_refs_count = 0;
463
+ }
357
464
  if (const_record_walker((Node *) stmt->fromClause, jstate))
358
465
  return true;
359
466
  if (const_record_walker((Node *) stmt->whereClause, jstate))
360
467
  return true;
361
468
 
362
- // Instead of walking all of groupClause (like raw_expression_tree_walker does),
363
- // only walk certain items.
469
+ /*
470
+ * Instead of walking all of groupClause (like raw_expression_tree_walker does),
471
+ * only walk certain items.
472
+ */
364
473
  foreach(lc, stmt->groupClause)
365
474
  {
366
- // Do not walk A_Const values that are simple integers, this avoids
367
- // turning "GROUP BY 1" into "GROUP BY $n", which obscures an important
368
- // semantic meaning. This matches how pg_stat_statements handles the
369
- // GROUP BY clause (i.e. it doesn't touch these constants)
475
+ /*
476
+ * Do not walk A_Const values that are simple integers, this avoids
477
+ * turning "GROUP BY 1" into "GROUP BY $n", which obscures an important
478
+ * semantic meaning. This matches how pg_stat_statements handles the
479
+ * GROUP BY clause (i.e. it doesn't touch these constants)
480
+ */
370
481
  if (IsA(lfirst(lc), A_Const) && IsA(&castNode(A_Const, lfirst(lc))->val, Integer))
371
482
  continue;
372
483
 
484
+ /*
485
+ * Match up GROUP BY clauses against the target list, to assign the same
486
+ * param refs as used in the target list - this ensures the query is valid,
487
+ * instead of throwing a bogus "columns ... must appear in the GROUP BY
488
+ * clause or be used in an aggregate function" error
489
+ */
490
+ uint64_t fp = pg_query_fingerprint_node(lfirst(lc));
491
+ FpAndParamRefs *fppr = NULL;
492
+ ListCell *lc2;
493
+ foreach(lc2, fp_and_param_refs_list) {
494
+ if (fp == ((FpAndParamRefs *) lfirst(lc2))->fp) {
495
+ fppr = (FpAndParamRefs *) lfirst(lc2);
496
+ foreach_delete_current(fp_and_param_refs_list, lc2);
497
+ break;
498
+ }
499
+ }
500
+
501
+ int prev_cloc_count = jstate->clocations_count;
373
502
  if (const_record_walker((Node *) lfirst(lc), jstate))
374
503
  return true;
504
+
505
+ if (fppr != NULL && fppr->param_refs_count == jstate->clocations_count - prev_cloc_count) {
506
+ for (int i = prev_cloc_count; i < jstate->clocations_count; i++) {
507
+ jstate->clocations[i].param_id = fppr->param_refs[i - prev_cloc_count];
508
+ }
509
+ jstate->highest_normalize_param_id -= fppr->param_refs_count;
510
+ }
375
511
  }
376
512
  foreach(lc, stmt->sortClause)
377
513
  {
378
- // Similarly, don't turn "ORDER BY 1" into "ORDER BY $n"
514
+ /* Similarly, don't turn "ORDER BY 1" into "ORDER BY $n" */
379
515
  if (IsA(lfirst(lc), SortBy) && IsA(castNode(SortBy, lfirst(lc))->node, A_Const) &&
380
516
  IsA(&castNode(A_Const, castNode(SortBy, lfirst(lc))->node)->val, Integer))
381
517
  continue;
@@ -436,7 +572,7 @@ PgQueryNormalizeResult pg_query_normalize(const char* input)
436
572
  int query_len;
437
573
 
438
574
  /* Parse query */
439
- tree = raw_parser(input);
575
+ tree = raw_parser(input, RAW_PARSE_DEFAULT);
440
576
 
441
577
  query_len = (int) strlen(input);
442
578
 
@@ -445,9 +581,13 @@ PgQueryNormalizeResult pg_query_normalize(const char* input)
445
581
  jstate.clocations = (pgssLocationLen *)
446
582
  palloc(jstate.clocations_buf_size * sizeof(pgssLocationLen));
447
583
  jstate.clocations_count = 0;
584
+ jstate.highest_normalize_param_id = 1;
448
585
  jstate.highest_extern_param_id = 0;
449
586
  jstate.query = input;
450
587
  jstate.query_len = query_len;
588
+ jstate.param_refs = NULL;
589
+ jstate.param_refs_buf_size = 0;
590
+ jstate.param_refs_count = 0;
451
591
 
452
592
  /* Walk tree and record const locations */
453
593
  const_record_walker((Node *) tree, &jstate);
@@ -466,6 +606,8 @@ PgQueryNormalizeResult pg_query_normalize(const char* input)
466
606
  error = malloc(sizeof(PgQueryError));
467
607
  error->message = strdup(error_data->message);
468
608
  error->filename = strdup(error_data->filename);
609
+ error->funcname = strdup(error_data->funcname);
610
+ error->context = NULL;
469
611
  error->lineno = error_data->lineno;
470
612
  error->cursorpos = error_data->cursorpos;
471
613
 
@@ -484,6 +626,7 @@ void pg_query_free_normalize_result(PgQueryNormalizeResult result)
484
626
  if (result.error) {
485
627
  free(result.error->message);
486
628
  free(result.error->filename);
629
+ free(result.error->funcname);
487
630
  free(result.error);
488
631
  }
489
632
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  PgQueryProtobuf pg_query_nodes_to_protobuf(const void *obj);
7
7
 
8
+ char *pg_query_node_to_json(const void *obj);
8
9
  char *pg_query_nodes_to_json(const void *obj);
9
10
 
10
11
  #endif
@@ -195,39 +195,77 @@ _outOidList(StringInfo out, const List *node)
195
195
  }
196
196
 
197
197
  static void
198
- _outInteger(StringInfo out, const Value *node)
198
+ _outInteger(StringInfo out, const Integer *node)
199
199
  {
200
- appendStringInfo(out, "\"ival\":%d,", node->val.ival);
200
+ if (node->ival > 0)
201
+ appendStringInfo(out, "\"ival\":%d", node->ival);
201
202
  }
202
203
 
203
204
  static void
204
- _outFloat(StringInfo out, const Value *node)
205
+ _outBoolean(StringInfo out, const Boolean *node)
205
206
  {
206
- appendStringInfo(out, "\"str\":");
207
- _outToken(out, node->val.str);
208
- appendStringInfo(out, ",");
207
+ appendStringInfo(out, "\"boolval\":%s", booltostr(node->boolval));
209
208
  }
210
209
 
211
210
  static void
212
- _outString(StringInfo out, const Value *node)
211
+ _outFloat(StringInfo out, const Float *node)
213
212
  {
214
- appendStringInfo(out, "\"str\":");
215
- _outToken(out, node->val.str);
216
- appendStringInfo(out, ",");
213
+ appendStringInfo(out, "\"fval\":");
214
+ _outToken(out, node->fval);
217
215
  }
218
216
 
219
217
  static void
220
- _outBitString(StringInfo out, const Value *node)
218
+ _outString(StringInfo out, const String *node)
221
219
  {
222
- appendStringInfo(out, "\"str\":");
223
- _outToken(out, node->val.str);
224
- appendStringInfo(out, ",");
220
+ appendStringInfo(out, "\"sval\":");
221
+ _outToken(out, node->sval);
222
+ }
223
+
224
+ static void
225
+ _outBitString(StringInfo out, const BitString *node)
226
+ {
227
+ appendStringInfo(out, "\"bsval\":");
228
+ _outToken(out, node->bsval);
225
229
  }
226
230
 
227
231
  static void
228
- _outNull(StringInfo out, const Value *node)
232
+ _outAConst(StringInfo out, const A_Const *node)
229
233
  {
230
- // No fields
234
+ if (node->isnull) {
235
+ appendStringInfo(out, "\"isnull\":true");
236
+ } else {
237
+ switch (node->val.node.type) {
238
+ case T_Integer:
239
+ appendStringInfoString(out, "\"ival\":{");
240
+ _outInteger(out, &node->val.ival);
241
+ appendStringInfoChar(out, '}');
242
+ break;
243
+ case T_Float:
244
+ appendStringInfoString(out, "\"fval\":{");
245
+ _outFloat(out, &node->val.fval);
246
+ appendStringInfoChar(out, '}');
247
+ break;
248
+ case T_Boolean:
249
+ appendStringInfo(out, "\"boolval\":{%s}", node->val.boolval.boolval ? "\"boolval\":true" : "");
250
+ break;
251
+ case T_String:
252
+ appendStringInfoString(out, "\"sval\":{");
253
+ _outString(out, &node->val.sval);
254
+ appendStringInfoChar(out, '}');
255
+ break;
256
+ case T_BitString:
257
+ appendStringInfoString(out, "\"bsval\":{");
258
+ _outBitString(out, &node->val.bsval);
259
+ appendStringInfoChar(out, '}');
260
+ break;
261
+
262
+ // Unreachable, A_Const cannot contain any other nodes.
263
+ default:
264
+ Assert(false);
265
+ }
266
+ }
267
+
268
+ appendStringInfo(out, ",\"location\":%d", node->location);
231
269
  }
232
270
 
233
271
  #include "pg_query_enum_defs.c"
@@ -259,6 +297,17 @@ _outNode(StringInfo out, const void *obj)
259
297
  }
260
298
  }
261
299
 
300
+ char *
301
+ pg_query_node_to_json(const void *obj)
302
+ {
303
+ StringInfoData out;
304
+
305
+ initStringInfo(&out);
306
+ _outNode(&out, obj);
307
+
308
+ return out.data;
309
+ }
310
+
262
311
  char *
263
312
  pg_query_nodes_to_json(const void *obj)
264
313
  {