pg_query 2.0.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (557) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +165 -0
  3. data/README.md +67 -29
  4. data/Rakefile +8 -23
  5. data/ext/pg_query/extconf.rb +21 -3
  6. data/ext/pg_query/include/pg_query.h +29 -4
  7. data/ext/pg_query/include/pg_query_enum_defs.c +551 -272
  8. data/ext/pg_query/include/pg_query_fingerprint_conds.c +563 -470
  9. data/ext/pg_query/include/pg_query_fingerprint_defs.c +5403 -3945
  10. data/ext/pg_query/include/pg_query_outfuncs_conds.c +402 -330
  11. data/ext/pg_query/include/pg_query_outfuncs_defs.c +1319 -1059
  12. data/ext/pg_query/include/pg_query_readfuncs_conds.c +141 -118
  13. data/ext/pg_query/include/pg_query_readfuncs_defs.c +1685 -1379
  14. data/ext/pg_query/include/{access → postgres/access}/amapi.h +47 -1
  15. data/ext/pg_query/include/{access → postgres/access}/attmap.h +5 -3
  16. data/ext/pg_query/include/{access → postgres/access}/attnum.h +2 -2
  17. data/ext/pg_query/include/{access → postgres/access}/clog.h +4 -2
  18. data/ext/pg_query/include/{access → postgres/access}/commit_ts.h +6 -9
  19. data/ext/pg_query/include/{access → postgres/access}/detoast.h +1 -11
  20. data/ext/pg_query/include/{access → postgres/access}/genam.h +21 -16
  21. data/ext/pg_query/include/{access → postgres/access}/gin.h +17 -4
  22. data/ext/pg_query/include/{access → postgres/access}/htup.h +1 -1
  23. data/ext/pg_query/include/{access → postgres/access}/htup_details.h +80 -88
  24. data/ext/pg_query/include/{access → postgres/access}/itup.h +61 -52
  25. data/ext/pg_query/include/{access → postgres/access}/parallel.h +2 -2
  26. data/ext/pg_query/include/{access → postgres/access}/printtup.h +1 -1
  27. data/ext/pg_query/include/{access → postgres/access}/relation.h +1 -1
  28. data/ext/pg_query/include/{access → postgres/access}/relscan.h +17 -2
  29. data/ext/pg_query/include/postgres/access/rmgr.h +62 -0
  30. data/ext/pg_query/include/{access → postgres/access}/rmgrlist.h +24 -24
  31. data/ext/pg_query/include/{access → postgres/access}/sdir.h +12 -3
  32. data/ext/pg_query/include/{access → postgres/access}/skey.h +1 -1
  33. data/ext/pg_query/include/{access → postgres/access}/stratnum.h +4 -2
  34. data/ext/pg_query/include/{access → postgres/access}/sysattr.h +1 -1
  35. data/ext/pg_query/include/{access → postgres/access}/table.h +2 -1
  36. data/ext/pg_query/include/{access → postgres/access}/tableam.h +337 -62
  37. data/ext/pg_query/include/postgres/access/toast_compression.h +73 -0
  38. data/ext/pg_query/include/{access → postgres/access}/transam.h +123 -13
  39. data/ext/pg_query/include/postgres/access/tsmapi.h +82 -0
  40. data/ext/pg_query/include/{access → postgres/access}/tupconvert.h +5 -2
  41. data/ext/pg_query/include/{access → postgres/access}/tupdesc.h +2 -2
  42. data/ext/pg_query/include/{access → postgres/access}/tupmacs.h +60 -100
  43. data/ext/pg_query/include/{access → postgres/access}/twophase.h +5 -1
  44. data/ext/pg_query/include/{access → postgres/access}/xact.h +99 -32
  45. data/ext/pg_query/include/{access → postgres/access}/xlog.h +69 -165
  46. data/ext/pg_query/include/{access → postgres/access}/xlog_internal.h +147 -73
  47. data/ext/pg_query/include/postgres/access/xlogbackup.h +41 -0
  48. data/ext/pg_query/include/{access → postgres/access}/xlogdefs.h +13 -40
  49. data/ext/pg_query/include/postgres/access/xlogprefetcher.h +55 -0
  50. data/ext/pg_query/include/{access → postgres/access}/xlogreader.h +154 -37
  51. data/ext/pg_query/include/{access → postgres/access}/xlogrecord.h +34 -13
  52. data/ext/pg_query/include/postgres/access/xlogrecovery.h +158 -0
  53. data/ext/pg_query/include/postgres/archive/archive_module.h +59 -0
  54. data/ext/pg_query/include/{c.h → postgres/c.h} +245 -188
  55. data/ext/pg_query/include/{catalog → postgres/catalog}/catalog.h +6 -3
  56. data/ext/pg_query/include/{catalog → postgres/catalog}/catversion.h +6 -2
  57. data/ext/pg_query/include/{catalog → postgres/catalog}/dependency.h +14 -19
  58. data/ext/pg_query/include/postgres/catalog/genbki.h +143 -0
  59. data/ext/pg_query/include/{catalog → postgres/catalog}/index.h +20 -5
  60. data/ext/pg_query/include/postgres/catalog/indexing.h +54 -0
  61. data/ext/pg_query/include/{catalog → postgres/catalog}/namespace.h +5 -3
  62. data/ext/pg_query/include/{catalog → postgres/catalog}/objectaccess.h +73 -3
  63. data/ext/pg_query/include/{catalog → postgres/catalog}/objectaddress.h +12 -7
  64. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_aggregate.h +14 -10
  65. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_aggregate_d.h +2 -1
  66. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_am.h +4 -1
  67. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_am_d.h +3 -1
  68. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_attribute.h +45 -26
  69. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_attribute_d.h +19 -16
  70. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_authid.h +7 -2
  71. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_authid_d.h +19 -9
  72. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_class.h +45 -15
  73. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_class_d.h +31 -2
  74. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_collation.h +35 -8
  75. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_collation_d.h +21 -3
  76. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_constraint.h +39 -13
  77. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_constraint_d.h +10 -4
  78. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_control.h +13 -5
  79. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_conversion.h +8 -5
  80. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_conversion_d.h +4 -1
  81. data/ext/pg_query/include/postgres/catalog/pg_database.h +124 -0
  82. data/ext/pg_query/include/postgres/catalog/pg_database_d.h +52 -0
  83. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_depend.h +11 -7
  84. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_depend_d.h +3 -1
  85. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_event_trigger.h +9 -3
  86. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_event_trigger_d.h +3 -1
  87. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_index.h +17 -7
  88. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_index_d.h +20 -17
  89. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_language.h +10 -5
  90. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_language_d.h +3 -1
  91. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_namespace.h +7 -2
  92. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_namespace_d.h +3 -1
  93. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_opclass.h +8 -5
  94. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_opclass_d.h +3 -1
  95. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_operator.h +21 -16
  96. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_operator_d.h +37 -1
  97. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_opfamily.h +8 -4
  98. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_opfamily_d.h +6 -2
  99. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_partitioned_table.h +20 -9
  100. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_partitioned_table_d.h +2 -1
  101. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_proc.h +20 -11
  102. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_proc_d.h +10 -8
  103. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_publication.h +49 -6
  104. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_publication_d.h +3 -1
  105. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_replication_origin.h +6 -1
  106. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_replication_origin_d.h +5 -1
  107. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_statistic.h +19 -12
  108. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_statistic_d.h +2 -1
  109. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_statistic_ext.h +19 -5
  110. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_statistic_ext_d.h +7 -2
  111. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_transform.h +8 -5
  112. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_transform_d.h +3 -1
  113. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_trigger.h +24 -8
  114. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_trigger_d.h +4 -1
  115. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_config.h +6 -3
  116. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_config_d.h +3 -1
  117. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_dict.h +8 -3
  118. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_dict_d.h +3 -1
  119. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_parser.h +6 -3
  120. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_parser_d.h +3 -1
  121. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_template.h +6 -3
  122. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_ts_template_d.h +3 -1
  123. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_type.h +56 -24
  124. data/ext/pg_query/include/{catalog → postgres/catalog}/pg_type_d.h +70 -31
  125. data/ext/pg_query/include/{catalog → postgres/catalog}/storage.h +9 -7
  126. data/ext/pg_query/include/{commands → postgres/commands}/async.h +4 -5
  127. data/ext/pg_query/include/{commands → postgres/commands}/dbcommands.h +3 -1
  128. data/ext/pg_query/include/{commands → postgres/commands}/defrem.h +12 -24
  129. data/ext/pg_query/include/{commands → postgres/commands}/event_trigger.h +2 -2
  130. data/ext/pg_query/include/{commands → postgres/commands}/explain.h +3 -1
  131. data/ext/pg_query/include/{commands → postgres/commands}/prepare.h +1 -1
  132. data/ext/pg_query/include/{commands → postgres/commands}/tablespace.h +6 -4
  133. data/ext/pg_query/include/{commands → postgres/commands}/trigger.h +36 -25
  134. data/ext/pg_query/include/{commands → postgres/commands}/user.h +10 -4
  135. data/ext/pg_query/include/{commands → postgres/commands}/vacuum.h +140 -47
  136. data/ext/pg_query/include/postgres/common/cryptohash.h +39 -0
  137. data/ext/pg_query/include/{common → postgres/common}/file_perm.h +4 -4
  138. data/ext/pg_query/include/{common → postgres/common}/hashfn.h +1 -1
  139. data/ext/pg_query/include/postgres/common/int.h +437 -0
  140. data/ext/pg_query/include/{common → postgres/common}/keywords.h +2 -6
  141. data/ext/pg_query/include/{common → postgres/common}/kwlookup.h +2 -2
  142. data/ext/pg_query/include/postgres/common/pg_prng.h +61 -0
  143. data/ext/pg_query/include/{common → postgres/common}/relpath.h +21 -14
  144. data/ext/pg_query/include/postgres/common/scram-common.h +70 -0
  145. data/ext/pg_query/include/postgres/common/sha2.h +32 -0
  146. data/ext/pg_query/include/postgres/common/string.h +44 -0
  147. data/ext/pg_query/include/postgres/common/unicode_east_asian_fw_table.h +125 -0
  148. data/ext/pg_query/include/{common/unicode_combining_table.h → postgres/common/unicode_nonspacing_table.h} +138 -8
  149. data/ext/pg_query/include/postgres/copyfuncs.funcs.c +5013 -0
  150. data/ext/pg_query/include/postgres/copyfuncs.switch.c +938 -0
  151. data/ext/pg_query/include/{datatype → postgres/datatype}/timestamp.h +50 -4
  152. data/ext/pg_query/include/postgres/equalfuncs.funcs.c +3097 -0
  153. data/ext/pg_query/include/postgres/equalfuncs.switch.c +785 -0
  154. data/ext/pg_query/include/{executor → postgres/executor}/execdesc.h +1 -1
  155. data/ext/pg_query/include/{executor → postgres/executor}/executor.h +98 -32
  156. data/ext/pg_query/include/{executor → postgres/executor}/functions.h +17 -3
  157. data/ext/pg_query/include/{executor → postgres/executor}/instrument.h +33 -16
  158. data/ext/pg_query/include/{executor → postgres/executor}/spi.h +42 -4
  159. data/ext/pg_query/include/{executor → postgres/executor}/tablefunc.h +1 -1
  160. data/ext/pg_query/include/{executor → postgres/executor}/tuptable.h +18 -11
  161. data/ext/pg_query/include/{fmgr.h → postgres/fmgr.h} +33 -8
  162. data/ext/pg_query/include/postgres/foreign/fdwapi.h +294 -0
  163. data/ext/pg_query/include/{funcapi.h → postgres/funcapi.h} +22 -10
  164. data/ext/pg_query/include/postgres/gram.h +1127 -0
  165. data/ext/pg_query/include/{parser → postgres}/gramparse.h +4 -4
  166. data/ext/pg_query/include/{jit → postgres/jit}/jit.h +12 -12
  167. data/ext/pg_query/include/postgres/kwlist_d.h +1119 -0
  168. data/ext/pg_query/include/postgres/lib/dshash.h +115 -0
  169. data/ext/pg_query/include/{lib → postgres/lib}/ilist.h +454 -22
  170. data/ext/pg_query/include/{lib → postgres/lib}/pairingheap.h +1 -1
  171. data/ext/pg_query/include/{lib → postgres/lib}/simplehash.h +158 -33
  172. data/ext/pg_query/include/postgres/lib/sort_template.h +432 -0
  173. data/ext/pg_query/include/{lib → postgres/lib}/stringinfo.h +3 -3
  174. data/ext/pg_query/include/{libpq → postgres/libpq}/auth.h +12 -4
  175. data/ext/pg_query/include/{libpq → postgres/libpq}/crypt.h +5 -4
  176. data/ext/pg_query/include/{libpq → postgres/libpq}/hba.h +54 -8
  177. data/ext/pg_query/include/{libpq → postgres/libpq}/libpq-be.h +45 -17
  178. data/ext/pg_query/include/{libpq → postgres/libpq}/libpq.h +31 -20
  179. data/ext/pg_query/include/{libpq → postgres/libpq}/pqcomm.h +26 -71
  180. data/ext/pg_query/include/{libpq → postgres/libpq}/pqformat.h +2 -2
  181. data/ext/pg_query/include/{libpq → postgres/libpq}/pqsignal.h +25 -13
  182. data/ext/pg_query/include/postgres/libpq/sasl.h +136 -0
  183. data/ext/pg_query/include/postgres/libpq/scram.h +37 -0
  184. data/ext/pg_query/include/{mb → postgres/mb}/pg_wchar.h +125 -25
  185. data/ext/pg_query/include/{mb → postgres/mb}/stringinfo_mb.h +1 -1
  186. data/ext/pg_query/include/{miscadmin.h → postgres/miscadmin.h} +96 -65
  187. data/ext/pg_query/include/{nodes → postgres/nodes}/bitmapset.h +11 -7
  188. data/ext/pg_query/include/{nodes → postgres/nodes}/execnodes.h +351 -103
  189. data/ext/pg_query/include/{nodes → postgres/nodes}/extensible.h +8 -4
  190. data/ext/pg_query/include/{nodes → postgres/nodes}/lockoptions.h +1 -1
  191. data/ext/pg_query/include/{nodes → postgres/nodes}/makefuncs.h +19 -6
  192. data/ext/pg_query/include/{nodes → postgres/nodes}/memnodes.h +11 -6
  193. data/ext/pg_query/include/postgres/nodes/miscnodes.h +56 -0
  194. data/ext/pg_query/include/{nodes → postgres/nodes}/nodeFuncs.h +89 -29
  195. data/ext/pg_query/include/{nodes → postgres/nodes}/nodes.h +100 -496
  196. data/ext/pg_query/include/postgres/nodes/nodetags.h +471 -0
  197. data/ext/pg_query/include/{nodes → postgres/nodes}/params.h +3 -3
  198. data/ext/pg_query/include/{nodes → postgres/nodes}/parsenodes.h +678 -207
  199. data/ext/pg_query/include/{nodes → postgres/nodes}/pathnodes.h +1282 -454
  200. data/ext/pg_query/include/{nodes → postgres/nodes}/pg_list.h +103 -73
  201. data/ext/pg_query/include/{nodes → postgres/nodes}/plannodes.h +474 -133
  202. data/ext/pg_query/include/{nodes → postgres/nodes}/primnodes.h +754 -254
  203. data/ext/pg_query/include/{nodes → postgres/nodes}/print.h +1 -1
  204. data/ext/pg_query/include/postgres/nodes/queryjumble.h +86 -0
  205. data/ext/pg_query/include/postgres/nodes/replnodes.h +111 -0
  206. data/ext/pg_query/include/postgres/nodes/supportnodes.h +346 -0
  207. data/ext/pg_query/include/{nodes → postgres/nodes}/tidbitmap.h +1 -1
  208. data/ext/pg_query/include/postgres/nodes/value.h +90 -0
  209. data/ext/pg_query/include/{optimizer → postgres/optimizer}/cost.h +14 -5
  210. data/ext/pg_query/include/{optimizer → postgres/optimizer}/geqo.h +9 -7
  211. data/ext/pg_query/include/{optimizer → postgres/optimizer}/geqo_gene.h +1 -1
  212. data/ext/pg_query/include/{optimizer → postgres/optimizer}/optimizer.h +31 -28
  213. data/ext/pg_query/include/{optimizer → postgres/optimizer}/paths.h +29 -12
  214. data/ext/pg_query/include/{optimizer → postgres/optimizer}/planmain.h +15 -17
  215. data/ext/pg_query/include/{parser → postgres/parser}/analyze.h +20 -5
  216. data/ext/pg_query/include/postgres/parser/kwlist.h +498 -0
  217. data/ext/pg_query/include/{parser → postgres/parser}/parse_agg.h +5 -8
  218. data/ext/pg_query/include/{parser → postgres/parser}/parse_coerce.h +6 -1
  219. data/ext/pg_query/include/{parser → postgres/parser}/parse_expr.h +2 -3
  220. data/ext/pg_query/include/{parser → postgres/parser}/parse_func.h +2 -1
  221. data/ext/pg_query/include/{parser → postgres/parser}/parse_node.h +41 -11
  222. data/ext/pg_query/include/{parser → postgres/parser}/parse_oper.h +3 -5
  223. data/ext/pg_query/include/{parser → postgres/parser}/parse_relation.h +11 -5
  224. data/ext/pg_query/include/{parser → postgres/parser}/parse_type.h +4 -3
  225. data/ext/pg_query/include/postgres/parser/parser.h +68 -0
  226. data/ext/pg_query/include/{parser → postgres/parser}/parsetree.h +1 -1
  227. data/ext/pg_query/include/{parser → postgres/parser}/scanner.h +2 -2
  228. data/ext/pg_query/include/{parser → postgres/parser}/scansup.h +2 -5
  229. data/ext/pg_query/include/{partitioning → postgres/partitioning}/partdefs.h +1 -1
  230. data/ext/pg_query/include/{pg_config.h → postgres/pg_config.h} +216 -228
  231. data/ext/pg_query/include/{pg_config_manual.h → postgres/pg_config_manual.h} +80 -58
  232. data/ext/pg_query/include/postgres/pg_config_os.h +8 -0
  233. data/ext/pg_query/include/{pg_getopt.h → postgres/pg_getopt.h} +6 -6
  234. data/ext/pg_query/include/{pg_trace.h → postgres/pg_trace.h} +1 -1
  235. data/ext/pg_query/include/postgres/pgstat.h +778 -0
  236. data/ext/pg_query/include/{pgtime.h → postgres/pgtime.h} +16 -6
  237. data/ext/pg_query/include/{pl_gram.h → postgres/pl_gram.h} +116 -116
  238. data/ext/pg_query/include/{pl_reserved_kwlist.h → postgres/pl_reserved_kwlist.h} +1 -1
  239. data/ext/pg_query/include/{pl_reserved_kwlist_d.h → postgres/pl_reserved_kwlist_d.h} +10 -10
  240. data/ext/pg_query/include/{pl_unreserved_kwlist.h → postgres/pl_unreserved_kwlist.h} +3 -3
  241. data/ext/pg_query/include/{pl_unreserved_kwlist_d.h → postgres/pl_unreserved_kwlist_d.h} +60 -60
  242. data/ext/pg_query/include/{plerrcodes.h → postgres/plerrcodes.h} +9 -1
  243. data/ext/pg_query/include/{plpgsql.h → postgres/plpgsql.h} +79 -86
  244. data/ext/pg_query/include/{port → postgres/port}/atomics/arch-arm.h +9 -3
  245. data/ext/pg_query/include/postgres/port/atomics/arch-hppa.h +17 -0
  246. data/ext/pg_query/include/{port → postgres/port}/atomics/arch-ppc.h +21 -21
  247. data/ext/pg_query/include/{port → postgres/port}/atomics/arch-x86.h +2 -2
  248. data/ext/pg_query/include/{port → postgres/port}/atomics/fallback.h +3 -3
  249. data/ext/pg_query/include/{port → postgres/port}/atomics/generic-gcc.h +3 -3
  250. data/ext/pg_query/include/postgres/port/atomics/generic-msvc.h +101 -0
  251. data/ext/pg_query/include/postgres/port/atomics/generic-sunpro.h +106 -0
  252. data/ext/pg_query/include/{port → postgres/port}/atomics/generic.h +1 -1
  253. data/ext/pg_query/include/{port → postgres/port}/atomics.h +2 -7
  254. data/ext/pg_query/include/{port → postgres/port}/pg_bitutils.h +129 -16
  255. data/ext/pg_query/include/{port → postgres/port}/pg_bswap.h +1 -1
  256. data/ext/pg_query/include/{port → postgres/port}/pg_crc32c.h +1 -1
  257. data/ext/pg_query/include/postgres/port/simd.h +375 -0
  258. data/ext/pg_query/include/postgres/port/win32/arpa/inet.h +3 -0
  259. data/ext/pg_query/include/postgres/port/win32/dlfcn.h +1 -0
  260. data/ext/pg_query/include/postgres/port/win32/grp.h +1 -0
  261. data/ext/pg_query/include/postgres/port/win32/netdb.h +7 -0
  262. data/ext/pg_query/include/postgres/port/win32/netinet/in.h +3 -0
  263. data/ext/pg_query/include/postgres/port/win32/netinet/tcp.h +7 -0
  264. data/ext/pg_query/include/postgres/port/win32/pwd.h +3 -0
  265. data/ext/pg_query/include/postgres/port/win32/sys/resource.h +20 -0
  266. data/ext/pg_query/include/postgres/port/win32/sys/select.h +3 -0
  267. data/ext/pg_query/include/postgres/port/win32/sys/socket.h +26 -0
  268. data/ext/pg_query/include/postgres/port/win32/sys/un.h +17 -0
  269. data/ext/pg_query/include/postgres/port/win32/sys/wait.h +3 -0
  270. data/ext/pg_query/include/postgres/port/win32.h +59 -0
  271. data/ext/pg_query/include/postgres/port/win32_msvc/dirent.h +34 -0
  272. data/ext/pg_query/include/postgres/port/win32_msvc/sys/file.h +1 -0
  273. data/ext/pg_query/include/postgres/port/win32_msvc/sys/param.h +1 -0
  274. data/ext/pg_query/include/postgres/port/win32_msvc/sys/time.h +1 -0
  275. data/ext/pg_query/include/postgres/port/win32_msvc/unistd.h +9 -0
  276. data/ext/pg_query/include/postgres/port/win32_msvc/utime.h +3 -0
  277. data/ext/pg_query/include/postgres/port/win32_port.h +594 -0
  278. data/ext/pg_query/include/{port.h → postgres/port.h} +107 -111
  279. data/ext/pg_query/include/postgres/portability/instr_time.h +197 -0
  280. data/ext/pg_query/include/postgres/postgres.h +579 -0
  281. data/ext/pg_query/include/{postgres_ext.h → postgres/postgres_ext.h} +0 -1
  282. data/ext/pg_query/include/{postmaster → postgres/postmaster}/autovacuum.h +17 -20
  283. data/ext/pg_query/include/{postmaster → postgres/postmaster}/bgworker.h +3 -2
  284. data/ext/pg_query/include/{postmaster → postgres/postmaster}/bgworker_internals.h +2 -2
  285. data/ext/pg_query/include/{postmaster → postgres/postmaster}/bgwriter.h +6 -6
  286. data/ext/pg_query/include/{postmaster → postgres/postmaster}/interrupt.h +1 -1
  287. data/ext/pg_query/include/{postmaster → postgres/postmaster}/pgarch.h +7 -10
  288. data/ext/pg_query/include/{postmaster → postgres/postmaster}/postmaster.h +21 -17
  289. data/ext/pg_query/include/postgres/postmaster/startup.h +41 -0
  290. data/ext/pg_query/include/{postmaster → postgres/postmaster}/syslogger.h +16 -11
  291. data/ext/pg_query/include/{postmaster → postgres/postmaster}/walwriter.h +5 -3
  292. data/ext/pg_query/include/{regex → postgres/regex}/regex.h +27 -22
  293. data/ext/pg_query/include/{replication → postgres/replication}/logicallauncher.h +8 -5
  294. data/ext/pg_query/include/postgres/replication/logicalproto.h +274 -0
  295. data/ext/pg_query/include/postgres/replication/logicalworker.h +32 -0
  296. data/ext/pg_query/include/{replication → postgres/replication}/origin.h +8 -8
  297. data/ext/pg_query/include/postgres/replication/reorderbuffer.h +753 -0
  298. data/ext/pg_query/include/{replication → postgres/replication}/slot.h +42 -12
  299. data/ext/pg_query/include/{replication → postgres/replication}/syncrep.h +6 -12
  300. data/ext/pg_query/include/{replication → postgres/replication}/walreceiver.h +158 -20
  301. data/ext/pg_query/include/{replication → postgres/replication}/walsender.h +20 -20
  302. data/ext/pg_query/include/{rewrite → postgres/rewrite}/prs2lock.h +1 -1
  303. data/ext/pg_query/include/{rewrite → postgres/rewrite}/rewriteHandler.h +1 -6
  304. data/ext/pg_query/include/{rewrite → postgres/rewrite}/rewriteManip.h +11 -2
  305. data/ext/pg_query/include/{rewrite → postgres/rewrite}/rewriteSupport.h +1 -1
  306. data/ext/pg_query/include/{storage → postgres/storage}/backendid.h +3 -3
  307. data/ext/pg_query/include/{storage → postgres/storage}/block.h +24 -37
  308. data/ext/pg_query/include/{storage → postgres/storage}/buf.h +1 -1
  309. data/ext/pg_query/include/{storage → postgres/storage}/bufmgr.h +196 -95
  310. data/ext/pg_query/include/{storage → postgres/storage}/bufpage.h +152 -101
  311. data/ext/pg_query/include/{storage → postgres/storage}/condition_variable.h +14 -3
  312. data/ext/pg_query/include/{storage → postgres/storage}/dsm.h +6 -6
  313. data/ext/pg_query/include/{storage → postgres/storage}/dsm_impl.h +6 -2
  314. data/ext/pg_query/include/{storage → postgres/storage}/fd.h +48 -14
  315. data/ext/pg_query/include/postgres/storage/fileset.h +40 -0
  316. data/ext/pg_query/include/{storage → postgres/storage}/ipc.h +5 -2
  317. data/ext/pg_query/include/{storage → postgres/storage}/item.h +1 -1
  318. data/ext/pg_query/include/{storage → postgres/storage}/itemid.h +1 -1
  319. data/ext/pg_query/include/{storage → postgres/storage}/itemptr.h +96 -57
  320. data/ext/pg_query/include/{storage → postgres/storage}/large_object.h +2 -2
  321. data/ext/pg_query/include/{storage → postgres/storage}/latch.h +17 -13
  322. data/ext/pg_query/include/{storage → postgres/storage}/lmgr.h +7 -1
  323. data/ext/pg_query/include/{storage → postgres/storage}/lock.h +37 -25
  324. data/ext/pg_query/include/{storage → postgres/storage}/lockdefs.h +4 -4
  325. data/ext/pg_query/include/{storage → postgres/storage}/lwlock.h +21 -33
  326. data/ext/pg_query/include/{storage → postgres/storage}/lwlocknames.h +0 -1
  327. data/ext/pg_query/include/{storage → postgres/storage}/off.h +1 -1
  328. data/ext/pg_query/include/{storage → postgres/storage}/pg_sema.h +1 -1
  329. data/ext/pg_query/include/{storage → postgres/storage}/pg_shmem.h +9 -7
  330. data/ext/pg_query/include/{storage → postgres/storage}/pmsignal.h +15 -4
  331. data/ext/pg_query/include/{storage → postgres/storage}/predicate.h +5 -5
  332. data/ext/pg_query/include/{storage → postgres/storage}/proc.h +200 -67
  333. data/ext/pg_query/include/postgres/storage/procarray.h +99 -0
  334. data/ext/pg_query/include/{storage → postgres/storage}/proclist_types.h +1 -1
  335. data/ext/pg_query/include/{storage → postgres/storage}/procsignal.h +5 -7
  336. data/ext/pg_query/include/postgres/storage/relfilelocator.h +99 -0
  337. data/ext/pg_query/include/{storage → postgres/storage}/s_lock.h +118 -298
  338. data/ext/pg_query/include/{storage → postgres/storage}/sharedfileset.h +3 -11
  339. data/ext/pg_query/include/{storage → postgres/storage}/shm_mq.h +5 -4
  340. data/ext/pg_query/include/{storage → postgres/storage}/shm_toc.h +1 -1
  341. data/ext/pg_query/include/{storage → postgres/storage}/shmem.h +1 -23
  342. data/ext/pg_query/include/{storage → postgres/storage}/sinval.h +5 -5
  343. data/ext/pg_query/include/{storage → postgres/storage}/sinvaladt.h +4 -2
  344. data/ext/pg_query/include/{storage → postgres/storage}/smgr.h +21 -17
  345. data/ext/pg_query/include/{storage → postgres/storage}/spin.h +2 -2
  346. data/ext/pg_query/include/{storage → postgres/storage}/standby.h +17 -9
  347. data/ext/pg_query/include/{storage → postgres/storage}/standbydefs.h +2 -2
  348. data/ext/pg_query/include/{storage → postgres/storage}/sync.h +9 -5
  349. data/ext/pg_query/include/{tcop → postgres/tcop}/cmdtag.h +7 -2
  350. data/ext/pg_query/include/{tcop → postgres/tcop}/cmdtaglist.h +3 -2
  351. data/ext/pg_query/include/{tcop → postgres/tcop}/deparse_utility.h +1 -1
  352. data/ext/pg_query/include/{tcop → postgres/tcop}/dest.h +1 -3
  353. data/ext/pg_query/include/{tcop → postgres/tcop}/fastpath.h +1 -2
  354. data/ext/pg_query/include/{tcop → postgres/tcop}/pquery.h +7 -1
  355. data/ext/pg_query/include/{tcop → postgres/tcop}/tcopprot.h +19 -14
  356. data/ext/pg_query/include/{tcop → postgres/tcop}/utility.h +7 -3
  357. data/ext/pg_query/include/{tsearch → postgres/tsearch}/ts_cache.h +3 -5
  358. data/ext/pg_query/include/{utils → postgres/utils}/acl.h +37 -71
  359. data/ext/pg_query/include/{utils → postgres/utils}/aclchk_internal.h +1 -1
  360. data/ext/pg_query/include/{utils → postgres/utils}/array.h +26 -2
  361. data/ext/pg_query/include/postgres/utils/backend_progress.h +45 -0
  362. data/ext/pg_query/include/postgres/utils/backend_status.h +342 -0
  363. data/ext/pg_query/include/{utils → postgres/utils}/builtins.h +20 -11
  364. data/ext/pg_query/include/{utils → postgres/utils}/bytea.h +3 -2
  365. data/ext/pg_query/include/{utils → postgres/utils}/catcache.h +1 -1
  366. data/ext/pg_query/include/{utils → postgres/utils}/date.h +37 -9
  367. data/ext/pg_query/include/{utils → postgres/utils}/datetime.h +48 -27
  368. data/ext/pg_query/include/{utils → postgres/utils}/datum.h +9 -1
  369. data/ext/pg_query/include/{utils → postgres/utils}/dsa.h +5 -1
  370. data/ext/pg_query/include/{utils → postgres/utils}/elog.h +154 -48
  371. data/ext/pg_query/include/{utils → postgres/utils}/errcodes.h +2 -0
  372. data/ext/pg_query/include/{utils → postgres/utils}/expandeddatum.h +14 -3
  373. data/ext/pg_query/include/{utils → postgres/utils}/expandedrecord.h +14 -4
  374. data/ext/pg_query/include/{utils → postgres/utils}/float.h +13 -12
  375. data/ext/pg_query/include/{utils → postgres/utils}/fmgroids.h +1353 -696
  376. data/ext/pg_query/include/{utils → postgres/utils}/fmgrprotos.h +243 -18
  377. data/ext/pg_query/include/{utils → postgres/utils}/fmgrtab.h +6 -5
  378. data/ext/pg_query/include/{utils → postgres/utils}/guc.h +120 -121
  379. data/ext/pg_query/include/postgres/utils/guc_hooks.h +163 -0
  380. data/ext/pg_query/include/{utils → postgres/utils}/guc_tables.h +71 -21
  381. data/ext/pg_query/include/{utils → postgres/utils}/hsearch.h +15 -11
  382. data/ext/pg_query/include/{utils → postgres/utils}/inval.h +7 -3
  383. data/ext/pg_query/include/postgres/utils/logtape.h +77 -0
  384. data/ext/pg_query/include/{utils → postgres/utils}/lsyscache.h +16 -1
  385. data/ext/pg_query/include/{utils → postgres/utils}/memdebug.h +1 -1
  386. data/ext/pg_query/include/{utils → postgres/utils}/memutils.h +14 -53
  387. data/ext/pg_query/include/postgres/utils/memutils_internal.h +136 -0
  388. data/ext/pg_query/include/postgres/utils/memutils_memorychunk.h +237 -0
  389. data/ext/pg_query/include/{utils → postgres/utils}/numeric.h +38 -9
  390. data/ext/pg_query/include/{utils → postgres/utils}/palloc.h +33 -4
  391. data/ext/pg_query/include/{utils → postgres/utils}/partcache.h +3 -2
  392. data/ext/pg_query/include/{utils → postgres/utils}/pg_locale.h +37 -21
  393. data/ext/pg_query/include/postgres/utils/pgstat_internal.h +814 -0
  394. data/ext/pg_query/include/{utils → postgres/utils}/plancache.h +6 -5
  395. data/ext/pg_query/include/{utils → postgres/utils}/portal.h +12 -1
  396. data/ext/pg_query/include/{utils → postgres/utils}/probes.h +59 -59
  397. data/ext/pg_query/include/postgres/utils/ps_status.h +47 -0
  398. data/ext/pg_query/include/{utils → postgres/utils}/queryenvironment.h +1 -1
  399. data/ext/pg_query/include/postgres/utils/regproc.h +39 -0
  400. data/ext/pg_query/include/{utils → postgres/utils}/rel.h +129 -61
  401. data/ext/pg_query/include/{utils → postgres/utils}/relcache.h +21 -14
  402. data/ext/pg_query/include/{utils → postgres/utils}/reltrigger.h +1 -1
  403. data/ext/pg_query/include/{utils → postgres/utils}/resowner.h +1 -1
  404. data/ext/pg_query/include/{utils → postgres/utils}/ruleutils.h +9 -1
  405. data/ext/pg_query/include/{utils → postgres/utils}/sharedtuplestore.h +1 -1
  406. data/ext/pg_query/include/{utils → postgres/utils}/snapmgr.h +38 -15
  407. data/ext/pg_query/include/{utils → postgres/utils}/snapshot.h +14 -1
  408. data/ext/pg_query/include/{utils → postgres/utils}/sortsupport.h +117 -2
  409. data/ext/pg_query/include/{utils → postgres/utils}/syscache.h +9 -1
  410. data/ext/pg_query/include/{utils → postgres/utils}/timeout.h +11 -4
  411. data/ext/pg_query/include/{utils → postgres/utils}/timestamp.h +46 -15
  412. data/ext/pg_query/include/{utils → postgres/utils}/tuplesort.h +209 -41
  413. data/ext/pg_query/include/{utils → postgres/utils}/tuplestore.h +2 -2
  414. data/ext/pg_query/include/{utils → postgres/utils}/typcache.h +24 -17
  415. data/ext/pg_query/include/{utils → postgres/utils}/varlena.h +17 -3
  416. data/ext/pg_query/include/postgres/utils/wait_event.h +294 -0
  417. data/ext/pg_query/include/{utils → postgres/utils}/xml.h +18 -8
  418. data/ext/pg_query/include/{postgres.h → postgres/varatt.h} +65 -471
  419. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +7494 -6382
  420. data/ext/pg_query/include/protobuf/pg_query.pb.h +116922 -84792
  421. data/ext/pg_query/include/protobuf-c/protobuf-c.h +7 -3
  422. data/ext/pg_query/include/protobuf-c.h +7 -3
  423. data/ext/pg_query/pg_query.c +10 -1
  424. data/ext/pg_query/pg_query.pb-c.c +21026 -17002
  425. data/ext/pg_query/pg_query_deparse.c +1 -9896
  426. data/ext/pg_query/pg_query_fingerprint.c +162 -50
  427. data/ext/pg_query/pg_query_fingerprint.h +3 -1
  428. data/ext/pg_query/pg_query_internal.h +1 -1
  429. data/ext/pg_query/pg_query_json_plpgsql.c +56 -12
  430. data/ext/pg_query/pg_query_normalize.c +259 -64
  431. data/ext/pg_query/pg_query_outfuncs.h +1 -0
  432. data/ext/pg_query/pg_query_outfuncs_json.c +71 -16
  433. data/ext/pg_query/pg_query_outfuncs_protobuf.c +73 -12
  434. data/ext/pg_query/pg_query_parse.c +47 -5
  435. data/ext/pg_query/pg_query_parse_plpgsql.c +86 -21
  436. data/ext/pg_query/pg_query_readfuncs_protobuf.c +43 -8
  437. data/ext/pg_query/pg_query_ruby.c +6 -1
  438. data/ext/pg_query/pg_query_ruby_freebsd.sym +2 -0
  439. data/ext/pg_query/pg_query_scan.c +3 -2
  440. data/ext/pg_query/pg_query_split.c +6 -5
  441. data/ext/pg_query/postgres_deparse.c +11067 -0
  442. data/ext/pg_query/postgres_deparse.h +9 -0
  443. data/ext/pg_query/protobuf-c.c +34 -27
  444. data/ext/pg_query/src_backend_catalog_namespace.c +27 -10
  445. data/ext/pg_query/src_backend_catalog_pg_proc.c +4 -1
  446. data/ext/pg_query/src_backend_commands_define.c +11 -1
  447. data/ext/pg_query/src_backend_nodes_bitmapset.c +13 -70
  448. data/ext/pg_query/src_backend_nodes_copyfuncs.c +103 -5894
  449. data/ext/pg_query/src_backend_nodes_equalfuncs.c +102 -3830
  450. data/ext/pg_query/src_backend_nodes_extensible.c +6 -29
  451. data/ext/pg_query/src_backend_nodes_list.c +99 -12
  452. data/ext/pg_query/src_backend_nodes_makefuncs.c +99 -4
  453. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +325 -131
  454. data/ext/pg_query/src_backend_nodes_nodes.c +38 -0
  455. data/ext/pg_query/src_backend_nodes_value.c +28 -19
  456. data/ext/pg_query/src_backend_parser_gram.c +36104 -32074
  457. data/ext/pg_query/src_backend_parser_parser.c +53 -8
  458. data/ext/pg_query/src_backend_parser_scan.c +4893 -3701
  459. data/ext/pg_query/src_backend_parser_scansup.c +4 -28
  460. data/ext/pg_query/src_backend_storage_ipc_ipc.c +13 -4
  461. data/ext/pg_query/src_backend_tcop_postgres.c +133 -105
  462. data/ext/pg_query/src_backend_utils_activity_pgstat_database.c +140 -0
  463. data/ext/pg_query/src_backend_utils_adt_datum.c +17 -7
  464. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +1 -1
  465. data/ext/pg_query/src_backend_utils_adt_format_type.c +6 -2
  466. data/ext/pg_query/src_backend_utils_adt_numutils.c +489 -0
  467. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +187 -19
  468. data/ext/pg_query/src_backend_utils_error_assert.c +17 -18
  469. data/ext/pg_query/src_backend_utils_error_elog.c +513 -318
  470. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +44 -17
  471. data/ext/pg_query/src_backend_utils_init_globals.c +9 -6
  472. data/ext/pg_query/src_backend_utils_mb_mbutils.c +74 -131
  473. data/ext/pg_query/src_backend_utils_misc_guc_tables.c +492 -0
  474. data/ext/pg_query/src_backend_utils_mmgr_alignedalloc.c +163 -0
  475. data/ext/pg_query/src_backend_utils_mmgr_aset.c +453 -314
  476. data/ext/pg_query/src_backend_utils_mmgr_generation.c +1039 -0
  477. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +549 -76
  478. data/ext/pg_query/src_backend_utils_mmgr_slab.c +1021 -0
  479. data/ext/pg_query/src_common_encnames.c +4 -1
  480. data/ext/pg_query/src_common_hashfn.c +420 -0
  481. data/ext/pg_query/src_common_keywords.c +15 -2
  482. data/ext/pg_query/src_common_kwlist_d.h +545 -498
  483. data/ext/pg_query/src_common_kwlookup.c +1 -1
  484. data/ext/pg_query/src_common_psprintf.c +1 -1
  485. data/ext/pg_query/src_common_stringinfo.c +4 -4
  486. data/ext/pg_query/src_common_wchar.c +717 -113
  487. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +49 -22
  488. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +3 -18
  489. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +1136 -1195
  490. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +1 -1
  491. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +10 -10
  492. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +2 -2
  493. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +60 -60
  494. data/ext/pg_query/src_port_pg_bitutils.c +103 -40
  495. data/ext/pg_query/src_port_pgstrcasecmp.c +29 -1
  496. data/ext/pg_query/src_port_qsort.c +12 -224
  497. data/ext/pg_query/src_port_snprintf.c +51 -29
  498. data/ext/pg_query/src_port_strerror.c +9 -19
  499. data/ext/pg_query/src_port_strlcpy.c +79 -0
  500. data/lib/pg_query/deparse.rb +7 -1
  501. data/lib/pg_query/filter_columns.rb +7 -5
  502. data/lib/pg_query/fingerprint.rb +21 -9
  503. data/lib/pg_query/node.rb +18 -13
  504. data/lib/pg_query/param_refs.rb +1 -1
  505. data/lib/pg_query/parse.rb +141 -50
  506. data/lib/pg_query/pg_query_pb.rb +175 -3031
  507. data/lib/pg_query/treewalker.rb +26 -2
  508. data/lib/pg_query/truncate.rb +54 -8
  509. data/lib/pg_query/version.rb +1 -1
  510. data/lib/pg_query.rb +0 -1
  511. metadata +443 -380
  512. data/ext/pg_query/guc-file.c +0 -0
  513. data/ext/pg_query/include/access/rmgr.h +0 -35
  514. data/ext/pg_query/include/access/xloginsert.h +0 -64
  515. data/ext/pg_query/include/bootstrap/bootstrap.h +0 -62
  516. data/ext/pg_query/include/catalog/genbki.h +0 -64
  517. data/ext/pg_query/include/catalog/indexing.h +0 -366
  518. data/ext/pg_query/include/commands/variable.h +0 -38
  519. data/ext/pg_query/include/common/ip.h +0 -37
  520. data/ext/pg_query/include/common/string.h +0 -19
  521. data/ext/pg_query/include/getaddrinfo.h +0 -162
  522. data/ext/pg_query/include/kwlist_d.h +0 -1072
  523. data/ext/pg_query/include/nodes/value.h +0 -61
  524. data/ext/pg_query/include/parser/gram.h +0 -1067
  525. data/ext/pg_query/include/parser/kwlist.h +0 -477
  526. data/ext/pg_query/include/parser/parse_clause.h +0 -54
  527. data/ext/pg_query/include/parser/parse_collate.h +0 -27
  528. data/ext/pg_query/include/parser/parse_target.h +0 -46
  529. data/ext/pg_query/include/parser/parser.h +0 -41
  530. data/ext/pg_query/include/pg_config_os.h +0 -8
  531. data/ext/pg_query/include/pgstat.h +0 -1487
  532. data/ext/pg_query/include/portability/instr_time.h +0 -256
  533. data/ext/pg_query/include/postmaster/fork_process.h +0 -17
  534. data/ext/pg_query/include/replication/logicalproto.h +0 -110
  535. data/ext/pg_query/include/replication/logicalworker.h +0 -19
  536. data/ext/pg_query/include/replication/reorderbuffer.h +0 -467
  537. data/ext/pg_query/include/storage/relfilenode.h +0 -99
  538. data/ext/pg_query/include/utils/dynahash.h +0 -19
  539. data/ext/pg_query/include/utils/pg_lsn.h +0 -29
  540. data/ext/pg_query/include/utils/pidfile.h +0 -56
  541. data/ext/pg_query/include/utils/ps_status.h +0 -25
  542. data/ext/pg_query/include/utils/regproc.h +0 -28
  543. data/ext/pg_query/include/utils/rls.h +0 -50
  544. data/ext/pg_query/include/utils/tzparser.h +0 -39
  545. data/ext/pg_query/src_backend_libpq_pqcomm.c +0 -651
  546. data/ext/pg_query/src_backend_parser_parse_expr.c +0 -313
  547. data/ext/pg_query/src_backend_postmaster_postmaster.c +0 -2230
  548. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +0 -370
  549. data/ext/pg_query/src_backend_utils_hash_dynahash.c +0 -1086
  550. data/ext/pg_query/src_backend_utils_misc_guc.c +0 -1831
  551. data/ext/pg_query/src_common_string.c +0 -86
  552. data/ext/pg_query/src_port_erand48.c +0 -127
  553. data/ext/pg_query/src_port_pgsleep.c +0 -69
  554. data/ext/pg_query/src_port_random.c +0 -31
  555. data/ext/pg_query/src_port_strnlen.c +0 -39
  556. data/lib/pg_query/json_field_names.rb +0 -1402
  557. /data/ext/pg_query/include/{pg_config_ext.h → postgres/pg_config_ext.h} +0 -0
