pg_query 5.1.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (479) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -0
  3. data/README.md +1 -1
  4. data/Rakefile +2 -2
  5. data/ext/pg_query/include/pg_query.h +4 -3
  6. data/ext/pg_query/include/pg_query_enum_defs.c +424 -154
  7. data/ext/pg_query/include/pg_query_fingerprint_conds.c +68 -4
  8. data/ext/pg_query/include/pg_query_fingerprint_defs.c +2952 -1845
  9. data/ext/pg_query/include/pg_query_outfuncs_conds.c +51 -3
  10. data/ext/pg_query/include/pg_query_outfuncs_defs.c +210 -23
  11. data/ext/pg_query/include/pg_query_readfuncs_conds.c +17 -1
  12. data/ext/pg_query/include/pg_query_readfuncs_defs.c +271 -52
  13. data/ext/pg_query/include/postgres/access/amapi.h +10 -3
  14. data/ext/pg_query/include/postgres/access/attmap.h +1 -1
  15. data/ext/pg_query/include/postgres/access/attnum.h +1 -1
  16. data/ext/pg_query/include/postgres/access/brin_internal.h +116 -0
  17. data/ext/pg_query/include/postgres/access/brin_tuple.h +112 -0
  18. data/ext/pg_query/include/postgres/access/clog.h +2 -3
  19. data/ext/pg_query/include/postgres/access/commit_ts.h +2 -3
  20. data/ext/pg_query/include/postgres/access/detoast.h +1 -1
  21. data/ext/pg_query/include/postgres/access/genam.h +8 -4
  22. data/ext/pg_query/include/postgres/access/gin.h +1 -1
  23. data/ext/pg_query/include/postgres/access/htup.h +1 -1
  24. data/ext/pg_query/include/postgres/access/htup_details.h +11 -11
  25. data/ext/pg_query/include/postgres/access/itup.h +3 -3
  26. data/ext/pg_query/include/postgres/access/parallel.h +1 -2
  27. data/ext/pg_query/include/postgres/access/printtup.h +1 -1
  28. data/ext/pg_query/include/postgres/access/relation.h +1 -1
  29. data/ext/pg_query/include/postgres/access/relscan.h +1 -1
  30. data/ext/pg_query/include/postgres/access/rmgrlist.h +1 -1
  31. data/ext/pg_query/include/postgres/access/sdir.h +1 -1
  32. data/ext/pg_query/include/postgres/access/skey.h +1 -1
  33. data/ext/pg_query/include/postgres/access/slru.h +221 -0
  34. data/ext/pg_query/include/postgres/access/stratnum.h +1 -1
  35. data/ext/pg_query/include/postgres/access/sysattr.h +1 -1
  36. data/ext/pg_query/include/postgres/access/table.h +1 -1
  37. data/ext/pg_query/include/postgres/access/tableam.h +33 -24
  38. data/ext/pg_query/include/postgres/access/tidstore.h +50 -0
  39. data/ext/pg_query/include/postgres/access/toast_compression.h +2 -2
  40. data/ext/pg_query/include/postgres/access/transam.h +7 -7
  41. data/ext/pg_query/include/postgres/access/tsmapi.h +1 -1
  42. data/ext/pg_query/include/postgres/access/tupconvert.h +1 -1
  43. data/ext/pg_query/include/postgres/access/tupdesc.h +5 -5
  44. data/ext/pg_query/include/postgres/access/tupmacs.h +1 -1
  45. data/ext/pg_query/include/postgres/access/twophase.h +2 -2
  46. data/ext/pg_query/include/postgres/access/xact.h +5 -5
  47. data/ext/pg_query/include/postgres/access/xlog.h +20 -12
  48. data/ext/pg_query/include/postgres/access/xlog_internal.h +4 -3
  49. data/ext/pg_query/include/postgres/access/xlogbackup.h +3 -1
  50. data/ext/pg_query/include/postgres/access/xlogdefs.h +5 -5
  51. data/ext/pg_query/include/postgres/access/xlogprefetcher.h +2 -2
  52. data/ext/pg_query/include/postgres/access/xlogreader.h +2 -2
  53. data/ext/pg_query/include/postgres/access/xlogrecord.h +3 -3
  54. data/ext/pg_query/include/postgres/access/xlogrecovery.h +4 -4
  55. data/ext/pg_query/include/postgres/archive/archive_module.h +9 -1
  56. data/ext/pg_query/include/postgres/c.h +31 -36
  57. data/ext/pg_query/include/postgres/catalog/catalog.h +3 -1
  58. data/ext/pg_query/include/postgres/catalog/catversion.h +2 -2
  59. data/ext/pg_query/include/postgres/catalog/dependency.h +17 -59
  60. data/ext/pg_query/include/postgres/catalog/genbki.h +12 -6
  61. data/ext/pg_query/include/postgres/catalog/index.h +22 -18
  62. data/ext/pg_query/include/postgres/catalog/indexing.h +1 -1
  63. data/ext/pg_query/include/postgres/catalog/namespace.h +18 -19
  64. data/ext/pg_query/include/postgres/catalog/objectaccess.h +2 -2
  65. data/ext/pg_query/include/postgres/catalog/objectaddress.h +1 -1
  66. data/ext/pg_query/include/postgres/catalog/pg_aggregate.h +4 -2
  67. data/ext/pg_query/include/postgres/catalog/pg_aggregate_d.h +1 -1
  68. data/ext/pg_query/include/postgres/catalog/pg_am.h +6 -3
  69. data/ext/pg_query/include/postgres/catalog/pg_am_d.h +1 -1
  70. data/ext/pg_query/include/postgres/catalog/pg_attribute.h +31 -14
  71. data/ext/pg_query/include/postgres/catalog/pg_attribute_d.h +3 -3
  72. data/ext/pg_query/include/postgres/catalog/pg_authid.h +6 -3
  73. data/ext/pg_query/include/postgres/catalog/pg_authid_d.h +2 -1
  74. data/ext/pg_query/include/postgres/catalog/pg_class.h +10 -5
  75. data/ext/pg_query/include/postgres/catalog/pg_class_d.h +4 -2
  76. data/ext/pg_query/include/postgres/catalog/pg_collation.h +11 -5
  77. data/ext/pg_query/include/postgres/catalog/pg_collation_d.h +5 -2
  78. data/ext/pg_query/include/postgres/catalog/pg_constraint.h +15 -10
  79. data/ext/pg_query/include/postgres/catalog/pg_constraint_d.h +2 -1
  80. data/ext/pg_query/include/postgres/catalog/pg_control.h +5 -3
  81. data/ext/pg_query/include/postgres/catalog/pg_conversion.h +8 -4
  82. data/ext/pg_query/include/postgres/catalog/pg_conversion_d.h +1 -1
  83. data/ext/pg_query/include/postgres/catalog/pg_database.h +9 -4
  84. data/ext/pg_query/include/postgres/catalog/pg_database_d.h +13 -12
  85. data/ext/pg_query/include/postgres/catalog/pg_depend.h +3 -3
  86. data/ext/pg_query/include/postgres/catalog/pg_depend_d.h +1 -1
  87. data/ext/pg_query/include/postgres/catalog/pg_event_trigger.h +6 -3
  88. data/ext/pg_query/include/postgres/catalog/pg_event_trigger_d.h +1 -1
  89. data/ext/pg_query/include/postgres/catalog/pg_index.h +5 -3
  90. data/ext/pg_query/include/postgres/catalog/pg_index_d.h +1 -1
  91. data/ext/pg_query/include/postgres/catalog/pg_language.h +6 -3
  92. data/ext/pg_query/include/postgres/catalog/pg_language_d.h +1 -1
  93. data/ext/pg_query/include/postgres/catalog/pg_namespace.h +6 -3
  94. data/ext/pg_query/include/postgres/catalog/pg_namespace_d.h +1 -1
  95. data/ext/pg_query/include/postgres/catalog/pg_opclass.h +6 -3
  96. data/ext/pg_query/include/postgres/catalog/pg_opclass_d.h +1 -1
  97. data/ext/pg_query/include/postgres/catalog/pg_operator.h +20 -3
  98. data/ext/pg_query/include/postgres/catalog/pg_operator_d.h +1 -1
  99. data/ext/pg_query/include/postgres/catalog/pg_opfamily.h +6 -3
  100. data/ext/pg_query/include/postgres/catalog/pg_opfamily_d.h +1 -1
  101. data/ext/pg_query/include/postgres/catalog/pg_partitioned_table.h +4 -2
  102. data/ext/pg_query/include/postgres/catalog/pg_partitioned_table_d.h +1 -1
  103. data/ext/pg_query/include/postgres/catalog/pg_proc.h +6 -3
  104. data/ext/pg_query/include/postgres/catalog/pg_proc_d.h +1 -1
  105. data/ext/pg_query/include/postgres/catalog/pg_publication.h +6 -3
  106. data/ext/pg_query/include/postgres/catalog/pg_publication_d.h +1 -1
  107. data/ext/pg_query/include/postgres/catalog/pg_replication_origin.h +6 -3
  108. data/ext/pg_query/include/postgres/catalog/pg_replication_origin_d.h +1 -1
  109. data/ext/pg_query/include/postgres/catalog/pg_statistic.h +10 -4
  110. data/ext/pg_query/include/postgres/catalog/pg_statistic_d.h +7 -3
  111. data/ext/pg_query/include/postgres/catalog/pg_statistic_ext.h +10 -7
  112. data/ext/pg_query/include/postgres/catalog/pg_statistic_ext_d.h +3 -3
  113. data/ext/pg_query/include/postgres/catalog/pg_transform.h +6 -3
  114. data/ext/pg_query/include/postgres/catalog/pg_transform_d.h +1 -1
  115. data/ext/pg_query/include/postgres/catalog/pg_trigger.h +4 -4
  116. data/ext/pg_query/include/postgres/catalog/pg_trigger_d.h +1 -1
  117. data/ext/pg_query/include/postgres/catalog/pg_ts_config.h +6 -3
  118. data/ext/pg_query/include/postgres/catalog/pg_ts_config_d.h +1 -1
  119. data/ext/pg_query/include/postgres/catalog/pg_ts_dict.h +6 -3
  120. data/ext/pg_query/include/postgres/catalog/pg_ts_dict_d.h +1 -1
  121. data/ext/pg_query/include/postgres/catalog/pg_ts_parser.h +6 -3
  122. data/ext/pg_query/include/postgres/catalog/pg_ts_parser_d.h +1 -1
  123. data/ext/pg_query/include/postgres/catalog/pg_ts_template.h +6 -3
  124. data/ext/pg_query/include/postgres/catalog/pg_ts_template_d.h +1 -1
  125. data/ext/pg_query/include/postgres/catalog/pg_type.h +6 -3
  126. data/ext/pg_query/include/postgres/catalog/pg_type_d.h +1 -1
  127. data/ext/pg_query/include/postgres/catalog/storage.h +1 -1
  128. data/ext/pg_query/include/postgres/catalog/syscache_ids.h +104 -0
  129. data/ext/pg_query/include/postgres/commands/async.h +2 -6
  130. data/ext/pg_query/include/postgres/commands/dbcommands.h +1 -1
  131. data/ext/pg_query/include/postgres/commands/defrem.h +6 -6
  132. data/ext/pg_query/include/postgres/commands/event_trigger.h +5 -2
  133. data/ext/pg_query/include/postgres/commands/explain.h +19 -3
  134. data/ext/pg_query/include/postgres/commands/prepare.h +1 -1
  135. data/ext/pg_query/include/postgres/commands/tablespace.h +1 -1
  136. data/ext/pg_query/include/postgres/commands/trigger.h +1 -1
  137. data/ext/pg_query/include/postgres/commands/vacuum.h +28 -26
  138. data/ext/pg_query/include/postgres/common/cryptohash.h +2 -2
  139. data/ext/pg_query/include/postgres/common/file_perm.h +1 -1
  140. data/ext/pg_query/include/postgres/common/file_utils.h +65 -0
  141. data/ext/pg_query/include/postgres/common/hashfn.h +16 -1
  142. data/ext/pg_query/include/postgres/common/hashfn_unstable.h +453 -0
  143. data/ext/pg_query/include/postgres/common/int.h +79 -4
  144. data/ext/pg_query/include/postgres/common/keywords.h +1 -1
  145. data/ext/pg_query/include/postgres/common/kwlookup.h +1 -1
  146. data/ext/pg_query/include/postgres/common/pg_prng.h +2 -1
  147. data/ext/pg_query/include/postgres/common/relpath.h +4 -4
  148. data/ext/pg_query/include/postgres/common/scram-common.h +1 -1
  149. data/ext/pg_query/include/postgres/common/sha2.h +1 -1
  150. data/ext/pg_query/include/postgres/common/string.h +1 -1
  151. data/ext/pg_query/include/postgres/common/unicode_east_asian_fw_table.h +2 -3
  152. data/ext/pg_query/include/postgres/copyfuncs.funcs.c +278 -30
  153. data/ext/pg_query/include/postgres/copyfuncs.switch.c +55 -4
  154. data/ext/pg_query/include/postgres/datatype/timestamp.h +28 -2
  155. data/ext/pg_query/include/postgres/equalfuncs.funcs.c +239 -26
  156. data/ext/pg_query/include/postgres/equalfuncs.switch.c +55 -4
  157. data/ext/pg_query/include/postgres/executor/execdesc.h +1 -1
  158. data/ext/pg_query/include/postgres/executor/executor.h +6 -5
  159. data/ext/pg_query/include/postgres/executor/functions.h +2 -1
  160. data/ext/pg_query/include/postgres/executor/instrument.h +5 -3
  161. data/ext/pg_query/include/postgres/executor/spi.h +2 -8
  162. data/ext/pg_query/include/postgres/executor/tablefunc.h +1 -1
  163. data/ext/pg_query/include/postgres/executor/tuptable.h +31 -2
  164. data/ext/pg_query/include/postgres/fmgr.h +2 -2
  165. data/ext/pg_query/include/postgres/foreign/fdwapi.h +1 -1
  166. data/ext/pg_query/include/postgres/funcapi.h +2 -2
  167. data/ext/pg_query/include/postgres/gram.h +871 -830
  168. data/ext/pg_query/include/postgres/gramparse.h +1 -1
  169. data/ext/pg_query/include/postgres/jit/jit.h +4 -3
  170. data/ext/pg_query/include/postgres/kwlist_d.h +511 -466
  171. data/ext/pg_query/include/postgres/lib/dshash.h +25 -10
  172. data/ext/pg_query/include/postgres/lib/ilist.h +1 -1
  173. data/ext/pg_query/include/postgres/lib/pairingheap.h +1 -1
  174. data/ext/pg_query/include/postgres/lib/simplehash.h +40 -18
  175. data/ext/pg_query/include/postgres/lib/sort_template.h +14 -1
  176. data/ext/pg_query/include/postgres/lib/stringinfo.h +93 -11
  177. data/ext/pg_query/include/postgres/libpq/auth.h +1 -1
  178. data/ext/pg_query/include/postgres/libpq/crypt.h +2 -2
  179. data/ext/pg_query/include/postgres/libpq/hba.h +4 -4
  180. data/ext/pg_query/include/postgres/libpq/libpq-be.h +29 -25
  181. data/ext/pg_query/include/postgres/libpq/libpq.h +6 -7
  182. data/ext/pg_query/include/postgres/libpq/pqcomm.h +26 -20
  183. data/ext/pg_query/include/postgres/libpq/pqformat.h +2 -3
  184. data/ext/pg_query/include/postgres/libpq/pqsignal.h +1 -1
  185. data/ext/pg_query/include/postgres/libpq/protocol.h +89 -0
  186. data/ext/pg_query/include/postgres/libpq/sasl.h +1 -1
  187. data/ext/pg_query/include/postgres/libpq/scram.h +1 -1
  188. data/ext/pg_query/include/postgres/mb/pg_wchar.h +102 -82
  189. data/ext/pg_query/include/postgres/mb/stringinfo_mb.h +1 -1
  190. data/ext/pg_query/include/postgres/miscadmin.h +64 -52
  191. data/ext/pg_query/include/postgres/nodes/bitmapset.h +17 -3
  192. data/ext/pg_query/include/postgres/nodes/execnodes.h +109 -25
  193. data/ext/pg_query/include/postgres/nodes/extensible.h +1 -1
  194. data/ext/pg_query/include/postgres/nodes/lockoptions.h +4 -4
  195. data/ext/pg_query/include/postgres/nodes/makefuncs.h +8 -2
  196. data/ext/pg_query/include/postgres/nodes/memnodes.h +43 -4
  197. data/ext/pg_query/include/postgres/nodes/miscnodes.h +1 -1
  198. data/ext/pg_query/include/postgres/nodes/nodeFuncs.h +1 -1
  199. data/ext/pg_query/include/postgres/nodes/nodes.h +30 -41
  200. data/ext/pg_query/include/postgres/nodes/nodetags.h +464 -444
  201. data/ext/pg_query/include/postgres/nodes/params.h +1 -1
  202. data/ext/pg_query/include/postgres/nodes/parsenodes.h +358 -175
  203. data/ext/pg_query/include/postgres/nodes/pathnodes.h +60 -9
  204. data/ext/pg_query/include/postgres/nodes/pg_list.h +62 -11
  205. data/ext/pg_query/include/postgres/nodes/plannodes.h +11 -10
  206. data/ext/pg_query/include/postgres/nodes/primnodes.h +344 -50
  207. data/ext/pg_query/include/postgres/nodes/print.h +1 -1
  208. data/ext/pg_query/include/postgres/nodes/queryjumble.h +2 -2
  209. data/ext/pg_query/include/postgres/nodes/replnodes.h +23 -2
  210. data/ext/pg_query/include/postgres/nodes/supportnodes.h +1 -1
  211. data/ext/pg_query/include/postgres/nodes/tidbitmap.h +1 -1
  212. data/ext/pg_query/include/postgres/nodes/value.h +1 -1
  213. data/ext/pg_query/include/postgres/optimizer/cost.h +5 -4
  214. data/ext/pg_query/include/postgres/optimizer/geqo.h +1 -1
  215. data/ext/pg_query/include/postgres/optimizer/geqo_gene.h +1 -1
  216. data/ext/pg_query/include/postgres/optimizer/optimizer.h +5 -2
  217. data/ext/pg_query/include/postgres/optimizer/paths.h +13 -8
  218. data/ext/pg_query/include/postgres/optimizer/planmain.h +7 -1
  219. data/ext/pg_query/include/postgres/parser/analyze.h +3 -1
  220. data/ext/pg_query/include/postgres/parser/kwlist.h +22 -2
  221. data/ext/pg_query/include/postgres/parser/parse_agg.h +1 -1
  222. data/ext/pg_query/include/postgres/parser/parse_coerce.h +2 -2
  223. data/ext/pg_query/include/postgres/parser/parse_expr.h +1 -1
  224. data/ext/pg_query/include/postgres/parser/parse_func.h +2 -2
  225. data/ext/pg_query/include/postgres/parser/parse_node.h +3 -2
  226. data/ext/pg_query/include/postgres/parser/parse_oper.h +4 -1
  227. data/ext/pg_query/include/postgres/parser/parse_relation.h +1 -1
  228. data/ext/pg_query/include/postgres/parser/parse_type.h +2 -2
  229. data/ext/pg_query/include/postgres/parser/parser.h +3 -3
  230. data/ext/pg_query/include/postgres/parser/parsetree.h +1 -1
  231. data/ext/pg_query/include/postgres/parser/scanner.h +1 -1
  232. data/ext/pg_query/include/postgres/parser/scansup.h +1 -1
  233. data/ext/pg_query/include/postgres/partitioning/partdefs.h +1 -1
  234. data/ext/pg_query/include/postgres/pg_config.h +34 -34
  235. data/ext/pg_query/include/postgres/pg_config_manual.h +21 -8
  236. data/ext/pg_query/include/postgres/pg_getopt.h +1 -1
  237. data/ext/pg_query/include/postgres/pg_trace.h +1 -1
  238. data/ext/pg_query/include/postgres/pgstat.h +13 -11
  239. data/ext/pg_query/include/postgres/pgtime.h +1 -1
  240. data/ext/pg_query/include/postgres/pl_reserved_kwlist.h +1 -1
  241. data/ext/pg_query/include/postgres/pl_reserved_kwlist_d.h +1 -1
  242. data/ext/pg_query/include/postgres/pl_unreserved_kwlist.h +1 -1
  243. data/ext/pg_query/include/postgres/pl_unreserved_kwlist_d.h +1 -1
  244. data/ext/pg_query/include/postgres/plerrcodes.h +4 -4
  245. data/ext/pg_query/include/postgres/plpgsql.h +15 -13
  246. data/ext/pg_query/include/postgres/port/atomics/arch-arm.h +1 -1
  247. data/ext/pg_query/include/postgres/port/atomics/arch-hppa.h +1 -1
  248. data/ext/pg_query/include/postgres/port/atomics/arch-ppc.h +3 -1
  249. data/ext/pg_query/include/postgres/port/atomics/arch-x86.h +3 -1
  250. data/ext/pg_query/include/postgres/port/atomics/fallback.h +1 -1
  251. data/ext/pg_query/include/postgres/port/atomics/generic-gcc.h +38 -1
  252. data/ext/pg_query/include/postgres/port/atomics/generic-msvc.h +19 -1
  253. data/ext/pg_query/include/postgres/port/atomics/generic-sunpro.h +16 -1
  254. data/ext/pg_query/include/postgres/port/atomics/generic.h +38 -2
  255. data/ext/pg_query/include/postgres/port/atomics.h +93 -6
  256. data/ext/pg_query/include/postgres/port/pg_bitutils.h +91 -9
  257. data/ext/pg_query/include/postgres/port/pg_bswap.h +1 -1
  258. data/ext/pg_query/include/postgres/port/pg_crc32c.h +10 -1
  259. data/ext/pg_query/include/postgres/port/pg_iovec.h +117 -0
  260. data/ext/pg_query/include/postgres/port/simd.h +48 -1
  261. data/ext/pg_query/include/postgres/port/win32/sys/socket.h +8 -0
  262. data/ext/pg_query/include/postgres/port/win32_port.h +1 -11
  263. data/ext/pg_query/include/postgres/port.h +7 -3
  264. data/ext/pg_query/include/postgres/portability/instr_time.h +1 -1
  265. data/ext/pg_query/include/postgres/postgres.h +1 -1
  266. data/ext/pg_query/include/postgres/postmaster/autovacuum.h +5 -16
  267. data/ext/pg_query/include/postgres/postmaster/bgworker.h +8 -6
  268. data/ext/pg_query/include/postgres/postmaster/bgworker_internals.h +3 -7
  269. data/ext/pg_query/include/postgres/postmaster/bgwriter.h +3 -3
  270. data/ext/pg_query/include/postgres/postmaster/interrupt.h +1 -1
  271. data/ext/pg_query/include/postgres/postmaster/pgarch.h +2 -2
  272. data/ext/pg_query/include/postgres/postmaster/postmaster.h +25 -5
  273. data/ext/pg_query/include/postgres/postmaster/startup.h +2 -2
  274. data/ext/pg_query/include/postgres/postmaster/syslogger.h +2 -4
  275. data/ext/pg_query/include/postgres/postmaster/walsummarizer.h +35 -0
  276. data/ext/pg_query/include/postgres/postmaster/walwriter.h +2 -2
  277. data/ext/pg_query/include/postgres/regex/regex.h +92 -9
  278. data/ext/pg_query/include/postgres/replication/logicallauncher.h +1 -1
  279. data/ext/pg_query/include/postgres/replication/logicalproto.h +2 -2
  280. data/ext/pg_query/include/postgres/replication/logicalworker.h +2 -1
  281. data/ext/pg_query/include/postgres/replication/origin.h +1 -1
  282. data/ext/pg_query/include/postgres/replication/reorderbuffer.h +18 -28
  283. data/ext/pg_query/include/postgres/replication/slot.h +41 -5
  284. data/ext/pg_query/include/postgres/replication/slotsync.h +38 -0
  285. data/ext/pg_query/include/postgres/replication/syncrep.h +1 -1
  286. data/ext/pg_query/include/postgres/replication/walreceiver.h +37 -11
  287. data/ext/pg_query/include/postgres/replication/walsender.h +5 -3
  288. data/ext/pg_query/include/postgres/rewrite/prs2lock.h +1 -1
  289. data/ext/pg_query/include/postgres/rewrite/rewriteHandler.h +7 -1
  290. data/ext/pg_query/include/postgres/rewrite/rewriteManip.h +2 -2
  291. data/ext/pg_query/include/postgres/rewrite/rewriteSupport.h +1 -1
  292. data/ext/pg_query/include/postgres/storage/block.h +1 -1
  293. data/ext/pg_query/include/postgres/storage/buf.h +1 -1
  294. data/ext/pg_query/include/postgres/storage/bufmgr.h +59 -41
  295. data/ext/pg_query/include/postgres/storage/bufpage.h +1 -1
  296. data/ext/pg_query/include/postgres/storage/condition_variable.h +1 -1
  297. data/ext/pg_query/include/postgres/storage/dsm.h +1 -1
  298. data/ext/pg_query/include/postgres/storage/dsm_impl.h +2 -2
  299. data/ext/pg_query/include/postgres/storage/fd.h +30 -13
  300. data/ext/pg_query/include/postgres/storage/fileset.h +1 -1
  301. data/ext/pg_query/include/postgres/storage/ipc.h +4 -1
  302. data/ext/pg_query/include/postgres/storage/item.h +1 -1
  303. data/ext/pg_query/include/postgres/storage/itemid.h +1 -1
  304. data/ext/pg_query/include/postgres/storage/itemptr.h +1 -1
  305. data/ext/pg_query/include/postgres/storage/large_object.h +1 -1
  306. data/ext/pg_query/include/postgres/storage/latch.h +4 -2
  307. data/ext/pg_query/include/postgres/storage/lmgr.h +8 -2
  308. data/ext/pg_query/include/postgres/storage/lock.h +19 -19
  309. data/ext/pg_query/include/postgres/storage/lockdefs.h +1 -1
  310. data/ext/pg_query/include/postgres/storage/lwlock.h +17 -9
  311. data/ext/pg_query/include/postgres/storage/lwlocknames.h +7 -10
  312. data/ext/pg_query/include/postgres/storage/off.h +1 -1
  313. data/ext/pg_query/include/postgres/storage/pg_sema.h +1 -1
  314. data/ext/pg_query/include/postgres/storage/pg_shmem.h +5 -4
  315. data/ext/pg_query/include/postgres/storage/pmsignal.h +2 -2
  316. data/ext/pg_query/include/postgres/storage/predicate.h +1 -5
  317. data/ext/pg_query/include/postgres/storage/proc.h +48 -23
  318. data/ext/pg_query/include/postgres/storage/procarray.h +5 -1
  319. data/ext/pg_query/include/postgres/storage/proclist_types.h +11 -9
  320. data/ext/pg_query/include/postgres/storage/procnumber.h +43 -0
  321. data/ext/pg_query/include/postgres/storage/procsignal.h +8 -6
  322. data/ext/pg_query/include/postgres/storage/read_stream.h +65 -0
  323. data/ext/pg_query/include/postgres/storage/relfilelocator.h +16 -15
  324. data/ext/pg_query/include/postgres/storage/s_lock.h +7 -27
  325. data/ext/pg_query/include/postgres/storage/sharedfileset.h +1 -1
  326. data/ext/pg_query/include/postgres/storage/shm_mq.h +2 -2
  327. data/ext/pg_query/include/postgres/storage/shm_toc.h +1 -1
  328. data/ext/pg_query/include/postgres/storage/shmem.h +1 -1
  329. data/ext/pg_query/include/postgres/storage/sinval.h +3 -3
  330. data/ext/pg_query/include/postgres/storage/smgr.h +41 -27
  331. data/ext/pg_query/include/postgres/storage/spin.h +1 -1
  332. data/ext/pg_query/include/postgres/storage/standby.h +13 -3
  333. data/ext/pg_query/include/postgres/storage/standbydefs.h +2 -2
  334. data/ext/pg_query/include/postgres/storage/sync.h +4 -4
  335. data/ext/pg_query/include/postgres/tcop/cmdtag.h +1 -2
  336. data/ext/pg_query/include/postgres/tcop/cmdtaglist.h +3 -2
  337. data/ext/pg_query/include/postgres/tcop/deparse_utility.h +2 -2
  338. data/ext/pg_query/include/postgres/tcop/dest.h +3 -2
  339. data/ext/pg_query/include/postgres/tcop/fastpath.h +1 -1
  340. data/ext/pg_query/include/postgres/tcop/pquery.h +1 -1
  341. data/ext/pg_query/include/postgres/tcop/tcopprot.h +9 -5
  342. data/ext/pg_query/include/postgres/tcop/utility.h +2 -2
  343. data/ext/pg_query/include/postgres/tsearch/ts_cache.h +1 -1
  344. data/ext/pg_query/include/postgres/utils/acl.h +19 -7
  345. data/ext/pg_query/include/postgres/utils/aclchk_internal.h +1 -1
  346. data/ext/pg_query/include/postgres/utils/array.h +1 -2
  347. data/ext/pg_query/include/postgres/utils/ascii.h +84 -0
  348. data/ext/pg_query/include/postgres/utils/backend_progress.h +3 -2
  349. data/ext/pg_query/include/postgres/utils/backend_status.h +8 -10
  350. data/ext/pg_query/include/postgres/utils/builtins.h +4 -1
  351. data/ext/pg_query/include/postgres/utils/bytea.h +2 -2
  352. data/ext/pg_query/include/postgres/utils/catcache.h +5 -6
  353. data/ext/pg_query/include/postgres/utils/date.h +1 -1
  354. data/ext/pg_query/include/postgres/utils/datetime.h +4 -1
  355. data/ext/pg_query/include/postgres/utils/datum.h +1 -1
  356. data/ext/pg_query/include/postgres/utils/dsa.h +44 -5
  357. data/ext/pg_query/include/postgres/utils/elog.h +3 -8
  358. data/ext/pg_query/include/postgres/utils/errcodes.h +1 -3
  359. data/ext/pg_query/include/postgres/utils/expandeddatum.h +1 -1
  360. data/ext/pg_query/include/postgres/utils/expandedrecord.h +1 -1
  361. data/ext/pg_query/include/postgres/utils/float.h +1 -1
  362. data/ext/pg_query/include/postgres/utils/fmgroids.h +49 -16
  363. data/ext/pg_query/include/postgres/utils/fmgrprotos.h +47 -14
  364. data/ext/pg_query/include/postgres/utils/fmgrtab.h +1 -1
  365. data/ext/pg_query/include/postgres/utils/guc.h +20 -6
  366. data/ext/pg_query/include/postgres/utils/guc_hooks.h +23 -2
  367. data/ext/pg_query/include/postgres/utils/guc_tables.h +6 -5
  368. data/ext/pg_query/include/postgres/utils/hsearch.h +2 -2
  369. data/ext/pg_query/include/postgres/utils/injection_point.h +44 -0
  370. data/ext/pg_query/include/postgres/utils/inval.h +1 -1
  371. data/ext/pg_query/include/postgres/utils/logtape.h +5 -5
  372. data/ext/pg_query/include/postgres/utils/lsyscache.h +6 -3
  373. data/ext/pg_query/include/postgres/utils/memdebug.h +1 -1
  374. data/ext/pg_query/include/postgres/utils/memutils.h +12 -5
  375. data/ext/pg_query/include/postgres/utils/memutils_internal.h +53 -13
  376. data/ext/pg_query/include/postgres/utils/memutils_memorychunk.h +25 -9
  377. data/ext/pg_query/include/postgres/utils/numeric.h +6 -1
  378. data/ext/pg_query/include/postgres/utils/palloc.h +1 -15
  379. data/ext/pg_query/include/postgres/utils/partcache.h +1 -1
  380. data/ext/pg_query/include/postgres/utils/pg_locale.h +8 -7
  381. data/ext/pg_query/include/postgres/utils/pgstat_internal.h +11 -17
  382. data/ext/pg_query/include/postgres/utils/plancache.h +5 -3
  383. data/ext/pg_query/include/postgres/utils/portal.h +9 -9
  384. data/ext/pg_query/include/postgres/utils/queryenvironment.h +2 -2
  385. data/ext/pg_query/include/postgres/utils/regproc.h +1 -1
  386. data/ext/pg_query/include/postgres/utils/rel.h +14 -15
  387. data/ext/pg_query/include/postgres/utils/relcache.h +2 -5
  388. data/ext/pg_query/include/postgres/utils/reltrigger.h +1 -1
  389. data/ext/pg_query/include/postgres/utils/resowner.h +90 -9
  390. data/ext/pg_query/include/postgres/utils/ruleutils.h +1 -1
  391. data/ext/pg_query/include/postgres/utils/sharedtuplestore.h +1 -1
  392. data/ext/pg_query/include/postgres/utils/snapmgr.h +1 -52
  393. data/ext/pg_query/include/postgres/utils/snapshot.h +2 -2
  394. data/ext/pg_query/include/postgres/utils/sortsupport.h +1 -1
  395. data/ext/pg_query/include/postgres/utils/syscache.h +2 -98
  396. data/ext/pg_query/include/postgres/utils/timeout.h +3 -2
  397. data/ext/pg_query/include/postgres/utils/timestamp.h +1 -1
  398. data/ext/pg_query/include/postgres/utils/tuplesort.h +36 -9
  399. data/ext/pg_query/include/postgres/utils/tuplestore.h +2 -5
  400. data/ext/pg_query/include/postgres/utils/typcache.h +2 -1
  401. data/ext/pg_query/include/postgres/utils/varlena.h +1 -1
  402. data/ext/pg_query/include/postgres/utils/wait_event.h +28 -214
  403. data/ext/pg_query/include/postgres/utils/wait_event_types.h +218 -0
  404. data/ext/pg_query/include/postgres/utils/xml.h +4 -4
  405. data/ext/pg_query/include/postgres/varatt.h +1 -1
  406. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +1546 -792
  407. data/ext/pg_query/include/protobuf/pg_query.pb.h +58365 -46595
  408. data/ext/pg_query/pg_query.pb-c.c +6598 -3739
  409. data/ext/pg_query/pg_query_normalize.c +42 -1
  410. data/ext/pg_query/pg_query_outfuncs_json.c +3 -1
  411. data/ext/pg_query/pg_query_parse_plpgsql.c +12 -13
  412. data/ext/pg_query/pg_query_readfuncs_protobuf.c +2 -2
  413. data/ext/pg_query/pg_query_ruby_freebsd.sym +0 -1
  414. data/ext/pg_query/pg_query_scan.c +1 -1
  415. data/ext/pg_query/postgres_deparse.c +409 -21
  416. data/ext/pg_query/src_backend_catalog_namespace.c +241 -66
  417. data/ext/pg_query/src_backend_catalog_pg_proc.c +1 -3
  418. data/ext/pg_query/src_backend_commands_define.c +2 -3
  419. data/ext/pg_query/src_backend_nodes_bitmapset.c +137 -94
  420. data/ext/pg_query/src_backend_nodes_copyfuncs.c +1 -1
  421. data/ext/pg_query/src_backend_nodes_equalfuncs.c +1 -1
  422. data/ext/pg_query/src_backend_nodes_extensible.c +1 -1
  423. data/ext/pg_query/src_backend_nodes_list.c +3 -7
  424. data/ext/pg_query/src_backend_nodes_makefuncs.c +59 -20
  425. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +109 -2
  426. data/ext/pg_query/src_backend_nodes_value.c +1 -1
  427. data/ext/pg_query/src_backend_parser_gram.c +34490 -32135
  428. data/ext/pg_query/src_backend_parser_parser.c +8 -8
  429. data/ext/pg_query/src_backend_parser_scan.c +5637 -3028
  430. data/ext/pg_query/src_backend_parser_scansup.c +2 -1
  431. data/ext/pg_query/src_backend_storage_ipc_ipc.c +1 -1
  432. data/ext/pg_query/src_backend_tcop_postgres.c +34 -10
  433. data/ext/pg_query/src_backend_utils_activity_pgstat_database.c +2 -2
  434. data/ext/pg_query/src_backend_utils_adt_datum.c +8 -6
  435. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +1 -1
  436. data/ext/pg_query/src_backend_utils_adt_format_type.c +1 -1
  437. data/ext/pg_query/src_backend_utils_adt_numutils.c +4 -5
  438. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +101 -28
  439. data/ext/pg_query/src_backend_utils_error_assert.c +1 -1
  440. data/ext/pg_query/src_backend_utils_error_elog.c +47 -42
  441. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +4 -2
  442. data/ext/pg_query/src_backend_utils_init_globals.c +15 -3
  443. data/ext/pg_query/src_backend_utils_mb_mbutils.c +11 -18
  444. data/ext/pg_query/src_backend_utils_misc_guc_tables.c +16 -6
  445. data/ext/pg_query/src_backend_utils_mmgr_alignedalloc.c +8 -5
  446. data/ext/pg_query/src_backend_utils_mmgr_aset.c +308 -238
  447. data/ext/pg_query/src_backend_utils_mmgr_bump.c +728 -0
  448. data/ext/pg_query/src_backend_utils_mmgr_generation.c +273 -197
  449. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +270 -215
  450. data/ext/pg_query/src_backend_utils_mmgr_slab.c +154 -96
  451. data/ext/pg_query/src_common_encnames.c +43 -44
  452. data/ext/pg_query/src_common_hashfn.c +1 -1
  453. data/ext/pg_query/src_common_keywords.c +1 -1
  454. data/ext/pg_query/src_common_kwlist_d.h +511 -466
  455. data/ext/pg_query/src_common_kwlookup.c +1 -1
  456. data/ext/pg_query/src_common_psprintf.c +3 -3
  457. data/ext/pg_query/src_common_stringinfo.c +18 -1
  458. data/ext/pg_query/src_common_wchar.c +45 -108
  459. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +99 -5
  460. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +1 -1
  461. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +242 -143
  462. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +1 -1
  463. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +1 -1
  464. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +19 -1
  465. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +1 -1
  466. data/ext/pg_query/src_port_pg_bitutils.c +173 -28
  467. data/ext/pg_query/src_port_pgstrcasecmp.c +29 -1
  468. data/ext/pg_query/src_port_snprintf.c +1 -1
  469. data/ext/pg_query/src_port_strerror.c +1 -3
  470. data/ext/pg_query/src_port_strlcpy.c +1 -1
  471. data/lib/pg_query/param_refs.rb +1 -1
  472. data/lib/pg_query/pg_query_pb.rb +26 -3
  473. data/lib/pg_query/treewalker.rb +38 -11
  474. data/lib/pg_query/truncate.rb +1 -1
  475. data/lib/pg_query/version.rb +1 -1
  476. metadata +25 -11
  477. data/ext/pg_query/include/postgres/storage/backendid.h +0 -37
  478. data/ext/pg_query/include/postgres/storage/sinvaladt.h +0 -45
  479. data/ext/pg_query/src_backend_nodes_nodes.c +0 -38