@@ -1,18 +1,18 @@
1
1
  /*--------------------------------------------------------------------
2
2
  * Symbols referenced in this file:
3
- * - AllocSetContextCreateInternal
4
- * - context_freelists
5
- * - AllocSetMethods
6
3
  * - AllocSetAlloc
7
4
  * - AllocSetFreeIndex
8
5
  * - AllocSetFree
9
6
  * - AllocSetRealloc
10
7
  * - AllocSetReset
11
8
  * - AllocSetDelete
9
+ * - context_freelists
10
+ * - AllocSetGetChunkContext
12
11
  * - AllocSetGetChunkSpace
13
12
  * - AllocSetIsEmpty
14
13
  * - AllocSetStats
15
14
  * - AllocSetCheck
15
+ * - AllocSetContextCreateInternal
16
16
  * - AllocSetDeleteFreeList
17
17
  *--------------------------------------------------------------------
18
18
  */
@@ -26,7 +26,7 @@
26
26
  * type.
27
27
  *
28
28
  *
29
- * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
29
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
30
30
  * Portions Copyright (c) 1994, Regents of the University of California
31
31
  *
32
32
  * IDENTIFICATION
@@ -68,6 +68,8 @@
68
68
  #include "port/pg_bitutils.h"
69
69
  #include "utils/memdebug.h"