@@ -1,14 +1,16 @@
1
1
  /*--------------------------------------------------------------------
2
2
  * Symbols referenced in this file:
3
3
  * - GenerationAlloc
4
+ * - GenerationAllocLarge
4
5
  * - GenerationBlockFreeBytes
5
- * - GenerationBlockIsEmpty
6
+ * - GenerationAllocChunkFromBlock
7
+ * - GenerationAllocFromNewBlock
6
8
  * - GenerationBlockInit
7
9
  * - GenerationFree
8
10
  * - GenerationBlockMarkEmpty
11
+ * - GenerationBlockFree
9
12
  * - GenerationRealloc
10
13
  * - GenerationReset
11
- * - GenerationBlockFree
12
14
  * - GenerationDelete
13
15
  * - GenerationGetChunkContext
14
16
  * - GenerationGetChunkSpace
@@ -26,7 +28,7 @@
26
28
  * Generation is a custom MemoryContext implementation designed for cases of
27
29
  * chunks with similar lifespan.
28
30
  *
29
- * Portions Copyright (c) 2017-2023, PostgreSQL Global Development Group
31
+ * Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
30
32
  *
31
33
  * IDENTIFICATION
32
34
  * src/backend/utils/mmgr/generation.c
@@ -59,8 +61,8 @@
59
61
  #include "port/pg_bitutils.h"
60
62
  #include "utils/memdebug.h"
61
63
  #include "utils/memutils.h"
62
- #include "utils/memutils_memorychunk.h"
63
64
  #include "utils/memutils_internal.h"
65
+ #include "utils/memutils_memorychunk.h"
64
66
 
65
67
 
66
68
  #define Generation_BLOCKHDRSZ MAXALIGN(sizeof(GenerationBlock))
@@ -81,17 +83,14 @@ typedef struct GenerationContext
81
83
  MemoryContextData header; /* Standard memory-context fields */
82
84
 
83
85
  /* Generational context parameters */
84
- Size initBlockSize; /* initial block size */
85
- Size maxBlockSize; /* maximum block size */
86
- Size nextBlockSize; /* next block size to allocate */
87
- Size allocChunkLimit; /* effective chunk size limit */
88
-
89
- GenerationBlock *block; /* current (most recently allocated) block, or
90
- * NULL if we've just freed the most recent
91
- * block */
92
- GenerationBlock *freeblock; /* pointer to a block that's being recycled,
93
- * or NULL if there's no such block. */
94
- GenerationBlock *keeper; /* keep this block over resets */
86
+ uint32 initBlockSize; /* initial block size */
87
+ uint32 maxBlockSize; /* maximum block size */
88
+ uint32 nextBlockSize; /* next block size to allocate */
89
+ uint32 allocChunkLimit; /* effective chunk size limit */
90
+
91
+ GenerationBlock *block; /* current (most recently allocated) block */
92
+ GenerationBlock *freeblock; /* pointer to an empty block that's being
93
+ * recycled, or NULL if there's no such block. */
95
94
  dlist_head blocks; /* list of blocks */
96
95
  } GenerationContext;
97
96
 
@@ -132,6 +131,12 @@ struct GenerationBlock
132
131
  #define GenerationBlockIsValid(block) \