70
70
  #include "utils/memutils.h"
71
+ #include "utils/memutils_memorychunk.h"
72
+ #include "utils/memutils_internal.h"
71
73
 
72
74
  /*--------------------
73
75
  * Chunk freelist k holds chunks of size 1 << (k + ALLOC_MINBITS),
@@ -85,7 +87,9 @@
85
87
  * CAUTION: ALLOC_MINBITS must be large enough so that
86
88
  * 1<<ALLOC_MINBITS is at least MAXALIGN,
87
89
  * or we may fail to align the smallest chunks adequately.
88
- * 8-byte alignment is enough on all currently known machines.
90
+ * 8-byte alignment is enough on all currently known machines. This 8-byte
91
+ * minimum also allows us to store a pointer to the next freelist item within
92
+ * the chunk of memory itself.
89
93
  *
90
94
  * With the current parameters, request sizes up to 8K are treated as chunks,
91
95
  * larger requests go into dedicated blocks. Change ALLOCSET_NUM_FREELISTS
@@ -117,10 +121,9 @@
117
121
  */
118
122
 
119
123
  #define ALLOC_BLOCKHDRSZ MAXALIGN(sizeof(AllocBlockData))
120
- #define ALLOC_CHUNKHDRSZ sizeof(struct AllocChunkData)
124
+ #define ALLOC_CHUNKHDRSZ sizeof(MemoryChunk)
121
125
 