133
132
  (PointerIsValid(block) && GenerationIsValid((block)->context))
134
133
 
134
+ /*
135
+ * GenerationBlockIsEmpty
136
+ * True iff block contains no chunks
137
+ */
138
+ #define GenerationBlockIsEmpty(b) ((b)->nchunks == 0)
139
+
135
140
  /*
136
141
  * We always store external chunks on a dedicated block. This makes fetching
137
142
  * the block from an external chunk easy since it's always the first and only
@@ -140,11 +145,18 @@ struct GenerationBlock
140
145
  #define ExternalChunkGetBlock(chunk) \
141
146
  (GenerationBlock *) ((char *) chunk - Generation_BLOCKHDRSZ)
142
147
 
148
+ /* Obtain the keeper block for a generation context */
149
+ #define KeeperBlock(set) \
150
+ ((GenerationBlock *) (((char *) set) + \
151
+ MAXALIGN(sizeof(GenerationContext))))
152
+
153
+ /* Check if the block is the keeper block of the given generation context */
154
+ #define IsKeeperBlock(set, block) ((block) == (KeeperBlock(set)))
155
+
143
156
  /* Inlined helper functions */
144
157
  static inline void GenerationBlockInit(GenerationContext *context,
145
158
  GenerationBlock *block,
146
159
  Size blksize);
147
- static inline bool GenerationBlockIsEmpty(GenerationBlock *block);
148
160
  static inline void GenerationBlockMarkEmpty(GenerationBlock *block);
149
161
  static inline Size GenerationBlockFreeBytes(GenerationBlock *block);
150
162
  static inline void GenerationBlockFree(GenerationContext *set,
@@ -172,8 +184,10 @@ static inline void GenerationBlockFree(GenerationContext *set,
172
184
  * GenerationReset
173
185
  * Frees all memory which is allocated in the given set.
174
186
  *
175
- * The code simply frees all the blocks in the context - we don't keep any
176
- * keeper blocks or anything like that.
187
+ * The initial "keeper" block (which shares a malloc chunk with the context
188
+ * header) is not given back to the operating system though. In this way, we
189
+ * don't thrash malloc() when a context is repeatedly reset after small
190
+ * allocations.
177
191
  */
178
192
  void
179
193
  GenerationReset(MemoryContext context)
@@ -199,14 +213,14 @@ GenerationReset(MemoryContext context)
199
213
  {
200
214
  GenerationBlock *block = dlist_container(GenerationBlock, node, miter.cur);
201
215
 
202
- if (block == set->keeper)
216
+ if (IsKeeperBlock(set, block))
203
217
  GenerationBlockMarkEmpty(block);
204
218
  else
205
219
  GenerationBlockFree(set, block);
206
220
  }
207
221
 
208
222
  /* set it so new allocations to make use of the keeper block */
209
- set->block = set->keeper;
223
+ set->block = KeeperBlock(set);
210
224
 
211
225
  /* Reset block size allocation sequence, too */
212
226
  set->nextBlockSize = set->initBlockSize;
@@ -230,28 +244,23 @@ GenerationDelete(MemoryContext context)
230
244
  }
231
245
 
232
246
  /*
233
- * GenerationAlloc
234
- * Returns pointer to allocated memory of given size or NULL if
235
- * request could not be completed; memory is added to the set.
236
- *
237
- * No request may exceed:
238
- * MAXALIGN_DOWN(SIZE_MAX) - Generation_BLOCKHDRSZ - Generation_CHUNKHDRSZ
239
- * All callers use a much-lower limit.
247
+ * Helper for GenerationAlloc() that allocates an entire block for the chunk.
240
248
  *
241
- * Note: when using valgrind, it doesn't matter how the returned allocation
242
- * is marked, as mcxt.c will set it to UNDEFINED. In some paths we will
243
- * return space that is marked NOACCESS - GenerationRealloc has to beware!
249
+ * GenerationAlloc()'s comment explains why this is separate.
244
250
  */
245
- void *
246
- GenerationAlloc(MemoryContext context, Size size)
251
+ pg_noinline
252
+ static void *
253
+ GenerationAllocLarge(MemoryContext context, Size size, int flags)
247
254
  {
248
255
  GenerationContext *set = (GenerationContext *) context;
249
256
  GenerationBlock *block;
250
257
  MemoryChunk *chunk;
251
258
  Size chunk_size;
252
259
  Size required_size;
260
+ Size blksize;
253
261
 
254
- Assert(GenerationIsValid(set));
262
+ /* validate 'size' is within the limits for the given 'flags' */
263
+ MemoryContextCheckSize(context, size, flags);
255
264
 
256
265
  #ifdef MEMORY_CONTEXT_CHECKING
257
266
  /* ensure there's always space for the sentinel byte */
@@ -260,140 +269,66 @@ GenerationAlloc(MemoryContext context, Size size)
260
269
  chunk_size = MAXALIGN(size);
261
270
  #endif
262
271
  required_size = chunk_size + Generation_CHUNKHDRSZ;
272
+ blksize = required_size + Generation_BLOCKHDRSZ;
263
273
 
264
- /* is it an over-sized chunk? if yes, allocate special block */
265
- if (chunk_size > set->allocChunkLimit)
266
- {
267
- Size blksize = required_size + Generation_BLOCKHDRSZ;
268
-
269
- block = (GenerationBlock *) malloc(blksize);
270
- if (block == NULL)
271
- return NULL;
274
+ block = (GenerationBlock *) malloc(blksize);
275
+ if (block == NULL)
276
+ return MemoryContextAllocationFailure(context, size, flags);
272
277
 
273
- context->mem_allocated += blksize;
278
+ context->mem_allocated += blksize;
274
279
 
275
- /* block with a single (used) chunk */
276
- block->context = set;
277
- block->blksize = blksize;
278
- block->nchunks = 1;
279
- block->nfree = 0;
280
+ /* block with a single (used) chunk */
281
+ block->context = set;
282
+ block->blksize = blksize;
283
+ block->nchunks = 1;
284
+ block->nfree = 0;
280
285
 
281
- /* the block is completely full */
282
- block->freeptr = block->endptr = ((char *) block) + blksize;
286
+ /* the block is completely full */
287
+ block->freeptr = block->endptr = ((char *) block) + blksize;
283
288
 
284
- chunk = (MemoryChunk *) (((char *) block) + Generation_BLOCKHDRSZ);
289
+ chunk = (MemoryChunk *) (((char *) block) + Generation_BLOCKHDRSZ);
285
290
 
286
- /* mark the MemoryChunk as externally managed */
287
- MemoryChunkSetHdrMaskExternal(chunk, MCTX_GENERATION_ID);
291
+ /* mark the MemoryChunk as externally managed */
292
+ MemoryChunkSetHdrMaskExternal(chunk, MCTX_GENERATION_ID);
288
293
 
289
294
  #ifdef MEMORY_CONTEXT_CHECKING
290
- chunk->requested_size = size;
291
- /* set mark to catch clobber of "unused" space */
292
- Assert(size < chunk_size);
293
- set_sentinel(MemoryChunkGetPointer(chunk), size);
295
+ chunk->requested_size = size;
296
+ /* set mark to catch clobber of "unused" space */
297
+ Assert(size < chunk_size);
298
+ set_sentinel(MemoryChunkGetPointer(chunk), size);
294
299
  #endif
295
300
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
296
- /* fill the allocated space with junk */
297
- randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
301
+ /* fill the allocated space with junk */
302
+ randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
298
303
  #endif
299
304
 
300
- /* add the block to the list of allocated blocks */
301
- dlist_push_head(&set->blocks, &block->node);
302
-
303
- /* Ensure any padding bytes are marked NOACCESS. */
304
- VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
305
- chunk_size - size);
306
-
307
- /* Disallow access to the chunk header. */
308
- VALGRIND_MAKE_MEM_NOACCESS(chunk, Generation_CHUNKHDRSZ);
309
-
310
- return MemoryChunkGetPointer(chunk);
311
- }
312
-
313
- /*
314
- * Not an oversized chunk. We try to first make use of the current block,
315
- * but if there's not enough space in it, instead of allocating a new
316
- * block, we look to see if the freeblock is empty and has enough space.
317
- * If not, we'll also try the same using the keeper block. The keeper
318
- * block may have become empty and we have no other way to reuse it again
319
- * if we don't try to use it explicitly here.
320
- *
321
- * We don't want to start filling the freeblock before the current block
322
- * is full, otherwise we may cause fragmentation in FIFO type workloads.
323
- * We only switch to using the freeblock or keeper block if those blocks
324
- * are completely empty. If we didn't do that we could end up fragmenting
325
- * consecutive allocations over multiple blocks which would be a problem
326
- * that would compound over time.
327
- */
328
- block = set->block;
329
-
330
- if (block == NULL ||
331
- GenerationBlockFreeBytes(block) < required_size)
332
- {
333
- Size blksize;
334
- GenerationBlock *freeblock = set->freeblock;
335
-
336
- if (freeblock != NULL &&
337
- GenerationBlockIsEmpty(freeblock) &&
338
- GenerationBlockFreeBytes(freeblock) >= required_size)
339
- {
340
- block = freeblock;
341
-
342
- /*
343
- * Zero out the freeblock as we'll set this to the current block
344
- * below
345
- */
346
- set->freeblock = NULL;
347
- }
348
- else if (GenerationBlockIsEmpty(set->keeper) &&
349
- GenerationBlockFreeBytes(set->keeper) >= required_size)
350
- {
351
- block = set->keeper;
352
- }
353
- else
354
- {
355
- /*
356
- * The first such block has size initBlockSize, and we double the
357
- * space in each succeeding block, but not more than maxBlockSize.
358
- */
359
- blksize = set->nextBlockSize;
360
- set->nextBlockSize <<= 1;
361
- if (set->nextBlockSize > set->maxBlockSize)
362
- set->nextBlockSize = set->maxBlockSize;
363
-
364
- /* we'll need a block hdr too, so add that to the required size */
365
- required_size += Generation_BLOCKHDRSZ;
366
-
367
- /* round the size up to the next power of 2 */
368
- if (blksize < required_size)
369
- blksize = pg_nextpower2_size_t(required_size);
305
+ /* add the block to the list of allocated blocks */
306
+ dlist_push_head(&set->blocks, &block->node);
370
307
 
371
- block = (GenerationBlock *) malloc(blksize);
372
-
373
- if (block == NULL)
374
- return NULL;
375
-
376
- context->mem_allocated += blksize;
377
-
378
- /* initialize the new block */
379
- GenerationBlockInit(set, block, blksize);
308
+ /* Ensure any padding bytes are marked NOACCESS. */
309
+ VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
310
+ chunk_size - size);
380
311
 
381
- /* add it to the doubly-linked list of blocks */
382
- dlist_push_head(&set->blocks, &block->node);
312
+ /* Disallow access to the chunk header. */
313
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, Generation_CHUNKHDRSZ);
383
314
 
384
- /* Zero out the freeblock in case it's become full */
385
- set->freeblock = NULL;
386
- }
315
+ return MemoryChunkGetPointer(chunk);
316
+ }
387
317
 