122
126
  typedef struct AllocBlockData *AllocBlock; /* forward reference */
123
- typedef struct AllocChunkData *AllocChunk;
124
127
 
125
128
  /*
126
129
  * AllocPointer
@@ -128,6 +131,34 @@ typedef struct AllocChunkData *AllocChunk;
128
131
  */
129
132
  typedef void *AllocPointer;
130
133
 
134
+ /*
135
+ * AllocFreeListLink
136
+ * When pfreeing memory, if we maintain a freelist for the given chunk's
137
+ * size then we use a AllocFreeListLink to point to the current item in
138
+ * the AllocSetContext's freelist and then set the given freelist element
139
+ * to point to the chunk being freed.
140
+ */
141
+ typedef struct AllocFreeListLink
142
+ {
143
+ MemoryChunk *next;
144
+ } AllocFreeListLink;
145
+
146
+ /*
147
+ * Obtain a AllocFreeListLink for the given chunk. Allocation sizes are
148
+ * always at least sizeof(AllocFreeListLink), so we reuse the pointer's memory
149
+ * itself to store the freelist link.
150
+ */
151
+ #define GetFreeListLink(chkptr) \
152
+ (AllocFreeListLink *) ((char *) (chkptr) + ALLOC_CHUNKHDRSZ)
153
+
154
+ /* Validate a freelist index retrieved from a chunk header */
155
+ #define FreeListIdxIsValid(fidx) \
156
+ ((fidx) >= 0 && (fidx) < ALLOCSET_NUM_FREELISTS)
157
+
158
+ /* Determine the size of the chunk based on the freelist index */
159
+ #define GetChunkSizeFromFreeListIdx(fidx) \
160
+ ((((Size) 1) << ALLOC_MINBITS) << (fidx))
161
+
131
162
  /*
132
163
  * AllocSetContext is our standard implementation of MemoryContext.
133
164
  *
@@ -142,7 +173,7 @@ typedef struct AllocSetContext
142
173
  MemoryContextData header; /* Standard memory-context fields */
143
174
  /* Info about storage allocated in this context: */
144
175
  AllocBlock blocks; /* head of list of blocks in this set */
145
- AllocChunk freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */
176
+ MemoryChunk *freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */
146
177
  /* Allocation parameters for this context: */
147
178
  Size initBlockSize; /* initial block size */
148
179
  Size maxBlockSize; /* maximum block size */
@@ -158,8 +189,8 @@ typedef AllocSetContext *AllocSet;
158
189
  /*
159
190
  * AllocBlock
160
191
  * An AllocBlock is the unit of memory that is obtained by aset.c
161
- * from malloc(). It contains one or more AllocChunks, which are
162
- * the units requested by palloc() and freed by pfree(). AllocChunks
192
+ * from malloc(). It contains one or more MemoryChunks, which are
193
+ * the units requested by palloc() and freed by pfree(). MemoryChunks
163
194
  * cannot be returned to malloc() individually, instead they are put
164
195
  * on freelists by pfree() and re-used by the next palloc() that has
165
196
  * a matching request size.
@@ -176,50 +207,6 @@ typedef struct AllocBlockData
176
207
  char *endptr; /* end of space in this block */
177
208
  } AllocBlockData;
178
209
 
179
- /*
180
- * AllocChunk
181
- * The prefix of each piece of memory in an AllocBlock
182
- *
183
- * Note: to meet the memory context APIs, the payload area of the chunk must
184
- * be maxaligned, and the "aset" link must be immediately adjacent to the
185
- * payload area (cf. GetMemoryChunkContext). We simplify matters for this
186
- * module by requiring sizeof(AllocChunkData) to be maxaligned, and then
187
- * we can ensure things work by adding any required alignment padding before
188
- * the "aset" field. There is a static assertion below that the alignment
189
- * is done correctly.
190
- */
191
- typedef struct AllocChunkData
192
- {
193
- /* size is always the size of the usable space in the chunk */
194
- Size size;
195
- #ifdef MEMORY_CONTEXT_CHECKING
196
- /* when debugging memory usage, also store actual requested size */
197
- /* this is zero in a free chunk */
198
- Size requested_size;
199
-
200
- #define ALLOCCHUNK_RAWSIZE (SIZEOF_SIZE_T * 2 + SIZEOF_VOID_P)
201
- #else
202
- #define ALLOCCHUNK_RAWSIZE (SIZEOF_SIZE_T + SIZEOF_VOID_P)
203
- #endif /* MEMORY_CONTEXT_CHECKING */
204
-
205
- /* ensure proper alignment by adding padding if needed */
206
- #if (ALLOCCHUNK_RAWSIZE % MAXIMUM_ALIGNOF) != 0
207
- char padding[MAXIMUM_ALIGNOF - ALLOCCHUNK_RAWSIZE % MAXIMUM_ALIGNOF];
208
- #endif
209
-
210
- /* aset is the owning aset if allocated, or the freelist link if free */
211
- void *aset;
212
- /* there must not be any padding to reach a MAXALIGN boundary here! */
213
- } AllocChunkData;
214
-
215
- /*
216
- * Only the "aset" field should be accessed outside this module.
217
- * We keep the rest of an allocated chunk's header marked NOACCESS when using
218
- * valgrind. But note that chunk headers that are in a freelist are kept
219
- * accessible, for simplicity.
220
- */
221
- #define ALLOCCHUNK_PRIVATE_LEN offsetof(AllocChunkData, aset)
222
-
223
210
  /*
224
211
  * AllocPointerIsValid
225
212
  * True iff pointer is valid allocation pointer.
@@ -230,12 +217,23 @@ typedef struct AllocChunkData
230
217
  * AllocSetIsValid
231
218
  * True iff set is valid allocation set.
232
219
  */
233
- #define AllocSetIsValid(set) PointerIsValid(set)
220
+ #define AllocSetIsValid(set) \
221
+ (PointerIsValid(set) && IsA(set, AllocSetContext))
234
222
 