388
- /* and also use it as the current allocation block */
389
- set->block = block;
390
- }
318
+ /*
319
+ * Small helper for allocating a new chunk from a chunk, to avoid duplicating
320
+ * the code between GenerationAlloc() and GenerationAllocFromNewBlock().
321
+ */
322
+ static inline void *
323
+ GenerationAllocChunkFromBlock(MemoryContext context, GenerationBlock *block,
324
+ Size size, Size chunk_size)
325
+ {
326
+ MemoryChunk *chunk = (MemoryChunk *) (block->freeptr);
391
327
 
392
- /* we're supposed to have a block with enough free space now */
328
+ /* validate we've been given a block with enough free space */
393
329
  Assert(block != NULL);
394
- Assert((block->endptr - block->freeptr) >= Generation_CHUNKHDRSZ + chunk_size);
395
-
396
- chunk = (MemoryChunk *) block->freeptr;
330
+ Assert((block->endptr - block->freeptr) >=
331
+ Generation_CHUNKHDRSZ + chunk_size);
397
332
 
398
333
  /* Prepare to initialize the chunk header. */
399
334
  VALGRIND_MAKE_MEM_UNDEFINED(chunk, Generation_CHUNKHDRSZ);
@@ -425,6 +360,156 @@ GenerationAlloc(MemoryContext context, Size size)
425
360
  return MemoryChunkGetPointer(chunk);
426
361
  }