235
- #define AllocPointerGetChunk(ptr) \
236
- ((AllocChunk)(((char *)(ptr)) - ALLOC_CHUNKHDRSZ))
237
- #define AllocChunkGetPointer(chk) \
238
- ((AllocPointer)(((char *)(chk)) + ALLOC_CHUNKHDRSZ))
223
+ /*
224
+ * AllocBlockIsValid
225
+ * True iff block is valid block of allocation set.
226
+ */
227
+ #define AllocBlockIsValid(block) \
228
+ (PointerIsValid(block) && AllocSetIsValid((block)->aset))
229
+
230
+ /*
231
+ * We always store external chunks on a dedicated block. This makes fetching
232
+ * the block from an external chunk easy since it's always the first and only
233
+ * chunk on the block.
234
+ */
235
+ #define ExternalChunkGetBlock(chunk) \
236
+ (AllocBlock) ((char *) chunk - ALLOC_BLOCKHDRSZ)
239
237
 
240
238
  /*
241
239
  * Rather than repeatedly creating and deleting memory contexts, we keep some
@@ -280,41 +278,6 @@ static __thread AllocSetFreeList context_freelists[2] =
280
278
  };
281
279
 
282
280
 
283
- /*
284
- * These functions implement the MemoryContext API for AllocSet contexts.
285
- */
286
- static void *AllocSetAlloc(MemoryContext context, Size size);
287
- static void AllocSetFree(MemoryContext context, void *pointer);
288
- static void *AllocSetRealloc(MemoryContext context, void *pointer, Size size);
289
- static void AllocSetReset(MemoryContext context);
290
- static void AllocSetDelete(MemoryContext context);
291
- static Size AllocSetGetChunkSpace(MemoryContext context, void *pointer);
292
- static bool AllocSetIsEmpty(MemoryContext context);
293
- static void AllocSetStats(MemoryContext context,
294
- MemoryStatsPrintFunc printfunc, void *passthru,
295
- MemoryContextCounters *totals);
296
-
297
- #ifdef MEMORY_CONTEXT_CHECKING
298
- static void AllocSetCheck(MemoryContext context);
299
- #endif
300
-
301
- /*
302
- * This is the virtual function table for AllocSet contexts.
303
- */
304
- static const MemoryContextMethods AllocSetMethods = {
305
- AllocSetAlloc,
306
- AllocSetFree,
307
- AllocSetRealloc,
308
- AllocSetReset,
309
- AllocSetDelete,
310
- AllocSetGetChunkSpace,
311
- AllocSetIsEmpty,
312
- AllocSetStats
313
- #ifdef MEMORY_CONTEXT_CHECKING
314
- ,AllocSetCheck
315
- #endif
316
- };
317
-
318
281
 
319
282
  /* ----------
320
283
  * AllocSetFreeIndex -
@@ -338,7 +301,7 @@ AllocSetFreeIndex(Size size)
338
301
  * or equivalently
339
302
  * pg_leftmost_one_pos32(size - 1) - ALLOC_MINBITS + 1
340
303
  *
341
- * However, rather than just calling that function, we duplicate the
304
+ * However, for platforms without intrinsic support, we duplicate the
342
305
  * logic here, allowing an additional optimization. It's reasonable
343
306
  * to assume that ALLOC_CHUNK_LIMIT fits in 16 bits, so we can unroll
344
307
  * the byte-at-a-time loop in pg_leftmost_one_pos32 and just handle
@@ -348,14 +311,14 @@ AllocSetFreeIndex(Size size)
348
311
  * much trouble.
349
312
  *----------
350
313
  */
351
- #ifdef HAVE__BUILTIN_CLZ
352
- idx = 31 - __builtin_clz((uint32) size - 1) - ALLOC_MINBITS + 1;
314
+ #ifdef HAVE_BITSCAN_REVERSE
315
+ idx = pg_leftmost_one_pos32((uint32) size - 1) - ALLOC_MINBITS + 1;
353
316
  #else
354
317
  uint32 t,
355
318
  tsize;
356
319
 
357
320
  /* Statically assert that we only have a 16-bit input value. */
358
- StaticAssertStmt(ALLOC_CHUNK_LIMIT < (1 << 16),
321
+ StaticAssertDecl(ALLOC_CHUNK_LIMIT < (1 << 16),
359
322
  "ALLOC_CHUNK_LIMIT must be less than 64kB");
360
323
 
361
324
  tsize = size - 1;
@@ -406,18 +369,24 @@ AllocSetContextCreateInternal(MemoryContext parent,
406
369
  AllocSet set;
407
370
  AllocBlock block;
408
371
 
409
- /* Assert we padded AllocChunkData properly */
410
- StaticAssertStmt(ALLOC_CHUNKHDRSZ == MAXALIGN(ALLOC_CHUNKHDRSZ),
411
- "sizeof(AllocChunkData) is not maxaligned");
412
- StaticAssertStmt(offsetof(AllocChunkData, aset) + sizeof(MemoryContext) ==
413
- ALLOC_CHUNKHDRSZ,
414
- "padding calculation in AllocChunkData is wrong");
372
+ /* ensure MemoryChunk's size is properly maxaligned */
373
+ StaticAssertDecl(ALLOC_CHUNKHDRSZ == MAXALIGN(ALLOC_CHUNKHDRSZ),
374
+ "sizeof(MemoryChunk) is not maxaligned");
375
+ /* check we have enough space to store the freelist link */
376
+ StaticAssertDecl(sizeof(AllocFreeListLink) <= (1 << ALLOC_MINBITS),
377
+ "sizeof(AllocFreeListLink) larger than minimum allocation size");
415
378
 
416
379
  /*
417
380
  * First, validate allocation parameters. Once these were regular runtime
418
- * test and elog's, but in practice Asserts seem sufficient because nobody
419
- * varies their parameters at runtime. We somewhat arbitrarily enforce a
420
- * minimum 1K block size.
381
+ * tests and elog's, but in practice Asserts seem sufficient because
382
+ * nobody varies their parameters at runtime. We somewhat arbitrarily
383
+ * enforce a minimum 1K block size. We restrict the maximum block size to
384
+ * MEMORYCHUNK_MAX_BLOCKOFFSET as MemoryChunks are limited to this in
385
+ * regards to addressing the offset between the chunk and the block that
386
+ * the chunk is stored on. We would be unable to store the offset between
387
+ * the chunk and block for any chunks that were beyond
388
+ * MEMORYCHUNK_MAX_BLOCKOFFSET bytes into the block if the block was to be
389
+ * larger than this.
421
390
  */
422
391
  Assert(initBlockSize == MAXALIGN(initBlockSize) &&
423
392
  initBlockSize >= 1024);
@@ -428,6 +397,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
428
397
  (minContextSize == MAXALIGN(minContextSize) &&
429
398
  minContextSize >= 1024 &&
430
399
  minContextSize <= maxBlockSize));
400
+ Assert(maxBlockSize <= MEMORYCHUNK_MAX_BLOCKOFFSET);
431
401
 
432
402
  /*
433
403
  * Check whether the parameters match either available freelist. We do
@@ -462,7 +432,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
462
432
  /* Reinitialize its header, installing correct name and parent */
463
433
  MemoryContextCreate((MemoryContext) set,
464
434
  T_AllocSetContext,
465
- &AllocSetMethods,
435
+ MCTX_ASET_ID,
466
436
  parent,
467
437
  name);
468
438
 
@@ -536,15 +506,20 @@ AllocSetContextCreateInternal(MemoryContext parent,
536
506
  * requests that are all the maximum chunk size we will waste at most
537
507
  * 1/8th of the allocated space.
538
508
  *
539
- * We have to have allocChunkLimit a power of two, because the requested
540
- * and actually-allocated sizes of any chunk must be on the same side of
541
- * the limit, else we get confused about whether the chunk is "big".
542
- *
543
509
  * Also, allocChunkLimit must not exceed ALLOCSET_SEPARATE_THRESHOLD.
544
510
  */
545
511
  StaticAssertStmt(ALLOC_CHUNK_LIMIT == ALLOCSET_SEPARATE_THRESHOLD,
546
512
  "ALLOC_CHUNK_LIMIT != ALLOCSET_SEPARATE_THRESHOLD");
547
513
 
514
+ /*
515
+ * Determine the maximum size that a chunk can be before we allocate an
516
+ * entire AllocBlock dedicated for that chunk. We set the absolute limit
517
+ * of that size as ALLOC_CHUNK_LIMIT but we reduce it further so that we
518
+ * can fit about ALLOC_CHUNK_FRACTION chunks this size on a maximally
519
+ * sized block. (We opt to keep allocChunkLimit a power-of-2 value
520
+ * primarily for legacy reasons rather than calculating it so that exactly
521
+ * ALLOC_CHUNK_FRACTION chunks fit on a maximally sized block.)
522
+ */
548
523
  set->allocChunkLimit = ALLOC_CHUNK_LIMIT;
549
524
  while ((Size) (set->allocChunkLimit + ALLOC_CHUNKHDRSZ) >
550
525
  (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION))
@@ -553,7 +528,7 @@ AllocSetContextCreateInternal(MemoryContext parent,
553
528
  /* Finally, do the type-independent part of context creation */
554
529
  MemoryContextCreate((MemoryContext) set,
555
530
  T_AllocSetContext,
556
- &AllocSetMethods,
531
+ MCTX_ASET_ID,
557
532
  parent,
558
533
  name);
559
534
 
@@ -574,21 +549,23 @@ AllocSetContextCreateInternal(MemoryContext parent,
574
549
  * thrash malloc() when a context is repeatedly reset after small allocations,
575
550
  * which is typical behavior for per-tuple contexts.
576
551
  */
577
- static void
552
+ void
578
553
  AllocSetReset(MemoryContext context)
579
554
  {
580
555
  AllocSet set = (AllocSet) context;
581
556
  AllocBlock block;
582
- Size keepersize PG_USED_FOR_ASSERTS_ONLY
583
- = set->keeper->endptr - ((char *) set);
557
+ Size keepersize PG_USED_FOR_ASSERTS_ONLY;
584
558
 
585
- AssertArg(AllocSetIsValid(set));
559
+ Assert(AllocSetIsValid(set));
586
560
 
587
561
  #ifdef MEMORY_CONTEXT_CHECKING
588
562
  /* Check for corruption and leaks before freeing */
589
563
  AllocSetCheck(context);
590
564
  #endif
591
565
 
566
+ /* Remember keeper block size for Assert below */
567
+ keepersize = set->keeper->endptr - ((char *) set);
568
+
592
569
  /* Clear chunk freelists */
593
570
  MemSetAligned(set->freelist, 0, sizeof(set->freelist));
594
571
 
@@ -642,21 +619,23 @@ AllocSetReset(MemoryContext context)
642
619
  *
643
620
  * Unlike AllocSetReset, this *must* free all resources of the set.
644
621
  */
645
- static void
622
+ void
646
623
  AllocSetDelete(MemoryContext context)
647
624
  {
648
625
  AllocSet set = (AllocSet) context;
649
626
  AllocBlock block = set->blocks;
650
- Size keepersize PG_USED_FOR_ASSERTS_ONLY
651
- = set->keeper->endptr - ((char *) set);
627
+ Size keepersize PG_USED_FOR_ASSERTS_ONLY;
652
628
 
653
- AssertArg(AllocSetIsValid(set));
629
+ Assert(AllocSetIsValid(set));
654
630
 
655
631
  #ifdef MEMORY_CONTEXT_CHECKING
656
632
  /* Check for corruption and leaks before freeing */
657
633
  AllocSetCheck(context);
658
634
  #endif
659
635
 
636
+ /* Remember keeper block size for Assert below */
637
+ keepersize = set->keeper->endptr - ((char *) set);
638
+
660
639
  /*
661
640
  * If the context is a candidate for a freelist, put it into that freelist
662
641
  * instead of destroying it.
@@ -736,17 +715,17 @@ AllocSetDelete(MemoryContext context)
736
715
  * is marked, as mcxt.c will set it to UNDEFINED. In some paths we will
737
716
  * return space that is marked NOACCESS - AllocSetRealloc has to beware!
738
717
  */
739
- static void *
718
+ void *
740
719
  AllocSetAlloc(MemoryContext context, Size size)
741
720
  {
742
721
  AllocSet set = (AllocSet) context;
743
722
  AllocBlock block;
744
- AllocChunk chunk;
723
+ MemoryChunk *chunk;
745
724
  int fidx;
746
725
  Size chunk_size;
747
726
  Size blksize;
748
727
 
749
- AssertArg(AllocSetIsValid(set));
728
+ Assert(AllocSetIsValid(set));
750
729
 
751
730
  /*
752
731
  * If requested size exceeds maximum for chunks, allocate an entire block
@@ -754,7 +733,13 @@ AllocSetAlloc(MemoryContext context, Size size)
754
733
  */
755
734
  if (size > set->allocChunkLimit)
756
735
  {
736
+ #ifdef MEMORY_CONTEXT_CHECKING
737
+ /* ensure there's always space for the sentinel byte */
738
+ chunk_size = MAXALIGN(size + 1);
739
+ #else
757
740
  chunk_size = MAXALIGN(size);
741
+ #endif
742
+
758
743
  blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
759
744
  block = (AllocBlock) malloc(blksize);
760
745
  if (block == NULL)
@@ -765,18 +750,20 @@ AllocSetAlloc(MemoryContext context, Size size)
765
750
  block->aset = set;
766
751
  block->freeptr = block->endptr = ((char *) block) + blksize;
767
752
 
768
- chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
769
- chunk->aset = set;
770
- chunk->size = chunk_size;
753
+ chunk = (MemoryChunk *) (((char *) block) + ALLOC_BLOCKHDRSZ);
754
+
755
+ /* mark the MemoryChunk as externally managed */
756
+ MemoryChunkSetHdrMaskExternal(chunk, MCTX_ASET_ID);
757
+
771
758
  #ifdef MEMORY_CONTEXT_CHECKING
772
759
  chunk->requested_size = size;
773
760
  /* set mark to catch clobber of "unused" space */
774
- if (size < chunk_size)
775
- set_sentinel(AllocChunkGetPointer(chunk), size);
761
+ Assert(size < chunk_size);
762
+ set_sentinel(MemoryChunkGetPointer(chunk), size);
776
763
  #endif
777
764
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
778
765
  /* fill the allocated space with junk */
779
- randomize_mem((char *) AllocChunkGetPointer(chunk), size);
766
+ randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
780
767
  #endif
781
768
 
782
769
  /*
@@ -799,13 +786,13 @@ AllocSetAlloc(MemoryContext context, Size size)
799
786
  }
800
787
 
801
788
  /* Ensure any padding bytes are marked NOACCESS. */
802
- VALGRIND_MAKE_MEM_NOACCESS((char *) AllocChunkGetPointer(chunk) + size,
789
+ VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
803
790
  chunk_size - size);
804
791
 
805
- /* Disallow external access to private part of chunk header. */
806
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
792
+ /* Disallow access to the chunk header. */
793
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
807
794
 
808
- return AllocChunkGetPointer(chunk);
795
+ return MemoryChunkGetPointer(chunk);
809
796
  }
810
797
 
811
798
  /*
@@ -813,42 +800,54 @@ AllocSetAlloc(MemoryContext context, Size size)
813
800
  * corresponding free list to see if there is a free chunk we could reuse.
814
801
  * If one is found, remove it from the free list, make it again a member
815
802
  * of the alloc set and return its data address.
803
+ *
804
+ * Note that we don't attempt to ensure there's space for the sentinel
805
+ * byte here. We expect a large proportion of allocations to be for sizes
806
+ * which are already a power of 2. If we were to always make space for a
807
+ * sentinel byte in MEMORY_CONTEXT_CHECKING builds, then we'd end up
808
+ * doubling the memory requirements for such allocations.
816
809
  */
817
810
  fidx = AllocSetFreeIndex(size);
818
811
  chunk = set->freelist[fidx];
819
812
  if (chunk != NULL)
820
813
  {
821
- Assert(chunk->size >= size);
814
+ AllocFreeListLink *link = GetFreeListLink(chunk);
815
+
816
+ /* Allow access to the chunk header. */
817
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
822
818
 
823
- set->freelist[fidx] = (AllocChunk) chunk->aset;
819
+ Assert(fidx == MemoryChunkGetValue(chunk));
824
820
 
825
- chunk->aset = (void *) set;
821
+ /* pop this chunk off the freelist */
822
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
823
+ set->freelist[fidx] = link->next;
824
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
826
825
 
827
826
  #ifdef MEMORY_CONTEXT_CHECKING
828
827
  chunk->requested_size = size;
829
828
  /* set mark to catch clobber of "unused" space */
830
- if (size < chunk->size)
831
- set_sentinel(AllocChunkGetPointer(chunk), size);
829
+ if (size < GetChunkSizeFromFreeListIdx(fidx))
830
+ set_sentinel(MemoryChunkGetPointer(chunk), size);
832
831
  #endif
833
832
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
834
833
  /* fill the allocated space with junk */
835
- randomize_mem((char *) AllocChunkGetPointer(chunk), size);
834
+ randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
836
835
  #endif
837
836
 
838
837
  /* Ensure any padding bytes are marked NOACCESS. */
839
- VALGRIND_MAKE_MEM_NOACCESS((char *) AllocChunkGetPointer(chunk) + size,
840
- chunk->size - size);
838
+ VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
839
+ GetChunkSizeFromFreeListIdx(fidx) - size);
841
840
 
842
- /* Disallow external access to private part of chunk header. */
843
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
841
+ /* Disallow access to the chunk header. */
842
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
844
843
 
845
- return AllocChunkGetPointer(chunk);
844
+ return MemoryChunkGetPointer(chunk);
846
845
  }
847
846
 
848
847
  /*
849
848
  * Choose the actual chunk size to allocate.
850
849
  */
851
- chunk_size = (1 << ALLOC_MINBITS) << fidx;
850
+ chunk_size = GetChunkSizeFromFreeListIdx(fidx);
852
851
  Assert(chunk_size >= size);
853
852
 
854
853
  /*
@@ -875,6 +874,7 @@ AllocSetAlloc(MemoryContext context, Size size)
875
874
  */
876
875
  while (availspace >= ((1 << ALLOC_MINBITS) + ALLOC_CHUNKHDRSZ))
877
876
  {
877
+ AllocFreeListLink *link;
878
878
  Size availchunk = availspace - ALLOC_CHUNKHDRSZ;
879
879
  int a_fidx = AllocSetFreeIndex(availchunk);
880
880
 
@@ -883,29 +883,34 @@ AllocSetAlloc(MemoryContext context, Size size)
883
883
  * freelist than the one we need to put this chunk on. The
884
884
  * exception is when availchunk is exactly a power of 2.
885
885
  */
886
- if (availchunk != ((Size) 1 << (a_fidx + ALLOC_MINBITS)))
886
+ if (availchunk != GetChunkSizeFromFreeListIdx(a_fidx))
887
887
  {
888
888
  a_fidx--;
889
889
  Assert(a_fidx >= 0);
890
- availchunk = ((Size) 1 << (a_fidx + ALLOC_MINBITS));
890
+ availchunk = GetChunkSizeFromFreeListIdx(a_fidx);
891
891
  }
892
892
 
893
- chunk = (AllocChunk) (block->freeptr);
893
+ chunk = (MemoryChunk *) (block->freeptr);
894
894
 
895
895
  /* Prepare to initialize the chunk header. */
896
896
  VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNKHDRSZ);
897
-
898
897
  block->freeptr += (availchunk + ALLOC_CHUNKHDRSZ);
899
898
  availspace -= (availchunk + ALLOC_CHUNKHDRSZ);
900
899
 
901
- chunk->size = availchunk;
900
+ /* store the freelist index in the value field */
901
+ MemoryChunkSetHdrMask(chunk, block, a_fidx, MCTX_ASET_ID);
902
902
  #ifdef MEMORY_CONTEXT_CHECKING
903
- chunk->requested_size = 0; /* mark it free */
903
+ chunk->requested_size = InvalidAllocSize; /* mark it free */
904
904
  #endif
905
- chunk->aset = (void *) set->freelist[a_fidx];
905
+ /* push this chunk onto the free list */
906
+ link = GetFreeListLink(chunk);
907
+
908
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
909
+ link->next = set->freelist[a_fidx];
910
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
911
+
906
912
  set->freelist[a_fidx] = chunk;
907
913
  }
908
-
909
914
  /* Mark that we need to create a new block */
910
915
  block = NULL;
911
916
  }
@@ -973,7 +978,7 @@ AllocSetAlloc(MemoryContext context, Size size)
973
978
  /*
974
979
  * OK, do the allocation
975
980
  */
976
- chunk = (AllocChunk) (block->freeptr);
981
+ chunk = (MemoryChunk *) (block->freeptr);
977
982
 
978
983
  /* Prepare to initialize the chunk header. */
979
984
  VALGRIND_MAKE_MEM_UNDEFINED(chunk, ALLOC_CHUNKHDRSZ);
@@ -981,69 +986,67 @@ AllocSetAlloc(MemoryContext context, Size size)
981
986
  block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
982
987
  Assert(block->freeptr <= block->endptr);
983
988
 
984
- chunk->aset = (void *) set;
985
- chunk->size = chunk_size;
989
+ /* store the free list index in the value field */
990
+ MemoryChunkSetHdrMask(chunk, block, fidx, MCTX_ASET_ID);
991
+
986
992
  #ifdef MEMORY_CONTEXT_CHECKING
987
993
  chunk->requested_size = size;
988
994
  /* set mark to catch clobber of "unused" space */
989
- if (size < chunk->size)
990
- set_sentinel(AllocChunkGetPointer(chunk), size);
995
+ if (size < chunk_size)
996
+ set_sentinel(MemoryChunkGetPointer(chunk), size);
991
997
  #endif
992
998
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
993
999
  /* fill the allocated space with junk */
994
- randomize_mem((char *) AllocChunkGetPointer(chunk), size);
1000
+ randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
995
1001
  #endif
996
1002
 
997
1003
  /* Ensure any padding bytes are marked NOACCESS. */
998
- VALGRIND_MAKE_MEM_NOACCESS((char *) AllocChunkGetPointer(chunk) + size,
1004
+ VALGRIND_MAKE_MEM_NOACCESS((char *) MemoryChunkGetPointer(chunk) + size,
999
1005
  chunk_size - size);
1000
1006
 
1001
- /* Disallow external access to private part of chunk header. */
1002
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1007
+ /* Disallow access to the chunk header. */
1008
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1003
1009
 
1004
- return AllocChunkGetPointer(chunk);
1010
+ return MemoryChunkGetPointer(chunk);
1005
1011
  }
1006
1012
 
1007
1013
  /*
1008
1014
  * AllocSetFree
1009
1015
  * Frees allocated memory; memory is removed from the set.
1010
1016
  */
1011
- static void
1012
- AllocSetFree(MemoryContext context, void *pointer)
1017
+ void
1018
+ AllocSetFree(void *pointer)
1013
1019
  {
1014
- AllocSet set = (AllocSet) context;
1015
- AllocChunk chunk = AllocPointerGetChunk(pointer);
1016
-
1017
- /* Allow access to private part of chunk header. */
1018
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1020
+ AllocSet set;
1021
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1019
1022
 
1020
- #ifdef MEMORY_CONTEXT_CHECKING
1021
- /* Test for someone scribbling on unused space in chunk */
1022
- if (chunk->requested_size < chunk->size)
1023
- if (!sentinel_ok(pointer, chunk->requested_size))
1024
- elog(WARNING, "detected write past chunk end in %s %p",
1025
- set->header.name, chunk);
1026
- #endif
1023
+ /* Allow access to the chunk header. */
1024
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1027
1025
 
1028
- if (chunk->size > set->allocChunkLimit)
1026
+ if (MemoryChunkIsExternal(chunk))
1029
1027
  {
1030
- /*
1031
- * Big chunks are certain to have been allocated as single-chunk
1032
- * blocks. Just unlink that block and return it to malloc().
1033
- */
1034
- AllocBlock block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ);
1028
+ /* Release single-chunk block. */
1029
+ AllocBlock block = ExternalChunkGetBlock(chunk);
1035
1030
 
1036
1031
  /*
1037
- * Try to verify that we have a sane block pointer: it should
1038
- * reference the correct aset, and freeptr and endptr should point
1039
- * just past the chunk.
1032
+ * Try to verify that we have a sane block pointer: the block header
1033
+ * should reference an aset and the freeptr should match the endptr.
1040
1034
  */
1041
- if (block->aset != set ||
1042
- block->freeptr != block->endptr ||
1043
- block->freeptr != ((char *) block) +
1044
- (chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ))
1035
+ if (!AllocBlockIsValid(block) || block->freeptr != block->endptr)
1045
1036
  elog(ERROR, "could not find block containing chunk %p", chunk);
1046
1037
 
1038
+ set = block->aset;
1039
+
1040
+ #ifdef MEMORY_CONTEXT_CHECKING
1041
+ {
1042
+ /* Test for someone scribbling on unused space in chunk */
1043
+ Assert(chunk->requested_size < (block->endptr - (char *) pointer));
1044
+ if (!sentinel_ok(pointer, chunk->requested_size))
1045
+ elog(WARNING, "detected write past chunk end in %s %p",
1046
+ set->header.name, chunk);
1047
+ }
1048
+ #endif
1049
+
1047
1050
  /* OK, remove block from aset's list and free it */
1048
1051
  if (block->prev)
1049
1052
  block->prev->next = block->next;
@@ -1052,7 +1055,7 @@ AllocSetFree(MemoryContext context, void *pointer)
1052
1055
  if (block->next)
1053
1056
  block->next->prev = block->prev;
1054
1057
 
1055
- context->mem_allocated -= block->endptr - ((char *) block);
1058
+ set->header.mem_allocated -= block->endptr - ((char *) block);
1056
1059
 
1057
1060
  #ifdef CLOBBER_FREED_MEMORY
1058
1061
  wipe_mem(block, block->freeptr - ((char *) block));
@@ -1061,20 +1064,48 @@ AllocSetFree(MemoryContext context, void *pointer)
1061
1064
  }
1062
1065
  else
1063
1066
  {
1064
- /* Normal case, put the chunk into appropriate freelist */
1065
- int fidx = AllocSetFreeIndex(chunk->size);
1067
+ AllocBlock block = MemoryChunkGetBlock(chunk);
1068
+ int fidx;
1069
+ AllocFreeListLink *link;
1070
+
1071
+ /*
1072
+ * In this path, for speed reasons we just Assert that the referenced
1073
+ * block is good. We can also Assert that the value field is sane.
1074
+ * Future field experience may show that these Asserts had better
1075
+ * become regular runtime test-and-elog checks.
1076
+ */
1077
+ Assert(AllocBlockIsValid(block));
1078
+ set = block->aset;
1066
1079
 
1067
- chunk->aset = (void *) set->freelist[fidx];
1080
+ fidx = MemoryChunkGetValue(chunk);
1081
+ Assert(FreeListIdxIsValid(fidx));
1082
+ link = GetFreeListLink(chunk);
1083
+
1084
+ #ifdef MEMORY_CONTEXT_CHECKING
1085
+ /* Test for someone scribbling on unused space in chunk */
1086
+ if (chunk->requested_size < GetChunkSizeFromFreeListIdx(fidx))
1087
+ if (!sentinel_ok(pointer, chunk->requested_size))
1088
+ elog(WARNING, "detected write past chunk end in %s %p",
1089
+ set->header.name, chunk);
1090
+ #endif
1068
1091
 
1069
1092
  #ifdef CLOBBER_FREED_MEMORY
1070
- wipe_mem(pointer, chunk->size);
1093
+ wipe_mem(pointer, GetChunkSizeFromFreeListIdx(fidx));
1071
1094
  #endif
1095
+ /* push this chunk onto the top of the free list */
1096
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
1097
+ link->next = set->freelist[fidx];
1098
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
1099
+ set->freelist[fidx] = chunk;
1072
1100
 
1073
1101
  #ifdef MEMORY_CONTEXT_CHECKING
1074
- /* Reset requested_size to 0 in chunks that are on freelist */
1075
- chunk->requested_size = 0;
1102
+
1103
+ /*
1104
+ * Reset requested_size to InvalidAllocSize in chunks that are on free
1105
+ * list.
1106
+ */
1107
+ chunk->requested_size = InvalidAllocSize;
1076
1108
  #endif
1077
- set->freelist[fidx] = chunk;
1078
1109
  }
1079
1110
  }
1080
1111
 
@@ -1090,57 +1121,56 @@ AllocSetFree(MemoryContext context, void *pointer)
1090
1121
  * (In principle, we could use VALGRIND_GET_VBITS() to rediscover the old
1091
1122
  * request size.)
1092
1123
  */
1093
- static void *
1094
- AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1124
+ void *
1125
+ AllocSetRealloc(void *pointer, Size size)
1095
1126
  {
1096
- AllocSet set = (AllocSet) context;
1097
- AllocChunk chunk = AllocPointerGetChunk(pointer);
1098
- Size oldsize;
1099
-
1100
- /* Allow access to private part of chunk header. */
1101
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1102
-
1103
- oldsize = chunk->size;
1127
+ AllocBlock block;
1128
+ AllocSet set;
1129
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1130
+ Size oldchksize;
1131
+ int fidx;
1104
1132
 
1105
- #ifdef MEMORY_CONTEXT_CHECKING
1106
- /* Test for someone scribbling on unused space in chunk */
1107
- if (chunk->requested_size < oldsize)
1108
- if (!sentinel_ok(pointer, chunk->requested_size))
1109
- elog(WARNING, "detected write past chunk end in %s %p",
1110
- set->header.name, chunk);
1111
- #endif
1133
+ /* Allow access to the chunk header. */
1134
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1112
1135
 
1113
- if (oldsize > set->allocChunkLimit)
1136
+ if (MemoryChunkIsExternal(chunk))
1114
1137
  {
1115
1138
  /*
1116
1139
  * The chunk must have been allocated as a single-chunk block. Use
1117
1140
  * realloc() to make the containing block bigger, or smaller, with
1118
1141
  * minimum space wastage.
1119
1142
  */
1120
- AllocBlock block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ);
1121
1143
  Size chksize;
1122
1144
  Size blksize;
1123
1145
  Size oldblksize;
1124
1146
 
1147
+ block = ExternalChunkGetBlock(chunk);
1148
+
1125
1149
  /*
1126
- * Try to verify that we have a sane block pointer: it should
1127
- * reference the correct aset, and freeptr and endptr should point
1128
- * just past the chunk.
1150
+ * Try to verify that we have a sane block pointer: the block header
1151
+ * should reference an aset and the freeptr should match the endptr.
1129
1152
  */
1130
- if (block->aset != set ||
1131
- block->freeptr != block->endptr ||
1132
- block->freeptr != ((char *) block) +
1133
- (oldsize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ))
1153
+ if (!AllocBlockIsValid(block) || block->freeptr != block->endptr)
1134
1154
  elog(ERROR, "could not find block containing chunk %p", chunk);
1135
1155
 
1136
- /*
1137
- * Even if the new request is less than set->allocChunkLimit, we stick
1138
- * with the single-chunk block approach. Therefore we need
1139
- * chunk->size to be bigger than set->allocChunkLimit, so we don't get
1140
- * confused about the chunk's status in future calls.
1141
- */
1142
- chksize = Max(size, set->allocChunkLimit + 1);
1143
- chksize = MAXALIGN(chksize);
1156
+ set = block->aset;
1157
+
1158
+ oldchksize = block->endptr - (char *) pointer;
1159
+
1160
+ #ifdef MEMORY_CONTEXT_CHECKING
1161
+ /* Test for someone scribbling on unused space in chunk */
1162
+ Assert(chunk->requested_size < oldchksize);
1163
+ if (!sentinel_ok(pointer, chunk->requested_size))
1164
+ elog(WARNING, "detected write past chunk end in %s %p",
1165
+ set->header.name, chunk);
1166
+ #endif
1167
+
1168
+ #ifdef MEMORY_CONTEXT_CHECKING
1169
+ /* ensure there's always space for the sentinel byte */
1170
+ chksize = MAXALIGN(size + 1);
1171
+ #else
1172
+ chksize = MAXALIGN(size);
1173
+ #endif
1144
1174
 
1145
1175
  /* Do the realloc */
1146
1176
  blksize = chksize + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
@@ -1149,77 +1179,109 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1149
1179
  block = (AllocBlock) realloc(block, blksize);
1150
1180
  if (block == NULL)
1151
1181
  {
1152
- /* Disallow external access to private part of chunk header. */
1153
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1182
+ /* Disallow access to the chunk header. */
1183
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1154
1184
  return NULL;
1155
1185
  }
1156
1186
 
1157
1187
  /* updated separately, not to underflow when (oldblksize > blksize) */
1158
- context->mem_allocated -= oldblksize;
1159
- context->mem_allocated += blksize;
1188
+ set->header.mem_allocated -= oldblksize;
1189
+ set->header.mem_allocated += blksize;
1160
1190
 
1161
1191
  block->freeptr = block->endptr = ((char *) block) + blksize;
1162
1192
 
1163
1193
  /* Update pointers since block has likely been moved */
1164
- chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
1165
- pointer = AllocChunkGetPointer(chunk);
1194
+ chunk = (MemoryChunk *) (((char *) block) + ALLOC_BLOCKHDRSZ);
1195
+ pointer = MemoryChunkGetPointer(chunk);
1166
1196
  if (block->prev)
1167
1197
  block->prev->next = block;
1168
1198
  else
1169
1199
  set->blocks = block;
1170
1200
  if (block->next)
1171
1201
  block->next->prev = block;
1172
- chunk->size = chksize;
1173
1202
 
1174
1203
  #ifdef MEMORY_CONTEXT_CHECKING
1175
1204
  #ifdef RANDOMIZE_ALLOCATED_MEMORY
1176
- /* We can only fill the extra space if we know the prior request */
1205
+
1206
+ /*
1207
+ * We can only randomize the extra space if we know the prior request.
1208
+ * When using Valgrind, randomize_mem() also marks memory UNDEFINED.
1209
+ */
1177
1210
  if (size > chunk->requested_size)
1178
1211
  randomize_mem((char *) pointer + chunk->requested_size,
1179
1212
  size - chunk->requested_size);
1180
- #endif
1213
+ #else
1181
1214
 
1182
1215
  /*
1183
- * realloc() (or randomize_mem()) will have left any newly-allocated
1184
- * part UNDEFINED, but we may need to adjust trailing bytes from the
1185
- * old allocation.
1216
+ * If this is an increase, realloc() will have marked any
1217
+ * newly-allocated part (from oldchksize to chksize) UNDEFINED, but we
1218
+ * also need to adjust trailing bytes from the old allocation (from
1219
+ * chunk->requested_size to oldchksize) as they are marked NOACCESS.
1220
+ * Make sure not to mark too many bytes in case chunk->requested_size
1221
+ * < size < oldchksize.
1186
1222
  */
1187
1223
  #ifdef USE_VALGRIND
1188
- if (oldsize > chunk->requested_size)
1224
+ if (Min(size, oldchksize) > chunk->requested_size)
1189
1225
  VALGRIND_MAKE_MEM_UNDEFINED((char *) pointer + chunk->requested_size,
1190
- oldsize - chunk->requested_size);
1226
+ Min(size, oldchksize) - chunk->requested_size);
1227
+ #endif
1191
1228
  #endif
1192
1229
 
1193
1230
  chunk->requested_size = size;
1194
-
1195
1231
  /* set mark to catch clobber of "unused" space */
1196
- if (size < chunk->size)
1197
- set_sentinel(pointer, size);
1232
+ Assert(size < chksize);
1233
+ set_sentinel(pointer, size);
1198
1234
  #else /* !MEMORY_CONTEXT_CHECKING */
1199
1235
 
1200
1236
  /*
1201
- * We don't know how much of the old chunk size was the actual
1202
- * allocation; it could have been as small as one byte. We have to be
1203
- * conservative and just mark the entire old portion DEFINED.
1237
+ * We may need to adjust marking of bytes from the old allocation as
1238
+ * some of them may be marked NOACCESS. We don't know how much of the
1239
+ * old chunk size was the requested size; it could have been as small
1240
+ * as one byte. We have to be conservative and just mark the entire
1241
+ * old portion DEFINED. Make sure not to mark memory beyond the new
1242
+ * allocation in case it's smaller than the old one.
1204
1243
  */
1205
- VALGRIND_MAKE_MEM_DEFINED(pointer, oldsize);
1244
+ VALGRIND_MAKE_MEM_DEFINED(pointer, Min(size, oldchksize));
1206
1245
  #endif
1207
1246
 
1208
1247
  /* Ensure any padding bytes are marked NOACCESS. */
1209
1248
  VALGRIND_MAKE_MEM_NOACCESS((char *) pointer + size, chksize - size);
1210
1249
 
1211
- /* Disallow external access to private part of chunk header. */
1212
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1250
+ /* Disallow access to the chunk header . */
1251
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1213
1252
 
1214
1253
  return pointer;
1215
1254
  }
1216
1255
 
1256
+ block = MemoryChunkGetBlock(chunk);
1257
+
1258
+ /*
1259
+ * In this path, for speed reasons we just Assert that the referenced
1260
+ * block is good. We can also Assert that the value field is sane. Future
1261
+ * field experience may show that these Asserts had better become regular
1262
+ * runtime test-and-elog checks.
1263
+ */
1264
+ Assert(AllocBlockIsValid(block));
1265
+ set = block->aset;
1266
+
1267
+ fidx = MemoryChunkGetValue(chunk);
1268
+ Assert(FreeListIdxIsValid(fidx));
1269
+ oldchksize = GetChunkSizeFromFreeListIdx(fidx);
1270
+
1271
+ #ifdef MEMORY_CONTEXT_CHECKING
1272
+ /* Test for someone scribbling on unused space in chunk */
1273
+ if (chunk->requested_size < oldchksize)
1274
+ if (!sentinel_ok(pointer, chunk->requested_size))
1275
+ elog(WARNING, "detected write past chunk end in %s %p",
1276
+ set->header.name, chunk);
1277
+ #endif
1278
+
1217
1279
  /*
1218
1280
  * Chunk sizes are aligned to power of 2 in AllocSetAlloc(). Maybe the
1219
1281
  * allocated area already is >= the new size. (In particular, we will
1220
1282
  * fall out here if the requested size is a decrease.)
1221
1283
  */
1222
- else if (oldsize >= size)
1284
+ if (oldchksize >= size)
1223
1285
  {
1224
1286
  #ifdef MEMORY_CONTEXT_CHECKING
1225
1287
  Size oldrequest = chunk->requested_size;
@@ -1242,10 +1304,10 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1242
1304
  size - oldrequest);
1243
1305
  else
1244
1306
  VALGRIND_MAKE_MEM_NOACCESS((char *) pointer + size,
1245
- oldsize - size);
1307
+ oldchksize - size);
1246
1308
 
1247
1309
  /* set mark to catch clobber of "unused" space */
1248
- if (size < oldsize)
1310
+ if (size < oldchksize)
1249
1311
  set_sentinel(pointer, size);
1250
1312
  #else /* !MEMORY_CONTEXT_CHECKING */
1251
1313
 
@@ -1254,12 +1316,12 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1254
1316
  * the old request or shrinking it, so we conservatively mark the
1255
1317
  * entire new allocation DEFINED.
1256
1318
  */
1257
- VALGRIND_MAKE_MEM_NOACCESS(pointer, oldsize);
1319
+ VALGRIND_MAKE_MEM_NOACCESS(pointer, oldchksize);
1258
1320
  VALGRIND_MAKE_MEM_DEFINED(pointer, size);
1259
1321
  #endif
1260
1322
 
1261
- /* Disallow external access to private part of chunk header. */
1262
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1323
+ /* Disallow access to the chunk header. */
1324
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1263
1325
 
1264
1326
  return pointer;
1265
1327
  }