427
362
 
363
+ /*
364
+ * Helper for GenerationAlloc() that allocates a new block and returns a chunk
365
+ * allocated from it.
366
+ *
367
+ * GenerationAlloc()'s comment explains why this is separate.
368
+ */
369
+ pg_noinline
370
+ static void *
371
+ GenerationAllocFromNewBlock(MemoryContext context, Size size, int flags,
372
+ Size chunk_size)
373
+ {
374
+ GenerationContext *set = (GenerationContext *) context;
375
+ GenerationBlock *block;
376
+ Size blksize;
377
+ Size required_size;
378
+
379
+ /*
380
+ * The first such block has size initBlockSize, and we double the space in
381
+ * each succeeding block, but not more than maxBlockSize.
382
+ */
383
+ blksize = set->nextBlockSize;
384
+ set->nextBlockSize <<= 1;
385
+ if (set->nextBlockSize > set->maxBlockSize)
386
+ set->nextBlockSize = set->maxBlockSize;
387
+
388
+ /* we'll need space for the chunk, chunk hdr and block hdr */
389
+ required_size = chunk_size + Generation_CHUNKHDRSZ + Generation_BLOCKHDRSZ;
390
+
391
+ /* round the size up to the next power of 2 */
392
+ if (blksize < required_size)
393
+ blksize = pg_nextpower2_size_t(required_size);
394
+
395
+ block = (GenerationBlock *) malloc(blksize);
396
+
397
+ if (block == NULL)
398
+ return MemoryContextAllocationFailure(context, size, flags);
399
+
400
+ context->mem_allocated += blksize;
401
+
402
+ /* initialize the new block */
403
+ GenerationBlockInit(set, block, blksize);
404
+
405
+ /* add it to the doubly-linked list of blocks */
406
+ dlist_push_head(&set->blocks, &block->node);
407
+
408
+ /* make this the current block */
409
+ set->block = block;
410
+
411
+ return GenerationAllocChunkFromBlock(context, block, size, chunk_size);
412
+ }
413
+
414
+ /*
415
+ * GenerationAlloc
416
+ * Returns a pointer to allocated memory of given size or raises an ERROR
417
+ * on allocation failure, or returns NULL when flags contains
418
+ * MCXT_ALLOC_NO_OOM.
419
+ *
420
+ * No request may exceed:
421
+ * MAXALIGN_DOWN(SIZE_MAX) - Generation_BLOCKHDRSZ - Generation_CHUNKHDRSZ
422
+ * All callers use a much-lower limit.
423
+ *
424
+ * Note: when using valgrind, it doesn't matter how the returned allocation
425
+ * is marked, as mcxt.c will set it to UNDEFINED. In some paths we will
426
+ * return space that is marked NOACCESS - GenerationRealloc has to beware!
427
+ *
428
+ * This function should only contain the most common code paths. Everything
429
+ * else should be in pg_noinline helper functions, thus avoiding the overhead
430
+ * of creating a stack frame for the common cases. Allocating memory is often
431
+ * a bottleneck in many workloads, so avoiding stack frame setup is
432
+ * worthwhile. Helper functions should always directly return the newly
433
+ * allocated memory so that we can just return that address directly as a tail
434
+ * call.
435
+ */
436
+ void *
437
+ GenerationAlloc(MemoryContext context, Size size, int flags)
438
+ {
439
+ GenerationContext *set = (GenerationContext *) context;
440
+ GenerationBlock *block;
441
+ Size chunk_size;
442
+ Size required_size;
443
+
444
+ Assert(GenerationIsValid(set));
445
+
446
+ #ifdef MEMORY_CONTEXT_CHECKING
447
+ /* ensure there's always space for the sentinel byte */
448
+ chunk_size = MAXALIGN(size + 1);
449
+ #else
450
+ chunk_size = MAXALIGN(size);
451
+ #endif
452
+
453
+ /*
454
+ * If requested size exceeds maximum for chunks we hand the request off to
455
+ * GenerationAllocLarge().
456
+ */
457
+ if (chunk_size > set->allocChunkLimit)
458
+ return GenerationAllocLarge(context, size, flags);
459
+
460
+ required_size = chunk_size + Generation_CHUNKHDRSZ;
461
+
462
+ /*
463
+ * Not an oversized chunk. We try to first make use of the current block,
464
+ * but if there's not enough space in it, instead of allocating a new
465
+ * block, we look to see if the empty freeblock has enough space. We
466
+ * don't try reusing the keeper block. If it's become empty we'll reuse
467
+ * that again only if the context is reset.
468
+ *
469
+ * We only try reusing the freeblock if we've no space for this allocation
470
+ * on the current block. When a freeblock exists, we'll switch to it once
471
+ * the first time we can't fit an allocation in the current block. We
472
+ * avoid ping-ponging between the two as we need to be careful not to
473
+ * fragment differently sized consecutive allocations between several
474
+ * blocks. Going between the two could cause fragmentation for FIFO
475
+ * workloads, which generation is meant to be good at.
476
+ */
477
+ block = set->block;
478
+
479
+ if (unlikely(GenerationBlockFreeBytes(block) < required_size))
480
+ {
481
+ GenerationBlock *freeblock = set->freeblock;
482
+
483
+ /* freeblock, if set, must be empty */
484
+ Assert(freeblock == NULL || GenerationBlockIsEmpty(freeblock));
485
+
486
+ /* check if we have a freeblock and if it's big enough */
487
+ if (freeblock != NULL &&
488
+ GenerationBlockFreeBytes(freeblock) >= required_size)
489
+ {
490
+ /* make the freeblock the current block */
491
+ set->freeblock = NULL;
492
+ set->block = freeblock;
493
+
494
+ return GenerationAllocChunkFromBlock(context,
495
+ freeblock,
496
+ size,
497
+ chunk_size);
498
+ }
499
+ else
500
+ {
501
+ /*
502
+ * No freeblock, or it's not big enough for this allocation. Make
503
+ * a new block.
504
+ */
505
+ return GenerationAllocFromNewBlock(context, size, flags, chunk_size);
506
+ }
507
+ }
508
+
509
+ /* The current block has space, so just allocate chunk there. */
510
+ return GenerationAllocChunkFromBlock(context, block, size, chunk_size);
511
+ }
512
+
428
513
  /*
429
514
  * GenerationBlockInit
430
515
  * Initializes 'block' assuming 'blksize'. Does not update the context's
@@ -447,16 +532,6 @@ GenerationBlockInit(GenerationContext *context, GenerationBlock *block,
447
532
  blksize - Generation_BLOCKHDRSZ);
448
533
  }
449
534
 
450
- /*
451
- * GenerationBlockIsEmpty
452
- * Returns true iff 'block' contains no chunks
453
- */
454
- static inline bool
455
- GenerationBlockIsEmpty(GenerationBlock *block)
456
- {
457
- return (block->nchunks == 0);
458
- }
459
-
460
535
  /*
461
536
  * GenerationBlockMarkEmpty
462
537
  * Set a block as empty. Does not free the block.
@@ -499,7 +574,7 @@ static inline void
499
574
  GenerationBlockFree(GenerationContext *set, GenerationBlock *block)
500
575
  {
501
576
  /* Make sure nobody tries to free the keeper block */