@@ -1277,6 +1339,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1277
1339
  * memory indefinitely. See pgsql-hackers archives for 2007-08-11.)
1278
1340
  */
1279
1341
  AllocPointer newPointer;
1342
+ Size oldsize;
1280
1343
 
1281
1344
  /* allocate new chunk */
1282
1345
  newPointer = AllocSetAlloc((MemoryContext) set, size);
@@ -1284,8 +1347,8 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1284
1347
  /* leave immediately if request was not completed */
1285
1348
  if (newPointer == NULL)
1286
1349
  {
1287
- /* Disallow external access to private part of chunk header. */
1288
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1350
+ /* Disallow access to the chunk header. */
1351
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1289
1352
  return NULL;
1290
1353
  }
1291
1354
 
@@ -1301,6 +1364,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1301
1364
  #ifdef MEMORY_CONTEXT_CHECKING
1302
1365
  oldsize = chunk->requested_size;
1303
1366
  #else
1367
+ oldsize = oldchksize;
1304
1368
  VALGRIND_MAKE_MEM_DEFINED(pointer, oldsize);
1305
1369
  #endif
1306
1370
 
@@ -1308,36 +1372,84 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
1308
1372
  memcpy(newPointer, pointer, oldsize);
1309
1373
 
1310
1374
  /* free old chunk */
1311
- AllocSetFree((MemoryContext) set, pointer);
1375
+ AllocSetFree(pointer);
1312
1376
 
1313
1377
  return newPointer;
1314
1378
  }
1315
1379
  }
1316
1380
 
1381
+ /*
1382
+ * AllocSetGetChunkContext
1383
+ * Return the MemoryContext that 'pointer' belongs to.
1384
+ */
1385
+ MemoryContext
1386
+ AllocSetGetChunkContext(void *pointer)
1387
+ {
1388
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1389
+ AllocBlock block;
1390
+ AllocSet set;
1391
+
1392
+ /* Allow access to the chunk header. */
1393
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1394
+
1395
+ if (MemoryChunkIsExternal(chunk))
1396
+ block = ExternalChunkGetBlock(chunk);
1397
+ else
1398
+ block = (AllocBlock) MemoryChunkGetBlock(chunk);
1399
+
1400
+ /* Disallow access to the chunk header. */
1401
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1402
+
1403
+ Assert(AllocBlockIsValid(block));
1404
+ set = block->aset;
1405
+
1406
+ return &set->header;
1407
+ }
1408
+
1317
1409
  /*
1318
1410
  * AllocSetGetChunkSpace
1319
1411
  * Given a currently-allocated chunk, determine the total space
1320
1412
  * it occupies (including all memory-allocation overhead).
1321
1413
  */
1322
- static Size
1323
- AllocSetGetChunkSpace(MemoryContext context, void *pointer)
1414
+ Size
1415
+ AllocSetGetChunkSpace(void *pointer)
1324
1416
  {
1325
- AllocChunk chunk = AllocPointerGetChunk(pointer);
1326
- Size result;
1417
+ MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
1418
+ int fidx;
1419
+
1420
+ /* Allow access to the chunk header. */
1421
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1422
+
1423
+ if (MemoryChunkIsExternal(chunk))
1424
+ {
1425
+ AllocBlock block = ExternalChunkGetBlock(chunk);
1327
1426
 
1328
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1329
- result = chunk->size + ALLOC_CHUNKHDRSZ;
1330
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1331
- return result;
1427
+ /* Disallow access to the chunk header. */
1428
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1429
+
1430
+ Assert(AllocBlockIsValid(block));
1431
+
1432
+ return block->endptr - (char *) chunk;
1433
+ }
1434
+
1435
+ fidx = MemoryChunkGetValue(chunk);
1436
+ Assert(FreeListIdxIsValid(fidx));
1437
+
1438
+ /* Disallow access to the chunk header. */
1439
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1440
+
1441
+ return GetChunkSizeFromFreeListIdx(fidx) + ALLOC_CHUNKHDRSZ;
1332
1442
  }
1333
1443
 
1334
1444
  /*
1335
1445
  * AllocSetIsEmpty
1336
1446
  * Is an allocset empty of any allocated space?
1337
1447
  */
1338
- static bool
1448
+ bool
1339
1449
  AllocSetIsEmpty(MemoryContext context)
1340
1450
  {
1451
+ Assert(AllocSetIsValid(context));
1452
+
1341
1453
  /*
1342
1454
  * For now, we say "empty" only if the context is new or just reset. We
1343
1455
  * could examine the freelists to determine if all space has been freed,
@@ -1356,11 +1468,12 @@ AllocSetIsEmpty(MemoryContext context)
1356
1468
  * printfunc: if not NULL, pass a human-readable stats string to this.
1357
1469
  * passthru: pass this pointer through to printfunc.
1358
1470
  * totals: if not NULL, add stats about this context into *totals.
1471
+ * print_to_stderr: print stats to stderr if true, elog otherwise.
1359
1472
  */
1360
- static void
1473
+ void
1361
1474
  AllocSetStats(MemoryContext context,
1362
1475
  MemoryStatsPrintFunc printfunc, void *passthru,
1363
- MemoryContextCounters *totals)
1476
+ MemoryContextCounters *totals, bool print_to_stderr)
1364
1477
  {
1365
1478
  AllocSet set = (AllocSet) context;
1366
1479
  Size nblocks = 0;
@@ -1370,6 +1483,8 @@ AllocSetStats(MemoryContext context,
1370
1483
  AllocBlock block;
1371
1484
  int fidx;
1372
1485
 
1486
+ Assert(AllocSetIsValid(set));
1487
+
1373
1488
  /* Include context header in totalspace */
1374
1489
  totalspace = MAXALIGN(sizeof(AllocSetContext));
1375
1490
 
@@ -1381,13 +1496,24 @@ AllocSetStats(MemoryContext context,
1381
1496
  }
1382
1497
  for (fidx = 0; fidx < ALLOCSET_NUM_FREELISTS; fidx++)
1383
1498
  {
1384
- AllocChunk chunk;
1499
+ Size chksz = GetChunkSizeFromFreeListIdx(fidx);
1500
+ MemoryChunk *chunk = set->freelist[fidx];
1385
1501
 
1386
- for (chunk = set->freelist[fidx]; chunk != NULL;
1387
- chunk = (AllocChunk) chunk->aset)
1502
+ while (chunk != NULL)
1388
1503
  {
1504
+ AllocFreeListLink *link = GetFreeListLink(chunk);
1505
+
1506
+ /* Allow access to the chunk header. */
1507
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1508
+ Assert(MemoryChunkGetValue(chunk) == fidx);
1509
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1510
+
1389
1511
  freechunks++;
1390
- freespace += chunk->size + ALLOC_CHUNKHDRSZ;
1512
+ freespace += chksz + ALLOC_CHUNKHDRSZ;
1513
+
1514
+ VALGRIND_MAKE_MEM_DEFINED(link, sizeof(AllocFreeListLink));
1515
+ chunk = link->next;
1516
+ VALGRIND_MAKE_MEM_NOACCESS(link, sizeof(AllocFreeListLink));
1391
1517
  }
1392
1518
  }
1393
1519
 
@@ -1396,10 +1522,10 @@ AllocSetStats(MemoryContext context,
1396
1522
  char stats_string[200];
1397
1523
 
1398
1524
  snprintf(stats_string, sizeof(stats_string),
1399
- "%zu total in %zd blocks; %zu free (%zd chunks); %zu used",
1525
+ "%zu total in %zu blocks; %zu free (%zu chunks); %zu used",
1400
1526
  totalspace, nblocks, freespace, freechunks,
1401
1527
  totalspace - freespace);
1402
- printfunc(context, passthru, stats_string);
1528
+ printfunc(context, passthru, stats_string, print_to_stderr);
1403
1529
  }
1404
1530
 
1405
1531
  if (totals)
@@ -1422,7 +1548,7 @@ AllocSetStats(MemoryContext context,
1422
1548
  * find yourself in an infinite loop when trouble occurs, because this
1423
1549
  * routine will be entered again when elog cleanup tries to release memory!
1424
1550
  */
1425
- static void
1551
+ void
1426
1552
  AllocSetCheck(MemoryContext context)
1427
1553
  {
1428
1554
  AllocSet set = (AllocSet) context;
@@ -1439,6 +1565,7 @@ AllocSetCheck(MemoryContext context)
1439
1565
  long blk_used = block->freeptr - bpoz;
1440
1566
  long blk_data = 0;
1441
1567
  long nchunks = 0;
1568
+ bool has_external_chunk = false;
1442
1569
 
1443
1570
  if (set->keeper == block)
1444
1571
  total_allocated += block->endptr - ((char *) set);
@@ -1470,56 +1597,64 @@ AllocSetCheck(MemoryContext context)
1470
1597
  */
1471
1598
  while (bpoz < block->freeptr)
1472
1599
  {
1473
- AllocChunk chunk = (AllocChunk) bpoz;
1600
+ MemoryChunk *chunk = (MemoryChunk *) bpoz;
1474
1601
  Size chsize,
1475
1602
  dsize;
1476
1603
 
1477
- /* Allow access to private part of chunk header. */
1478
- VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOCCHUNK_PRIVATE_LEN);
1604
+ /* Allow access to the chunk header. */
1605
+ VALGRIND_MAKE_MEM_DEFINED(chunk, ALLOC_CHUNKHDRSZ);
1606
+
1607
+ if (MemoryChunkIsExternal(chunk))
1608
+ {
1609
+ chsize = block->endptr - (char *) MemoryChunkGetPointer(chunk); /* aligned chunk size */
1610
+ has_external_chunk = true;
1611
+
1612
+ /* make sure this chunk consumes the entire block */
1613
+ if (chsize + ALLOC_CHUNKHDRSZ != blk_used)
1614
+ elog(WARNING, "problem in alloc set %s: bad single-chunk %p in block %p",
1615
+ name, chunk, block);
1616
+ }
1617
+ else
1618
+ {
1619
+ int fidx = MemoryChunkGetValue(chunk);
1620
+
1621
+ if (!FreeListIdxIsValid(fidx))
1622
+ elog(WARNING, "problem in alloc set %s: bad chunk size for chunk %p in block %p",
1623
+ name, chunk, block);
1624
+
1625
+ chsize = GetChunkSizeFromFreeListIdx(fidx); /* aligned chunk size */
1479
1626
 
1480
- chsize = chunk->size; /* aligned chunk size */
1627
+ /*
1628
+ * Check the stored block offset correctly references this
1629
+ * block.
1630
+ */
1631
+ if (block != MemoryChunkGetBlock(chunk))
1632
+ elog(WARNING, "problem in alloc set %s: bad block offset for chunk %p in block %p",
1633
+ name, chunk, block);
1634
+ }
1481
1635
  dsize = chunk->requested_size; /* real data */
1482
1636
 
1483
- /*
1484
- * Check chunk size
1485
- */
1486
- if (dsize > chsize)
1637
+ /* an allocated chunk's requested size must be <= the chsize */
1638
+ if (dsize != InvalidAllocSize && dsize > chsize)
1487
1639
  elog(WARNING, "problem in alloc set %s: req size > alloc size for chunk %p in block %p",
1488
1640
  name, chunk, block);
1641
+
1642
+ /* chsize must not be smaller than the first freelist's size */
1489
1643
  if (chsize < (1 << ALLOC_MINBITS))
1490
1644
  elog(WARNING, "problem in alloc set %s: bad size %zu for chunk %p in block %p",
1491
1645
  name, chsize, chunk, block);
1492
1646
 
1493
- /* single-chunk block? */
1494
- if (chsize > set->allocChunkLimit &&
1495
- chsize + ALLOC_CHUNKHDRSZ != blk_used)
1496
- elog(WARNING, "problem in alloc set %s: bad single-chunk %p in block %p",
1497
- name, chunk, block);
1498
-
1499
- /*
1500
- * If chunk is allocated, check for correct aset pointer. (If it's
1501
- * free, the aset is the freelist pointer, which we can't check as
1502
- * easily...) Note this is an incomplete test, since palloc(0)
1503
- * produces an allocated chunk with requested_size == 0.
1504
- */
1505
- if (dsize > 0 && chunk->aset != (void *) set)
1506
- elog(WARNING, "problem in alloc set %s: bogus aset link in block %p, chunk %p",
1507
- name, block, chunk);
1508
-
1509
1647
  /*
1510
1648
  * Check for overwrite of padding space in an allocated chunk.
1511
1649
  */
1512
- if (chunk->aset == (void *) set && dsize < chsize &&
1650
+ if (dsize != InvalidAllocSize && dsize < chsize &&
1513
1651
  !sentinel_ok(chunk, ALLOC_CHUNKHDRSZ + dsize))
1514
1652
  elog(WARNING, "problem in alloc set %s: detected write past chunk end in block %p, chunk %p",
1515
1653
  name, block, chunk);
1516
1654
 
1517
- /*
1518
- * If chunk is allocated, disallow external access to private part
1519
- * of chunk header.
1520
- */
1521
- if (chunk->aset == (void *) set)
1522
- VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOCCHUNK_PRIVATE_LEN);
1655
+ /* if chunk is allocated, disallow access to the chunk header */
1656
+ if (dsize != InvalidAllocSize)
1657
+ VALGRIND_MAKE_MEM_NOACCESS(chunk, ALLOC_CHUNKHDRSZ);
1523
1658
 
1524
1659
  blk_data += chsize;
1525
1660
  nchunks++;
@@ -1530,6 +1665,10 @@ AllocSetCheck(MemoryContext context)
1530
1665
  if ((blk_data + (nchunks * ALLOC_CHUNKHDRSZ)) != blk_used)
1531
1666
  elog(WARNING, "problem in alloc set %s: found inconsistent memory block %p",
1532
1667
  name, block);
1668
+
1669
+ if (has_external_chunk && nchunks > 1)
1670
+ elog(WARNING, "problem in alloc set %s: external chunk on non-dedicated block %p",
1671
+ name, block);
1533
1672
  }
1534
1673
 
1535
1674
  Assert(total_allocated == context->mem_allocated);