502
- Assert(block != set->keeper);
577
+ Assert(!IsKeeperBlock(set, block));
503
578
  /* We shouldn't be freeing the freeblock either */
504
579
  Assert(block != set->freeblock);
505
580
 
@@ -517,8 +592,8 @@ GenerationBlockFree(GenerationContext *set, GenerationBlock *block)
517
592
 
518
593
  /*
519
594
  * GenerationFree
520
- * Update number of chunks in the block, and if all chunks in the block
521
- * are now free then discard the block.
595
+ * Update number of chunks in the block, and consider freeing the block
596
+ * if it's become empty.
522
597
  */
523
598
  void
524
599
  GenerationFree(void *pointer)
@@ -588,45 +663,41 @@ GenerationFree(void *pointer)
588
663
 
589
664
  Assert(block->nchunks > 0);
590
665
  Assert(block->nfree <= block->nchunks);
666
+ Assert(block != block->context->freeblock);
591
667
 
592
668
  /* If there are still allocated chunks in the block, we're done. */
593
- if (block->nfree < block->nchunks)
669
+ if (likely(block->nfree < block->nchunks))
594
670
  return;
595
671
 
596
672
  set = block->context;
597
673
 
598
- /* Don't try to free the keeper block, just mark it empty */
599
- if (block == set->keeper)
600
- {
601
- GenerationBlockMarkEmpty(block);
602
- return;
603
- }
604
-
605
- /*
606
- * If there is no freeblock set or if this is the freeblock then instead
607
- * of freeing this memory, we keep it around so that new allocations have
608
- * the option of recycling it.
674
+ /*-----------------------
675
+ * The block this allocation was on has now become completely empty of
676
+ * chunks. In the general case, we can now return the memory for this
677
+ * block back to malloc. However, there are cases where we don't want to
678
+ * do that:
679
+ *
680
+ * 1) If it's the keeper block. This block was malloc'd in the same
681
+ * allocation as the context itself and can't be free'd without
682
+ * freeing the context.
683
+ * 2) If it's the current block. We could free this, but doing so would
684
+ * leave us nothing to set the current block to, so we just mark the
685
+ * block as empty so new allocations can reuse it again.
686
+ * 3) If we have no "freeblock" set, then we save a single block for
687
+ * future allocations to avoid having to malloc a new block again.
688
+ * This is useful for FIFO workloads as it avoids continual
689
+ * free/malloc cycles.
609
690
  */
610
- if (set->freeblock == NULL || set->freeblock == block)
691
+ if (IsKeeperBlock(set, block) || set->block == block)
692
+ GenerationBlockMarkEmpty(block); /* case 1 and 2 */
693
+ else if (set->freeblock == NULL)
611
694
  {
612
- /* XXX should we only recycle maxBlockSize sized blocks? */
613
- set->freeblock = block;
695
+ /* case 3 */
614
696
  GenerationBlockMarkEmpty(block);
615
- return;
697
+ set->freeblock = block;
616
698
  }
617
-
618
- /* Also make sure the block is not marked as the current block. */
619
- if (set->block == block)
620
- set->block = NULL;
621
-
622
- /*
623
- * The block is empty, so let's get rid of it. First remove it from the
624
- * list of blocks, then return it to malloc().
625
- */
626
- dlist_delete(&block->node);
627
-
628
- set->header.mem_allocated -= block->blksize;
629
- free(block);
699
+ else
700
+ GenerationBlockFree(set, block); /* Otherwise, free it */
630
701
  }
631
702
 
632
703
  /*
@@ -636,7 +707,7 @@ GenerationFree(void *pointer)
636
707
  * into the old chunk - in that case we just update chunk header.
637
708
  */
638
709
  void *
639
- GenerationRealloc(void *pointer, Size size)
710
+ GenerationRealloc(void *pointer, Size size, int flags)
640
711
  {
641
712
  MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
642
713
  GenerationContext *set;
@@ -685,8 +756,8 @@ GenerationRealloc(void *pointer, Size size)
685
756
  #endif
686
757
 
687
758
  /*
688
- * Maybe the allocated area already is >= the new size. (In particular,
689
- * we always fall out here if the requested size is a decrease.)
759
+ * Maybe the allocated area already big enough. (In particular, we always
760
+ * fall out here if the requested size is a decrease.)
690
761
  *
691
762
  * This memory context does not use power-of-2 chunk sizing and instead
692
763
  * carves the chunks to be as small as possible, so most repalloc() calls
@@ -694,7 +765,12 @@ GenerationRealloc(void *pointer, Size size)
694
765
  *
695
766
  * XXX Perhaps we should annotate this condition with unlikely()?
696
767
  */
768
+ #ifdef MEMORY_CONTEXT_CHECKING
769
+ /* With MEMORY_CONTEXT_CHECKING, we need an extra byte for the sentinel */
770
+ if (oldsize > size)
771
+ #else
697
772
  if (oldsize >= size)
773
+ #endif
698
774
  {
699
775
  #ifdef MEMORY_CONTEXT_CHECKING
700
776
  Size oldrequest = chunk->requested_size;
@@ -738,15 +814,15 @@ GenerationRealloc(void *pointer, Size size)
738
814
  return pointer;
739
815
  }
740
816
 
741
- /* allocate new chunk */
742
- newPointer = GenerationAlloc((MemoryContext) set, size);
817
+ /* allocate new chunk (this also checks size is valid) */
818
+ newPointer = GenerationAlloc((MemoryContext) set, size, flags);
743
819
 
744
820
  /* leave immediately if request was not completed */
745
821
  if (newPointer == NULL)
746
822
  {
747
823
  /* Disallow access to the chunk header. */
748
824
  VALGRIND_MAKE_MEM_NOACCESS(chunk, Generation_CHUNKHDRSZ);
749
- return NULL;
825
+ return MemoryContextAllocationFailure((MemoryContext) set, size, flags);
750
826
  }
751
827
 
752
828
  /*