pg_query 1.1.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (478) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +163 -52
  3. data/README.md +80 -69
  4. data/Rakefile +82 -1
  5. data/ext/pg_query/extconf.rb +3 -31
  6. data/ext/pg_query/guc-file.c +0 -0
  7. data/ext/pg_query/include/access/amapi.h +246 -0
  8. data/ext/pg_query/include/access/attmap.h +52 -0
  9. data/ext/pg_query/include/access/attnum.h +64 -0
  10. data/ext/pg_query/include/access/clog.h +61 -0
  11. data/ext/pg_query/include/access/commit_ts.h +77 -0
  12. data/ext/pg_query/include/access/detoast.h +92 -0
  13. data/ext/pg_query/include/access/genam.h +228 -0
  14. data/ext/pg_query/include/access/gin.h +78 -0
  15. data/ext/pg_query/include/access/htup.h +89 -0
  16. data/ext/pg_query/include/access/htup_details.h +819 -0
  17. data/ext/pg_query/include/access/itup.h +161 -0
  18. data/ext/pg_query/include/access/parallel.h +82 -0
  19. data/ext/pg_query/include/access/printtup.h +35 -0
  20. data/ext/pg_query/include/access/relation.h +28 -0
  21. data/ext/pg_query/include/access/relscan.h +176 -0
  22. data/ext/pg_query/include/access/rmgr.h +35 -0
  23. data/ext/pg_query/include/access/rmgrlist.h +49 -0
  24. data/ext/pg_query/include/access/sdir.h +58 -0
  25. data/ext/pg_query/include/access/skey.h +151 -0
  26. data/ext/pg_query/include/access/stratnum.h +83 -0
  27. data/ext/pg_query/include/access/sysattr.h +29 -0
  28. data/ext/pg_query/include/access/table.h +27 -0
  29. data/ext/pg_query/include/access/tableam.h +1825 -0
  30. data/ext/pg_query/include/access/transam.h +265 -0
  31. data/ext/pg_query/include/access/tupconvert.h +51 -0
  32. data/ext/pg_query/include/access/tupdesc.h +154 -0
  33. data/ext/pg_query/include/access/tupmacs.h +247 -0
  34. data/ext/pg_query/include/access/twophase.h +61 -0
  35. data/ext/pg_query/include/access/xact.h +463 -0
  36. data/ext/pg_query/include/access/xlog.h +398 -0
  37. data/ext/pg_query/include/access/xlog_internal.h +330 -0
  38. data/ext/pg_query/include/access/xlogdefs.h +109 -0
  39. data/ext/pg_query/include/access/xloginsert.h +64 -0
  40. data/ext/pg_query/include/access/xlogreader.h +327 -0
  41. data/ext/pg_query/include/access/xlogrecord.h +227 -0
  42. data/ext/pg_query/include/bootstrap/bootstrap.h +62 -0
  43. data/ext/pg_query/include/c.h +1322 -0
  44. data/ext/pg_query/include/catalog/catalog.h +42 -0
  45. data/ext/pg_query/include/catalog/catversion.h +58 -0
  46. data/ext/pg_query/include/catalog/dependency.h +275 -0
  47. data/ext/pg_query/include/catalog/genbki.h +64 -0
  48. data/ext/pg_query/include/catalog/index.h +199 -0
  49. data/ext/pg_query/include/catalog/indexing.h +366 -0
  50. data/ext/pg_query/include/catalog/namespace.h +188 -0
  51. data/ext/pg_query/include/catalog/objectaccess.h +197 -0
  52. data/ext/pg_query/include/catalog/objectaddress.h +84 -0
  53. data/ext/pg_query/include/catalog/pg_aggregate.h +176 -0
  54. data/ext/pg_query/include/catalog/pg_aggregate_d.h +77 -0
  55. data/ext/pg_query/include/catalog/pg_am.h +60 -0
  56. data/ext/pg_query/include/catalog/pg_am_d.h +45 -0
  57. data/ext/pg_query/include/catalog/pg_attribute.h +204 -0
  58. data/ext/pg_query/include/catalog/pg_attribute_d.h +59 -0
  59. data/ext/pg_query/include/catalog/pg_authid.h +58 -0
  60. data/ext/pg_query/include/catalog/pg_authid_d.h +49 -0
  61. data/ext/pg_query/include/catalog/pg_class.h +200 -0
  62. data/ext/pg_query/include/catalog/pg_class_d.h +103 -0
  63. data/ext/pg_query/include/catalog/pg_collation.h +73 -0
  64. data/ext/pg_query/include/catalog/pg_collation_d.h +45 -0
  65. data/ext/pg_query/include/catalog/pg_constraint.h +247 -0
  66. data/ext/pg_query/include/catalog/pg_constraint_d.h +67 -0
  67. data/ext/pg_query/include/catalog/pg_control.h +250 -0
  68. data/ext/pg_query/include/catalog/pg_conversion.h +72 -0
  69. data/ext/pg_query/include/catalog/pg_conversion_d.h +35 -0
  70. data/ext/pg_query/include/catalog/pg_depend.h +73 -0
  71. data/ext/pg_query/include/catalog/pg_depend_d.h +34 -0
  72. data/ext/pg_query/include/catalog/pg_event_trigger.h +51 -0
  73. data/ext/pg_query/include/catalog/pg_event_trigger_d.h +34 -0
  74. data/ext/pg_query/include/catalog/pg_index.h +80 -0
  75. data/ext/pg_query/include/catalog/pg_index_d.h +56 -0
  76. data/ext/pg_query/include/catalog/pg_language.h +67 -0
  77. data/ext/pg_query/include/catalog/pg_language_d.h +39 -0
  78. data/ext/pg_query/include/catalog/pg_namespace.h +59 -0
  79. data/ext/pg_query/include/catalog/pg_namespace_d.h +34 -0
  80. data/ext/pg_query/include/catalog/pg_opclass.h +85 -0
  81. data/ext/pg_query/include/catalog/pg_opclass_d.h +49 -0
  82. data/ext/pg_query/include/catalog/pg_operator.h +102 -0
  83. data/ext/pg_query/include/catalog/pg_operator_d.h +106 -0
  84. data/ext/pg_query/include/catalog/pg_opfamily.h +60 -0
  85. data/ext/pg_query/include/catalog/pg_opfamily_d.h +47 -0
  86. data/ext/pg_query/include/catalog/pg_partitioned_table.h +63 -0
  87. data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +35 -0
  88. data/ext/pg_query/include/catalog/pg_proc.h +211 -0
  89. data/ext/pg_query/include/catalog/pg_proc_d.h +99 -0
  90. data/ext/pg_query/include/catalog/pg_publication.h +115 -0
  91. data/ext/pg_query/include/catalog/pg_publication_d.h +36 -0
  92. data/ext/pg_query/include/catalog/pg_replication_origin.h +57 -0
  93. data/ext/pg_query/include/catalog/pg_replication_origin_d.h +29 -0
  94. data/ext/pg_query/include/catalog/pg_statistic.h +275 -0
  95. data/ext/pg_query/include/catalog/pg_statistic_d.h +194 -0
  96. data/ext/pg_query/include/catalog/pg_statistic_ext.h +74 -0
  97. data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +40 -0
  98. data/ext/pg_query/include/catalog/pg_transform.h +45 -0
  99. data/ext/pg_query/include/catalog/pg_transform_d.h +32 -0
  100. data/ext/pg_query/include/catalog/pg_trigger.h +137 -0
  101. data/ext/pg_query/include/catalog/pg_trigger_d.h +106 -0
  102. data/ext/pg_query/include/catalog/pg_ts_config.h +50 -0
  103. data/ext/pg_query/include/catalog/pg_ts_config_d.h +32 -0
  104. data/ext/pg_query/include/catalog/pg_ts_dict.h +54 -0
  105. data/ext/pg_query/include/catalog/pg_ts_dict_d.h +33 -0
  106. data/ext/pg_query/include/catalog/pg_ts_parser.h +57 -0
  107. data/ext/pg_query/include/catalog/pg_ts_parser_d.h +35 -0
  108. data/ext/pg_query/include/catalog/pg_ts_template.h +48 -0
  109. data/ext/pg_query/include/catalog/pg_ts_template_d.h +32 -0
  110. data/ext/pg_query/include/catalog/pg_type.h +372 -0
  111. data/ext/pg_query/include/catalog/pg_type_d.h +285 -0
  112. data/ext/pg_query/include/catalog/storage.h +48 -0
  113. data/ext/pg_query/include/commands/async.h +54 -0
  114. data/ext/pg_query/include/commands/dbcommands.h +35 -0
  115. data/ext/pg_query/include/commands/defrem.h +173 -0
  116. data/ext/pg_query/include/commands/event_trigger.h +88 -0
  117. data/ext/pg_query/include/commands/explain.h +127 -0
  118. data/ext/pg_query/include/commands/prepare.h +61 -0
  119. data/ext/pg_query/include/commands/tablespace.h +67 -0
  120. data/ext/pg_query/include/commands/trigger.h +277 -0
  121. data/ext/pg_query/include/commands/user.h +37 -0
  122. data/ext/pg_query/include/commands/vacuum.h +293 -0
  123. data/ext/pg_query/include/commands/variable.h +38 -0
  124. data/ext/pg_query/include/common/file_perm.h +56 -0
  125. data/ext/pg_query/include/common/hashfn.h +104 -0
  126. data/ext/pg_query/include/common/ip.h +37 -0
  127. data/ext/pg_query/include/common/keywords.h +33 -0
  128. data/ext/pg_query/include/common/kwlookup.h +44 -0
  129. data/ext/pg_query/include/common/relpath.h +90 -0
  130. data/ext/pg_query/include/common/string.h +19 -0
  131. data/ext/pg_query/include/common/unicode_combining_table.h +196 -0
  132. data/ext/pg_query/include/datatype/timestamp.h +197 -0
  133. data/ext/pg_query/include/executor/execdesc.h +70 -0
  134. data/ext/pg_query/include/executor/executor.h +614 -0
  135. data/ext/pg_query/include/executor/functions.h +41 -0
  136. data/ext/pg_query/include/executor/instrument.h +101 -0
  137. data/ext/pg_query/include/executor/spi.h +175 -0
  138. data/ext/pg_query/include/executor/tablefunc.h +67 -0
  139. data/ext/pg_query/include/executor/tuptable.h +487 -0
  140. data/ext/pg_query/include/fmgr.h +775 -0
  141. data/ext/pg_query/include/funcapi.h +348 -0
  142. data/ext/pg_query/include/getaddrinfo.h +162 -0
  143. data/ext/pg_query/include/jit/jit.h +105 -0
  144. data/ext/pg_query/include/kwlist_d.h +1072 -0
  145. data/ext/pg_query/include/lib/ilist.h +727 -0
  146. data/ext/pg_query/include/lib/pairingheap.h +102 -0
  147. data/ext/pg_query/include/lib/simplehash.h +1059 -0
  148. data/ext/pg_query/include/lib/stringinfo.h +161 -0
  149. data/ext/pg_query/include/libpq/auth.h +29 -0
  150. data/ext/pg_query/include/libpq/crypt.h +46 -0
  151. data/ext/pg_query/include/libpq/hba.h +140 -0
  152. data/ext/pg_query/include/libpq/libpq-be.h +326 -0
  153. data/ext/pg_query/include/libpq/libpq.h +133 -0
  154. data/ext/pg_query/include/libpq/pqcomm.h +208 -0
  155. data/ext/pg_query/include/libpq/pqformat.h +210 -0
  156. data/ext/pg_query/include/libpq/pqsignal.h +42 -0
  157. data/ext/pg_query/include/mb/pg_wchar.h +672 -0
  158. data/ext/pg_query/include/mb/stringinfo_mb.h +24 -0
  159. data/ext/pg_query/include/miscadmin.h +476 -0
  160. data/ext/pg_query/include/nodes/bitmapset.h +122 -0
  161. data/ext/pg_query/include/nodes/execnodes.h +2520 -0
  162. data/ext/pg_query/include/nodes/extensible.h +160 -0
  163. data/ext/pg_query/include/nodes/lockoptions.h +61 -0
  164. data/ext/pg_query/include/nodes/makefuncs.h +108 -0
  165. data/ext/pg_query/include/nodes/memnodes.h +108 -0
  166. data/ext/pg_query/include/nodes/nodeFuncs.h +162 -0
  167. data/ext/pg_query/include/nodes/nodes.h +842 -0
  168. data/ext/pg_query/include/nodes/params.h +170 -0
  169. data/ext/pg_query/include/nodes/parsenodes.h +3579 -0
  170. data/ext/pg_query/include/nodes/pathnodes.h +2556 -0
  171. data/ext/pg_query/include/nodes/pg_list.h +605 -0
  172. data/ext/pg_query/include/nodes/plannodes.h +1251 -0
  173. data/ext/pg_query/include/nodes/primnodes.h +1541 -0
  174. data/ext/pg_query/include/nodes/print.h +34 -0
  175. data/ext/pg_query/include/nodes/tidbitmap.h +75 -0
  176. data/ext/pg_query/include/nodes/value.h +61 -0
  177. data/ext/pg_query/include/optimizer/cost.h +206 -0
  178. data/ext/pg_query/include/optimizer/geqo.h +88 -0
  179. data/ext/pg_query/include/optimizer/geqo_gene.h +45 -0
  180. data/ext/pg_query/include/optimizer/optimizer.h +199 -0
  181. data/ext/pg_query/include/optimizer/paths.h +249 -0
  182. data/ext/pg_query/include/optimizer/planmain.h +119 -0
  183. data/ext/pg_query/include/parser/analyze.h +49 -0
  184. data/ext/pg_query/include/parser/gram.h +1067 -0
  185. data/ext/pg_query/include/parser/gramparse.h +75 -0
  186. data/ext/pg_query/include/parser/kwlist.h +477 -0
  187. data/ext/pg_query/include/parser/parse_agg.h +68 -0
  188. data/ext/pg_query/include/parser/parse_clause.h +54 -0
  189. data/ext/pg_query/include/parser/parse_coerce.h +97 -0
  190. data/ext/pg_query/include/parser/parse_collate.h +27 -0
  191. data/ext/pg_query/include/parser/parse_expr.h +26 -0
  192. data/ext/pg_query/include/parser/parse_func.h +73 -0
  193. data/ext/pg_query/include/parser/parse_node.h +327 -0
  194. data/ext/pg_query/include/parser/parse_oper.h +67 -0
  195. data/ext/pg_query/include/parser/parse_relation.h +123 -0
  196. data/ext/pg_query/include/parser/parse_target.h +46 -0
  197. data/ext/pg_query/include/parser/parse_type.h +60 -0
  198. data/ext/pg_query/include/parser/parser.h +41 -0
  199. data/ext/pg_query/include/parser/parsetree.h +61 -0
  200. data/ext/pg_query/include/parser/scanner.h +152 -0
  201. data/ext/pg_query/include/parser/scansup.h +30 -0
  202. data/ext/pg_query/include/partitioning/partdefs.h +26 -0
  203. data/ext/pg_query/include/pg_config.h +988 -0
  204. data/ext/pg_query/include/pg_config_ext.h +8 -0
  205. data/ext/pg_query/include/pg_config_manual.h +350 -0
  206. data/ext/pg_query/include/pg_config_os.h +8 -0
  207. data/ext/pg_query/include/pg_getopt.h +56 -0
  208. data/ext/pg_query/include/pg_query.h +121 -0
  209. data/ext/pg_query/include/pg_query_enum_defs.c +2454 -0
  210. data/ext/pg_query/include/pg_query_fingerprint_conds.c +875 -0
  211. data/ext/pg_query/include/pg_query_fingerprint_defs.c +12413 -0
  212. data/ext/pg_query/include/pg_query_json_helper.c +61 -0
  213. data/ext/pg_query/include/pg_query_outfuncs_conds.c +686 -0
  214. data/ext/pg_query/include/pg_query_outfuncs_defs.c +2437 -0
  215. data/ext/pg_query/include/pg_query_readfuncs_conds.c +222 -0
  216. data/ext/pg_query/include/pg_query_readfuncs_defs.c +2878 -0
  217. data/ext/pg_query/include/pg_trace.h +17 -0
  218. data/ext/pg_query/include/pgstat.h +1487 -0
  219. data/ext/pg_query/include/pgtime.h +84 -0
  220. data/ext/pg_query/include/pl_gram.h +385 -0
  221. data/ext/pg_query/include/pl_reserved_kwlist.h +52 -0
  222. data/ext/pg_query/include/pl_reserved_kwlist_d.h +114 -0
  223. data/ext/pg_query/include/pl_unreserved_kwlist.h +112 -0
  224. data/ext/pg_query/include/pl_unreserved_kwlist_d.h +246 -0
  225. data/ext/pg_query/include/plerrcodes.h +990 -0
  226. data/ext/pg_query/include/plpgsql.h +1347 -0
  227. data/ext/pg_query/include/port.h +524 -0
  228. data/ext/pg_query/include/port/atomics.h +524 -0
  229. data/ext/pg_query/include/port/atomics/arch-arm.h +26 -0
  230. data/ext/pg_query/include/port/atomics/arch-ppc.h +254 -0
  231. data/ext/pg_query/include/port/atomics/arch-x86.h +252 -0
  232. data/ext/pg_query/include/port/atomics/fallback.h +170 -0
  233. data/ext/pg_query/include/port/atomics/generic-gcc.h +286 -0
  234. data/ext/pg_query/include/port/atomics/generic.h +401 -0
  235. data/ext/pg_query/include/port/pg_bitutils.h +226 -0
  236. data/ext/pg_query/include/port/pg_bswap.h +161 -0
  237. data/ext/pg_query/include/port/pg_crc32c.h +101 -0
  238. data/ext/pg_query/include/portability/instr_time.h +256 -0
  239. data/ext/pg_query/include/postgres.h +764 -0
  240. data/ext/pg_query/include/postgres_ext.h +74 -0
  241. data/ext/pg_query/include/postmaster/autovacuum.h +83 -0
  242. data/ext/pg_query/include/postmaster/bgworker.h +161 -0
  243. data/ext/pg_query/include/postmaster/bgworker_internals.h +64 -0
  244. data/ext/pg_query/include/postmaster/bgwriter.h +45 -0
  245. data/ext/pg_query/include/postmaster/fork_process.h +17 -0
  246. data/ext/pg_query/include/postmaster/interrupt.h +32 -0
  247. data/ext/pg_query/include/postmaster/pgarch.h +39 -0
  248. data/ext/pg_query/include/postmaster/postmaster.h +77 -0
  249. data/ext/pg_query/include/postmaster/syslogger.h +98 -0
  250. data/ext/pg_query/include/postmaster/walwriter.h +21 -0
  251. data/ext/pg_query/include/protobuf-c.h +1106 -0
  252. data/ext/pg_query/include/protobuf-c/protobuf-c.h +1106 -0
  253. data/ext/pg_query/include/protobuf/pg_query.pb-c.h +10846 -0
  254. data/ext/pg_query/include/protobuf/pg_query.pb.h +124718 -0
  255. data/ext/pg_query/include/regex/regex.h +184 -0
  256. data/ext/pg_query/include/replication/logicallauncher.h +31 -0
  257. data/ext/pg_query/include/replication/logicalproto.h +110 -0
  258. data/ext/pg_query/include/replication/logicalworker.h +19 -0
  259. data/ext/pg_query/include/replication/origin.h +73 -0
  260. data/ext/pg_query/include/replication/reorderbuffer.h +467 -0
  261. data/ext/pg_query/include/replication/slot.h +219 -0
  262. data/ext/pg_query/include/replication/syncrep.h +115 -0
  263. data/ext/pg_query/include/replication/walreceiver.h +340 -0
  264. data/ext/pg_query/include/replication/walsender.h +74 -0
  265. data/ext/pg_query/include/rewrite/prs2lock.h +46 -0
  266. data/ext/pg_query/include/rewrite/rewriteHandler.h +40 -0
  267. data/ext/pg_query/include/rewrite/rewriteManip.h +87 -0
  268. data/ext/pg_query/include/rewrite/rewriteSupport.h +26 -0
  269. data/ext/pg_query/include/storage/backendid.h +37 -0
  270. data/ext/pg_query/include/storage/block.h +121 -0
  271. data/ext/pg_query/include/storage/buf.h +46 -0
  272. data/ext/pg_query/include/storage/bufmgr.h +292 -0
  273. data/ext/pg_query/include/storage/bufpage.h +459 -0
  274. data/ext/pg_query/include/storage/condition_variable.h +62 -0
  275. data/ext/pg_query/include/storage/dsm.h +61 -0
  276. data/ext/pg_query/include/storage/dsm_impl.h +75 -0
  277. data/ext/pg_query/include/storage/fd.h +168 -0
  278. data/ext/pg_query/include/storage/ipc.h +81 -0
  279. data/ext/pg_query/include/storage/item.h +19 -0
  280. data/ext/pg_query/include/storage/itemid.h +184 -0
  281. data/ext/pg_query/include/storage/itemptr.h +206 -0
  282. data/ext/pg_query/include/storage/large_object.h +100 -0
  283. data/ext/pg_query/include/storage/latch.h +190 -0
  284. data/ext/pg_query/include/storage/lmgr.h +114 -0
  285. data/ext/pg_query/include/storage/lock.h +612 -0
  286. data/ext/pg_query/include/storage/lockdefs.h +59 -0
  287. data/ext/pg_query/include/storage/lwlock.h +232 -0
  288. data/ext/pg_query/include/storage/lwlocknames.h +51 -0
  289. data/ext/pg_query/include/storage/off.h +57 -0
  290. data/ext/pg_query/include/storage/pg_sema.h +61 -0
  291. data/ext/pg_query/include/storage/pg_shmem.h +90 -0
  292. data/ext/pg_query/include/storage/pmsignal.h +94 -0
  293. data/ext/pg_query/include/storage/predicate.h +87 -0
  294. data/ext/pg_query/include/storage/proc.h +333 -0
  295. data/ext/pg_query/include/storage/proclist_types.h +51 -0
  296. data/ext/pg_query/include/storage/procsignal.h +75 -0
  297. data/ext/pg_query/include/storage/relfilenode.h +99 -0
  298. data/ext/pg_query/include/storage/s_lock.h +1047 -0
  299. data/ext/pg_query/include/storage/sharedfileset.h +45 -0
  300. data/ext/pg_query/include/storage/shm_mq.h +85 -0
  301. data/ext/pg_query/include/storage/shm_toc.h +58 -0
  302. data/ext/pg_query/include/storage/shmem.h +81 -0
  303. data/ext/pg_query/include/storage/sinval.h +153 -0
  304. data/ext/pg_query/include/storage/sinvaladt.h +43 -0
  305. data/ext/pg_query/include/storage/smgr.h +109 -0
  306. data/ext/pg_query/include/storage/spin.h +77 -0
  307. data/ext/pg_query/include/storage/standby.h +91 -0
  308. data/ext/pg_query/include/storage/standbydefs.h +74 -0
  309. data/ext/pg_query/include/storage/sync.h +62 -0
  310. data/ext/pg_query/include/tcop/cmdtag.h +58 -0
  311. data/ext/pg_query/include/tcop/cmdtaglist.h +217 -0
  312. data/ext/pg_query/include/tcop/deparse_utility.h +108 -0
  313. data/ext/pg_query/include/tcop/dest.h +149 -0
  314. data/ext/pg_query/include/tcop/fastpath.h +21 -0
  315. data/ext/pg_query/include/tcop/pquery.h +45 -0
  316. data/ext/pg_query/include/tcop/tcopprot.h +89 -0
  317. data/ext/pg_query/include/tcop/utility.h +108 -0
  318. data/ext/pg_query/include/tsearch/ts_cache.h +98 -0
  319. data/ext/pg_query/include/utils/acl.h +312 -0
  320. data/ext/pg_query/include/utils/aclchk_internal.h +45 -0
  321. data/ext/pg_query/include/utils/array.h +458 -0
  322. data/ext/pg_query/include/utils/builtins.h +127 -0
  323. data/ext/pg_query/include/utils/bytea.h +27 -0
  324. data/ext/pg_query/include/utils/catcache.h +231 -0
  325. data/ext/pg_query/include/utils/date.h +90 -0
  326. data/ext/pg_query/include/utils/datetime.h +343 -0
  327. data/ext/pg_query/include/utils/datum.h +68 -0
  328. data/ext/pg_query/include/utils/dsa.h +123 -0
  329. data/ext/pg_query/include/utils/dynahash.h +19 -0
  330. data/ext/pg_query/include/utils/elog.h +439 -0
  331. data/ext/pg_query/include/utils/errcodes.h +352 -0
  332. data/ext/pg_query/include/utils/expandeddatum.h +159 -0
  333. data/ext/pg_query/include/utils/expandedrecord.h +231 -0
  334. data/ext/pg_query/include/utils/float.h +356 -0
  335. data/ext/pg_query/include/utils/fmgroids.h +2657 -0
  336. data/ext/pg_query/include/utils/fmgrprotos.h +2646 -0
  337. data/ext/pg_query/include/utils/fmgrtab.h +48 -0
  338. data/ext/pg_query/include/utils/guc.h +443 -0
  339. data/ext/pg_query/include/utils/guc_tables.h +272 -0
  340. data/ext/pg_query/include/utils/hsearch.h +149 -0
  341. data/ext/pg_query/include/utils/inval.h +64 -0
  342. data/ext/pg_query/include/utils/lsyscache.h +197 -0
  343. data/ext/pg_query/include/utils/memdebug.h +82 -0
  344. data/ext/pg_query/include/utils/memutils.h +225 -0
  345. data/ext/pg_query/include/utils/numeric.h +76 -0
  346. data/ext/pg_query/include/utils/palloc.h +136 -0
  347. data/ext/pg_query/include/utils/partcache.h +102 -0
  348. data/ext/pg_query/include/utils/pg_locale.h +119 -0
  349. data/ext/pg_query/include/utils/pg_lsn.h +29 -0
  350. data/ext/pg_query/include/utils/pidfile.h +56 -0
  351. data/ext/pg_query/include/utils/plancache.h +235 -0
  352. data/ext/pg_query/include/utils/portal.h +241 -0
  353. data/ext/pg_query/include/utils/probes.h +114 -0
  354. data/ext/pg_query/include/utils/ps_status.h +25 -0
  355. data/ext/pg_query/include/utils/queryenvironment.h +74 -0
  356. data/ext/pg_query/include/utils/regproc.h +28 -0
  357. data/ext/pg_query/include/utils/rel.h +644 -0
  358. data/ext/pg_query/include/utils/relcache.h +151 -0
  359. data/ext/pg_query/include/utils/reltrigger.h +81 -0
  360. data/ext/pg_query/include/utils/resowner.h +86 -0
  361. data/ext/pg_query/include/utils/rls.h +50 -0
  362. data/ext/pg_query/include/utils/ruleutils.h +44 -0
  363. data/ext/pg_query/include/utils/sharedtuplestore.h +61 -0
  364. data/ext/pg_query/include/utils/snapmgr.h +158 -0
  365. data/ext/pg_query/include/utils/snapshot.h +206 -0
  366. data/ext/pg_query/include/utils/sortsupport.h +276 -0
  367. data/ext/pg_query/include/utils/syscache.h +219 -0
  368. data/ext/pg_query/include/utils/timeout.h +88 -0
  369. data/ext/pg_query/include/utils/timestamp.h +116 -0
  370. data/ext/pg_query/include/utils/tuplesort.h +277 -0
  371. data/ext/pg_query/include/utils/tuplestore.h +91 -0
  372. data/ext/pg_query/include/utils/typcache.h +202 -0
  373. data/ext/pg_query/include/utils/tzparser.h +39 -0
  374. data/ext/pg_query/include/utils/varlena.h +39 -0
  375. data/ext/pg_query/include/utils/xml.h +84 -0
  376. data/ext/pg_query/include/xxhash.h +5445 -0
  377. data/ext/pg_query/include/xxhash/xxhash.h +5445 -0
  378. data/ext/pg_query/pg_query.c +104 -0
  379. data/ext/pg_query/pg_query.pb-c.c +37628 -0
  380. data/ext/pg_query/pg_query_deparse.c +9953 -0
  381. data/ext/pg_query/pg_query_fingerprint.c +292 -0
  382. data/ext/pg_query/pg_query_fingerprint.h +8 -0
  383. data/ext/pg_query/pg_query_internal.h +24 -0
  384. data/ext/pg_query/pg_query_json_plpgsql.c +738 -0
  385. data/ext/pg_query/pg_query_json_plpgsql.h +9 -0
  386. data/ext/pg_query/pg_query_normalize.c +437 -0
  387. data/ext/pg_query/pg_query_outfuncs.h +10 -0
  388. data/ext/pg_query/pg_query_outfuncs_json.c +297 -0
  389. data/ext/pg_query/pg_query_outfuncs_protobuf.c +237 -0
  390. data/ext/pg_query/pg_query_parse.c +148 -0
  391. data/ext/pg_query/pg_query_parse_plpgsql.c +460 -0
  392. data/ext/pg_query/pg_query_readfuncs.h +11 -0
  393. data/ext/pg_query/pg_query_readfuncs_protobuf.c +142 -0
  394. data/ext/pg_query/pg_query_ruby.c +108 -12
  395. data/ext/pg_query/pg_query_scan.c +173 -0
  396. data/ext/pg_query/pg_query_split.c +221 -0
  397. data/ext/pg_query/protobuf-c.c +3660 -0
  398. data/ext/pg_query/src_backend_catalog_namespace.c +1051 -0
  399. data/ext/pg_query/src_backend_catalog_pg_proc.c +142 -0
  400. data/ext/pg_query/src_backend_commands_define.c +117 -0
  401. data/ext/pg_query/src_backend_libpq_pqcomm.c +651 -0
  402. data/ext/pg_query/src_backend_nodes_bitmapset.c +513 -0
  403. data/ext/pg_query/src_backend_nodes_copyfuncs.c +6013 -0
  404. data/ext/pg_query/src_backend_nodes_equalfuncs.c +4003 -0
  405. data/ext/pg_query/src_backend_nodes_extensible.c +99 -0
  406. data/ext/pg_query/src_backend_nodes_list.c +922 -0
  407. data/ext/pg_query/src_backend_nodes_makefuncs.c +417 -0
  408. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +1363 -0
  409. data/ext/pg_query/src_backend_nodes_value.c +84 -0
  410. data/ext/pg_query/src_backend_parser_gram.c +47456 -0
  411. data/ext/pg_query/src_backend_parser_parse_expr.c +313 -0
  412. data/ext/pg_query/src_backend_parser_parser.c +497 -0
  413. data/ext/pg_query/src_backend_parser_scan.c +7091 -0
  414. data/ext/pg_query/src_backend_parser_scansup.c +160 -0
  415. data/ext/pg_query/src_backend_postmaster_postmaster.c +2230 -0
  416. data/ext/pg_query/src_backend_storage_ipc_ipc.c +192 -0
  417. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +370 -0
  418. data/ext/pg_query/src_backend_tcop_postgres.c +776 -0
  419. data/ext/pg_query/src_backend_utils_adt_datum.c +326 -0
  420. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +98 -0
  421. data/ext/pg_query/src_backend_utils_adt_format_type.c +136 -0
  422. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +1683 -0
  423. data/ext/pg_query/src_backend_utils_error_assert.c +74 -0
  424. data/ext/pg_query/src_backend_utils_error_elog.c +1748 -0
  425. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +570 -0
  426. data/ext/pg_query/src_backend_utils_hash_dynahash.c +1086 -0
  427. data/ext/pg_query/src_backend_utils_init_globals.c +168 -0
  428. data/ext/pg_query/src_backend_utils_mb_mbutils.c +839 -0
  429. data/ext/pg_query/src_backend_utils_misc_guc.c +1831 -0
  430. data/ext/pg_query/src_backend_utils_mmgr_aset.c +1560 -0
  431. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +1006 -0
  432. data/ext/pg_query/src_common_encnames.c +158 -0
  433. data/ext/pg_query/src_common_keywords.c +39 -0
  434. data/ext/pg_query/src_common_kwlist_d.h +1081 -0
  435. data/ext/pg_query/src_common_kwlookup.c +91 -0
  436. data/ext/pg_query/src_common_psprintf.c +158 -0
  437. data/ext/pg_query/src_common_string.c +86 -0
  438. data/ext/pg_query/src_common_stringinfo.c +336 -0
  439. data/ext/pg_query/src_common_wchar.c +1651 -0
  440. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +1133 -0
  441. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +877 -0
  442. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +6533 -0
  443. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +107 -0
  444. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +123 -0
  445. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +671 -0
  446. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +255 -0
  447. data/ext/pg_query/src_port_erand48.c +127 -0
  448. data/ext/pg_query/src_port_pg_bitutils.c +246 -0
  449. data/ext/pg_query/src_port_pgsleep.c +69 -0
  450. data/ext/pg_query/src_port_pgstrcasecmp.c +83 -0
  451. data/ext/pg_query/src_port_qsort.c +240 -0
  452. data/ext/pg_query/src_port_random.c +31 -0
  453. data/ext/pg_query/src_port_snprintf.c +1449 -0
  454. data/ext/pg_query/src_port_strerror.c +324 -0
  455. data/ext/pg_query/src_port_strnlen.c +39 -0
  456. data/ext/pg_query/xxhash.c +43 -0
  457. data/lib/pg_query.rb +7 -4
  458. data/lib/pg_query/constants.rb +21 -0
  459. data/lib/pg_query/deparse.rb +16 -1117
  460. data/lib/pg_query/filter_columns.rb +86 -85
  461. data/lib/pg_query/fingerprint.rb +122 -87
  462. data/lib/pg_query/json_field_names.rb +1402 -0
  463. data/lib/pg_query/node.rb +31 -0
  464. data/lib/pg_query/param_refs.rb +42 -37
  465. data/lib/pg_query/parse.rb +220 -200
  466. data/lib/pg_query/parse_error.rb +1 -1
  467. data/lib/pg_query/pg_query_pb.rb +3211 -0
  468. data/lib/pg_query/scan.rb +23 -0
  469. data/lib/pg_query/treewalker.rb +24 -40
  470. data/lib/pg_query/truncate.rb +64 -43
  471. data/lib/pg_query/version.rb +2 -2
  472. metadata +473 -11
  473. data/ext/pg_query/pg_query_ruby.h +0 -10
  474. data/lib/pg_query/deep_dup.rb +0 -16
  475. data/lib/pg_query/deparse/alter_table.rb +0 -42
  476. data/lib/pg_query/deparse/interval.rb +0 -105
  477. data/lib/pg_query/legacy_parsetree.rb +0 -109
  478. data/lib/pg_query/node_types.rb +0 -284
@@ -0,0 +1,190 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * latch.h
4
+ * Routines for interprocess latches
5
+ *
6
+ * A latch is a boolean variable, with operations that let processes sleep
7
+ * until it is set. A latch can be set from another process, or a signal
8
+ * handler within the same process.
9
+ *
10
+ * The latch interface is a reliable replacement for the common pattern of
11
+ * using pg_usleep() or select() to wait until a signal arrives, where the
12
+ * signal handler sets a flag variable. Because on some platforms an
13
+ * incoming signal doesn't interrupt sleep, and even on platforms where it
14
+ * does there is a race condition if the signal arrives just before
15
+ * entering the sleep, the common pattern must periodically wake up and
16
+ * poll the flag variable. The pselect() system call was invented to solve
17
+ * this problem, but it is not portable enough. Latches are designed to
18
+ * overcome these limitations, allowing you to sleep without polling and
19
+ * ensuring quick response to signals from other processes.
20
+ *
21
+ * There are two kinds of latches: local and shared. A local latch is
22
+ * initialized by InitLatch, and can only be set from the same process.
23
+ * A local latch can be used to wait for a signal to arrive, by calling
24
+ * SetLatch in the signal handler. A shared latch resides in shared memory,
25
+ * and must be initialized at postmaster startup by InitSharedLatch. Before
26
+ * a shared latch can be waited on, it must be associated with a process
27
+ * with OwnLatch. Only the process owning the latch can wait on it, but any
28
+ * process can set it.
29
+ *
30
+ * There are three basic operations on a latch:
31
+ *
32
+ * SetLatch - Sets the latch
33
+ * ResetLatch - Clears the latch, allowing it to be set again
34
+ * WaitLatch - Waits for the latch to become set
35
+ *
36
+ * WaitLatch includes a provision for timeouts (which should be avoided
37
+ * when possible, as they incur extra overhead) and a provision for
38
+ * postmaster child processes to wake up immediately on postmaster death.
39
+ * See latch.c for detailed specifications for the exported functions.
40
+ *
41
+ * The correct pattern to wait for event(s) is:
42
+ *
43
+ * for (;;)
44
+ * {
45
+ * ResetLatch();
46
+ * if (work to do)
47
+ * Do Stuff();
48
+ * WaitLatch();
49
+ * }
50
+ *
51
+ * It's important to reset the latch *before* checking if there's work to
52
+ * do. Otherwise, if someone sets the latch between the check and the
53
+ * ResetLatch call, you will miss it and Wait will incorrectly block.
54
+ *
55
+ * Another valid coding pattern looks like:
56
+ *
57
+ * for (;;)
58
+ * {
59
+ * if (work to do)
60
+ * Do Stuff(); // in particular, exit loop if some condition satisfied
61
+ * WaitLatch();
62
+ * ResetLatch();
63
+ * }
64
+ *
65
+ * This is useful to reduce latch traffic if it's expected that the loop's
66
+ * termination condition will often be satisfied in the first iteration;
67
+ * the cost is an extra loop iteration before blocking when it is not.
68
+ * What must be avoided is placing any checks for asynchronous events after
69
+ * WaitLatch and before ResetLatch, as that creates a race condition.
70
+ *
71
+ * To wake up the waiter, you must first set a global flag or something
72
+ * else that the wait loop tests in the "if (work to do)" part, and call
73
+ * SetLatch *after* that. SetLatch is designed to return quickly if the
74
+ * latch is already set.
75
+ *
76
+ * On some platforms, signals will not interrupt the latch wait primitive
77
+ * by themselves. Therefore, it is critical that any signal handler that
78
+ * is meant to terminate a WaitLatch wait calls SetLatch.
79
+ *
80
+ * Note that use of the process latch (PGPROC.procLatch) is generally better
81
+ * than an ad-hoc shared latch for signaling auxiliary processes. This is
82
+ * because generic signal handlers will call SetLatch on the process latch
83
+ * only, so using any latch other than the process latch effectively precludes
84
+ * use of any generic handler.
85
+ *
86
+ *
87
+ * WaitEventSets allow to wait for latches being set and additional events -
88
+ * postmaster dying and socket readiness of several sockets currently - at the
89
+ * same time. On many platforms using a long lived event set is more
90
+ * efficient than using WaitLatch or WaitLatchOrSocket.
91
+ *
92
+ *
93
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
94
+ * Portions Copyright (c) 1994, Regents of the University of California
95
+ *
96
+ * src/include/storage/latch.h
97
+ *
98
+ *-------------------------------------------------------------------------
99
+ */
100
+ #ifndef LATCH_H
101
+ #define LATCH_H
102
+
103
+ #include <signal.h>
104
+
105
+ /*
106
+ * Latch structure should be treated as opaque and only accessed through
107
+ * the public functions. It is defined here to allow embedding Latches as
108
+ * part of bigger structs.
109
+ */
110
+ typedef struct Latch
111
+ {
112
+ sig_atomic_t is_set;
113
+ bool is_shared;
114
+ int owner_pid;
115
+ #ifdef WIN32
116
+ HANDLE event;
117
+ #endif
118
+ } Latch;
119
+
120
+ /*
121
+ * Bitmasks for events that may wake-up WaitLatch(), WaitLatchOrSocket(), or
122
+ * WaitEventSetWait().
123
+ */
124
+ #define WL_LATCH_SET (1 << 0)
125
+ #define WL_SOCKET_READABLE (1 << 1)
126
+ #define WL_SOCKET_WRITEABLE (1 << 2)
127
+ #define WL_TIMEOUT (1 << 3) /* not for WaitEventSetWait() */
128
+ #define WL_POSTMASTER_DEATH (1 << 4)
129
+ #define WL_EXIT_ON_PM_DEATH (1 << 5)
130
+ #ifdef WIN32
131
+ #define WL_SOCKET_CONNECTED (1 << 6)
132
+ #else
133
+ /* avoid having to deal with case on platforms not requiring it */
134
+ #define WL_SOCKET_CONNECTED WL_SOCKET_WRITEABLE
135
+ #endif
136
+
137
+ #define WL_SOCKET_MASK (WL_SOCKET_READABLE | \
138
+ WL_SOCKET_WRITEABLE | \
139
+ WL_SOCKET_CONNECTED)
140
+
141
+ typedef struct WaitEvent
142
+ {
143
+ int pos; /* position in the event data structure */
144
+ uint32 events; /* triggered events */
145
+ pgsocket fd; /* socket fd associated with event */
146
+ void *user_data; /* pointer provided in AddWaitEventToSet */
147
+ #ifdef WIN32
148
+ bool reset; /* Is reset of the event required? */
149
+ #endif
150
+ } WaitEvent;
151
+
152
+ /* forward declaration to avoid exposing latch.c implementation details */
153
+ typedef struct WaitEventSet WaitEventSet;
154
+
155
+ /*
156
+ * prototypes for functions in latch.c
157
+ */
158
+ extern void InitializeLatchSupport(void);
159
+ extern void InitLatch(Latch *latch);
160
+ extern void InitSharedLatch(Latch *latch);
161
+ extern void OwnLatch(Latch *latch);
162
+ extern void DisownLatch(Latch *latch);
163
+ extern void SetLatch(Latch *latch);
164
+ extern void ResetLatch(Latch *latch);
165
+
166
+ extern WaitEventSet *CreateWaitEventSet(MemoryContext context, int nevents);
167
+ extern void FreeWaitEventSet(WaitEventSet *set);
168
+ extern int AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd,
169
+ Latch *latch, void *user_data);
170
+ extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch);
171
+
172
+ extern int WaitEventSetWait(WaitEventSet *set, long timeout,
173
+ WaitEvent *occurred_events, int nevents,
174
+ uint32 wait_event_info);
175
+ extern int WaitLatch(Latch *latch, int wakeEvents, long timeout,
176
+ uint32 wait_event_info);
177
+ extern int WaitLatchOrSocket(Latch *latch, int wakeEvents,
178
+ pgsocket sock, long timeout, uint32 wait_event_info);
179
+
180
+ /*
181
+ * Unix implementation uses SIGUSR1 for inter-process signaling.
182
+ * Win32 doesn't need this.
183
+ */
184
+ #ifndef WIN32
185
+ extern void latch_sigusr1_handler(void);
186
+ #else
187
+ #define latch_sigusr1_handler() ((void) 0)
188
+ #endif
189
+
190
+ #endif /* LATCH_H */
@@ -0,0 +1,114 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * lmgr.h
4
+ * POSTGRES lock manager definitions.
5
+ *
6
+ *
7
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8
+ * Portions Copyright (c) 1994, Regents of the University of California
9
+ *
10
+ * src/include/storage/lmgr.h
11
+ *
12
+ *-------------------------------------------------------------------------
13
+ */
14
+ #ifndef LMGR_H
15
+ #define LMGR_H
16
+
17
+ #include "lib/stringinfo.h"
18
+ #include "storage/itemptr.h"
19
+ #include "storage/lock.h"
20
+ #include "utils/rel.h"
21
+
22
+
23
+ /* XactLockTableWait operations */
24
+ typedef enum XLTW_Oper
25
+ {
26
+ XLTW_None,
27
+ XLTW_Update,
28
+ XLTW_Delete,
29
+ XLTW_Lock,
30
+ XLTW_LockUpdated,
31
+ XLTW_InsertIndex,
32
+ XLTW_InsertIndexUnique,
33
+ XLTW_FetchUpdated,
34
+ XLTW_RecheckExclusionConstr
35
+ } XLTW_Oper;
36
+
37
+ extern void RelationInitLockInfo(Relation relation);
38
+
39
+ /* Lock a relation */
40
+ extern void LockRelationOid(Oid relid, LOCKMODE lockmode);
41
+ extern bool ConditionalLockRelationOid(Oid relid, LOCKMODE lockmode);
42
+ extern void UnlockRelationId(LockRelId *relid, LOCKMODE lockmode);
43
+ extern void UnlockRelationOid(Oid relid, LOCKMODE lockmode);
44
+
45
+ extern void LockRelation(Relation relation, LOCKMODE lockmode);
46
+ extern bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode);
47
+ extern void UnlockRelation(Relation relation, LOCKMODE lockmode);
48
+ extern bool CheckRelationLockedByMe(Relation relation, LOCKMODE lockmode,
49
+ bool orstronger);
50
+ extern bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode);
51
+
52
+ extern void LockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode);
53
+ extern void UnlockRelationIdForSession(LockRelId *relid, LOCKMODE lockmode);
54
+
55
+ /* Lock a relation for extension */
56
+ extern void LockRelationForExtension(Relation relation, LOCKMODE lockmode);
57
+ extern void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode);
58
+ extern bool ConditionalLockRelationForExtension(Relation relation,
59
+ LOCKMODE lockmode);
60
+ extern int RelationExtensionLockWaiterCount(Relation relation);
61
+
62
+ /* Lock to recompute pg_database.datfrozenxid in the current database */
63
+ extern void LockDatabaseFrozenIds(LOCKMODE lockmode);
64
+
65
+ /* Lock a page (currently only used within indexes) */
66
+ extern void LockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
67
+ extern bool ConditionalLockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
68
+ extern void UnlockPage(Relation relation, BlockNumber blkno, LOCKMODE lockmode);
69
+
70
+ /* Lock a tuple (see heap_lock_tuple before assuming you understand this) */
71
+ extern void LockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode);
72
+ extern bool ConditionalLockTuple(Relation relation, ItemPointer tid,
73
+ LOCKMODE lockmode);
74
+ extern void UnlockTuple(Relation relation, ItemPointer tid, LOCKMODE lockmode);
75
+
76
+ /* Lock an XID (used to wait for a transaction to finish) */
77
+ extern void XactLockTableInsert(TransactionId xid);
78
+ extern void XactLockTableDelete(TransactionId xid);
79
+ extern void XactLockTableWait(TransactionId xid, Relation rel,
80
+ ItemPointer ctid, XLTW_Oper oper);
81
+ extern bool ConditionalXactLockTableWait(TransactionId xid);
82
+
83
+ /* Lock VXIDs, specified by conflicting locktags */
84
+ extern void WaitForLockers(LOCKTAG heaplocktag, LOCKMODE lockmode, bool progress);
85
+ extern void WaitForLockersMultiple(List *locktags, LOCKMODE lockmode, bool progress);
86
+
87
+ /* Lock an XID for tuple insertion (used to wait for an insertion to finish) */
88
+ extern uint32 SpeculativeInsertionLockAcquire(TransactionId xid);
89
+ extern void SpeculativeInsertionLockRelease(TransactionId xid);
90
+ extern void SpeculativeInsertionWait(TransactionId xid, uint32 token);
91
+
92
+ /* Lock a general object (other than a relation) of the current database */
93
+ extern void LockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
94
+ LOCKMODE lockmode);
95
+ extern void UnlockDatabaseObject(Oid classid, Oid objid, uint16 objsubid,
96
+ LOCKMODE lockmode);
97
+
98
+ /* Lock a shared-across-databases object (other than a relation) */
99
+ extern void LockSharedObject(Oid classid, Oid objid, uint16 objsubid,
100
+ LOCKMODE lockmode);
101
+ extern void UnlockSharedObject(Oid classid, Oid objid, uint16 objsubid,
102
+ LOCKMODE lockmode);
103
+
104
+ extern void LockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
105
+ LOCKMODE lockmode);
106
+ extern void UnlockSharedObjectForSession(Oid classid, Oid objid, uint16 objsubid,
107
+ LOCKMODE lockmode);
108
+
109
+ /* Describe a locktag for error messages */
110
+ extern void DescribeLockTag(StringInfo buf, const LOCKTAG *tag);
111
+
112
+ extern const char *GetLockNameFromTagType(uint16 locktag_type);
113
+
114
+ #endif /* LMGR_H */
@@ -0,0 +1,612 @@
1
+ /*-------------------------------------------------------------------------
2
+ *
3
+ * lock.h
4
+ * POSTGRES low-level lock mechanism
5
+ *
6
+ *
7
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
8
+ * Portions Copyright (c) 1994, Regents of the University of California
9
+ *
10
+ * src/include/storage/lock.h
11
+ *
12
+ *-------------------------------------------------------------------------
13
+ */
14
+ #ifndef LOCK_H_
15
+ #define LOCK_H_
16
+
17
+ #ifdef FRONTEND
18
+ #error "lock.h may not be included from frontend code"
19
+ #endif
20
+
21
+ #include "storage/backendid.h"
22
+ #include "storage/lockdefs.h"
23
+ #include "storage/lwlock.h"
24
+ #include "storage/shmem.h"
25
+
26
+ /* struct PGPROC is declared in proc.h, but must forward-reference it */
27
+ typedef struct PGPROC PGPROC;
28
+
29
+ typedef struct PROC_QUEUE
30
+ {
31
+ SHM_QUEUE links; /* head of list of PGPROC objects */
32
+ int size; /* number of entries in list */
33
+ } PROC_QUEUE;
34
+
35
+ /* GUC variables */
36
+ extern int max_locks_per_xact;
37
+
38
+ #ifdef LOCK_DEBUG
39
+ extern int Trace_lock_oidmin;
40
+ extern bool Trace_locks;
41
+ extern bool Trace_userlocks;
42
+ extern int Trace_lock_table;
43
+ extern bool Debug_deadlocks;
44
+ #endif /* LOCK_DEBUG */
45
+
46
+
47
+ /*
48
+ * Top-level transactions are identified by VirtualTransactionIDs comprising
49
+ * PGPROC fields backendId and lxid. For prepared transactions, the
50
+ * LocalTransactionId is an ordinary XID. These are guaranteed unique over
51
+ * the short term, but will be reused after a database restart or XID
52
+ * wraparound; hence they should never be stored on disk.
53
+ *
54
+ * Note that struct VirtualTransactionId can not be assumed to be atomically
55
+ * assignable as a whole. However, type LocalTransactionId is assumed to
56
+ * be atomically assignable, and the backend ID doesn't change often enough
57
+ * to be a problem, so we can fetch or assign the two fields separately.
58
+ * We deliberately refrain from using the struct within PGPROC, to prevent
59
+ * coding errors from trying to use struct assignment with it; instead use
60
+ * GET_VXID_FROM_PGPROC().
61
+ */
62
+ typedef struct
63
+ {
64
+ BackendId backendId; /* backendId from PGPROC */
65
+ LocalTransactionId localTransactionId; /* lxid from PGPROC */
66
+ } VirtualTransactionId;
67
+
68
+ #define InvalidLocalTransactionId 0
69
+ #define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId)
70
+ #define VirtualTransactionIdIsValid(vxid) \
71
+ (LocalTransactionIdIsValid((vxid).localTransactionId))
72
+ #define VirtualTransactionIdIsPreparedXact(vxid) \
73
+ ((vxid).backendId == InvalidBackendId)
74
+ #define VirtualTransactionIdEquals(vxid1, vxid2) \
75
+ ((vxid1).backendId == (vxid2).backendId && \
76
+ (vxid1).localTransactionId == (vxid2).localTransactionId)
77
+ #define SetInvalidVirtualTransactionId(vxid) \
78
+ ((vxid).backendId = InvalidBackendId, \
79
+ (vxid).localTransactionId = InvalidLocalTransactionId)
80
+ #define GET_VXID_FROM_PGPROC(vxid, proc) \
81
+ ((vxid).backendId = (proc).backendId, \
82
+ (vxid).localTransactionId = (proc).lxid)
83
+
84
+ /* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */
85
+ #define MAX_LOCKMODES 10
86
+
87
+ #define LOCKBIT_ON(lockmode) (1 << (lockmode))
88
+ #define LOCKBIT_OFF(lockmode) (~(1 << (lockmode)))
89
+
90
+
91
+ /*
92
+ * This data structure defines the locking semantics associated with a
93
+ * "lock method". The semantics specify the meaning of each lock mode
94
+ * (by defining which lock modes it conflicts with).
95
+ * All of this data is constant and is kept in const tables.
96
+ *
97
+ * numLockModes -- number of lock modes (READ,WRITE,etc) that
98
+ * are defined in this lock method. Must be less than MAX_LOCKMODES.
99
+ *
100
+ * conflictTab -- this is an array of bitmasks showing lock
101
+ * mode conflicts. conflictTab[i] is a mask with the j-th bit
102
+ * turned on if lock modes i and j conflict. Lock modes are
103
+ * numbered 1..numLockModes; conflictTab[0] is unused.
104
+ *
105
+ * lockModeNames -- ID strings for debug printouts.
106
+ *
107
+ * trace_flag -- pointer to GUC trace flag for this lock method. (The
108
+ * GUC variable is not constant, but we use "const" here to denote that
109
+ * it can't be changed through this reference.)
110
+ */
111
+ typedef struct LockMethodData
112
+ {
113
+ int numLockModes;
114
+ const LOCKMASK *conflictTab;
115
+ const char *const *lockModeNames;
116
+ const bool *trace_flag;
117
+ } LockMethodData;
118
+
119
+ typedef const LockMethodData *LockMethod;
120
+
121
+ /*
122
+ * Lock methods are identified by LOCKMETHODID. (Despite the declaration as
123
+ * uint16, we are constrained to 256 lockmethods by the layout of LOCKTAG.)
124
+ */
125
+ typedef uint16 LOCKMETHODID;
126
+
127
+ /* These identify the known lock methods */
128
+ #define DEFAULT_LOCKMETHOD 1
129
+ #define USER_LOCKMETHOD 2
130
+
131
+ /*
132
+ * LOCKTAG is the key information needed to look up a LOCK item in the
133
+ * lock hashtable. A LOCKTAG value uniquely identifies a lockable object.
134
+ *
135
+ * The LockTagType enum defines the different kinds of objects we can lock.
136
+ * We can handle up to 256 different LockTagTypes.
137
+ */
138
+ typedef enum LockTagType
139
+ {
140
+ LOCKTAG_RELATION, /* whole relation */
141
+ LOCKTAG_RELATION_EXTEND, /* the right to extend a relation */
142
+ LOCKTAG_DATABASE_FROZEN_IDS, /* pg_database.datfrozenxid */
143
+ LOCKTAG_PAGE, /* one page of a relation */
144
+ LOCKTAG_TUPLE, /* one physical tuple */
145
+ LOCKTAG_TRANSACTION, /* transaction (for waiting for xact done) */
146
+ LOCKTAG_VIRTUALTRANSACTION, /* virtual transaction (ditto) */
147
+ LOCKTAG_SPECULATIVE_TOKEN, /* speculative insertion Xid and token */
148
+ LOCKTAG_OBJECT, /* non-relation database object */
149
+ LOCKTAG_USERLOCK, /* reserved for old contrib/userlock code */
150
+ LOCKTAG_ADVISORY /* advisory user locks */
151
+ } LockTagType;
152
+
153
+ #define LOCKTAG_LAST_TYPE LOCKTAG_ADVISORY
154
+
155
+ extern const char *const LockTagTypeNames[];
156
+
157
+ /*
158
+ * The LOCKTAG struct is defined with malice aforethought to fit into 16
159
+ * bytes with no padding. Note that this would need adjustment if we were
160
+ * to widen Oid, BlockNumber, or TransactionId to more than 32 bits.
161
+ *
162
+ * We include lockmethodid in the locktag so that a single hash table in
163
+ * shared memory can store locks of different lockmethods.
164
+ */
165
+ typedef struct LOCKTAG
166
+ {
167
+ uint32 locktag_field1; /* a 32-bit ID field */
168
+ uint32 locktag_field2; /* a 32-bit ID field */
169
+ uint32 locktag_field3; /* a 32-bit ID field */
170
+ uint16 locktag_field4; /* a 16-bit ID field */
171
+ uint8 locktag_type; /* see enum LockTagType */
172
+ uint8 locktag_lockmethodid; /* lockmethod indicator */
173
+ } LOCKTAG;
174
+
175
+ /*
176
+ * These macros define how we map logical IDs of lockable objects into
177
+ * the physical fields of LOCKTAG. Use these to set up LOCKTAG values,
178
+ * rather than accessing the fields directly. Note multiple eval of target!
179
+ */
180
+
181
+ /* ID info for a relation is DB OID + REL OID; DB OID = 0 if shared */
182
+ #define SET_LOCKTAG_RELATION(locktag,dboid,reloid) \
183
+ ((locktag).locktag_field1 = (dboid), \
184
+ (locktag).locktag_field2 = (reloid), \
185
+ (locktag).locktag_field3 = 0, \
186
+ (locktag).locktag_field4 = 0, \
187
+ (locktag).locktag_type = LOCKTAG_RELATION, \
188
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
189
+
190
+ /* same ID info as RELATION */
191
+ #define SET_LOCKTAG_RELATION_EXTEND(locktag,dboid,reloid) \
192
+ ((locktag).locktag_field1 = (dboid), \
193
+ (locktag).locktag_field2 = (reloid), \
194
+ (locktag).locktag_field3 = 0, \
195
+ (locktag).locktag_field4 = 0, \
196
+ (locktag).locktag_type = LOCKTAG_RELATION_EXTEND, \
197
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
198
+
199
+ /* ID info for frozen IDs is DB OID */
200
+ #define SET_LOCKTAG_DATABASE_FROZEN_IDS(locktag,dboid) \
201
+ ((locktag).locktag_field1 = (dboid), \
202
+ (locktag).locktag_field2 = 0, \
203
+ (locktag).locktag_field3 = 0, \
204
+ (locktag).locktag_field4 = 0, \
205
+ (locktag).locktag_type = LOCKTAG_DATABASE_FROZEN_IDS, \
206
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
207
+
208
+ /* ID info for a page is RELATION info + BlockNumber */
209
+ #define SET_LOCKTAG_PAGE(locktag,dboid,reloid,blocknum) \
210
+ ((locktag).locktag_field1 = (dboid), \
211
+ (locktag).locktag_field2 = (reloid), \
212
+ (locktag).locktag_field3 = (blocknum), \
213
+ (locktag).locktag_field4 = 0, \
214
+ (locktag).locktag_type = LOCKTAG_PAGE, \
215
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
216
+
217
+ /* ID info for a tuple is PAGE info + OffsetNumber */
218
+ #define SET_LOCKTAG_TUPLE(locktag,dboid,reloid,blocknum,offnum) \
219
+ ((locktag).locktag_field1 = (dboid), \
220
+ (locktag).locktag_field2 = (reloid), \
221
+ (locktag).locktag_field3 = (blocknum), \
222
+ (locktag).locktag_field4 = (offnum), \
223
+ (locktag).locktag_type = LOCKTAG_TUPLE, \
224
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
225
+
226
+ /* ID info for a transaction is its TransactionId */
227
+ #define SET_LOCKTAG_TRANSACTION(locktag,xid) \
228
+ ((locktag).locktag_field1 = (xid), \
229
+ (locktag).locktag_field2 = 0, \
230
+ (locktag).locktag_field3 = 0, \
231
+ (locktag).locktag_field4 = 0, \
232
+ (locktag).locktag_type = LOCKTAG_TRANSACTION, \
233
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
234
+
235
+ /* ID info for a virtual transaction is its VirtualTransactionId */
236
+ #define SET_LOCKTAG_VIRTUALTRANSACTION(locktag,vxid) \
237
+ ((locktag).locktag_field1 = (vxid).backendId, \
238
+ (locktag).locktag_field2 = (vxid).localTransactionId, \
239
+ (locktag).locktag_field3 = 0, \
240
+ (locktag).locktag_field4 = 0, \
241
+ (locktag).locktag_type = LOCKTAG_VIRTUALTRANSACTION, \
242
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
243
+
244
+ /*
245
+ * ID info for a speculative insert is TRANSACTION info +
246
+ * its speculative insert counter.
247
+ */
248
+ #define SET_LOCKTAG_SPECULATIVE_INSERTION(locktag,xid,token) \
249
+ ((locktag).locktag_field1 = (xid), \
250
+ (locktag).locktag_field2 = (token), \
251
+ (locktag).locktag_field3 = 0, \
252
+ (locktag).locktag_field4 = 0, \
253
+ (locktag).locktag_type = LOCKTAG_SPECULATIVE_TOKEN, \
254
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
255
+
256
+ /*
257
+ * ID info for an object is DB OID + CLASS OID + OBJECT OID + SUBID
258
+ *
259
+ * Note: object ID has same representation as in pg_depend and
260
+ * pg_description, but notice that we are constraining SUBID to 16 bits.
261
+ * Also, we use DB OID = 0 for shared objects such as tablespaces.
262
+ */
263
+ #define SET_LOCKTAG_OBJECT(locktag,dboid,classoid,objoid,objsubid) \
264
+ ((locktag).locktag_field1 = (dboid), \
265
+ (locktag).locktag_field2 = (classoid), \
266
+ (locktag).locktag_field3 = (objoid), \
267
+ (locktag).locktag_field4 = (objsubid), \
268
+ (locktag).locktag_type = LOCKTAG_OBJECT, \
269
+ (locktag).locktag_lockmethodid = DEFAULT_LOCKMETHOD)
270
+
271
+ #define SET_LOCKTAG_ADVISORY(locktag,id1,id2,id3,id4) \
272
+ ((locktag).locktag_field1 = (id1), \
273
+ (locktag).locktag_field2 = (id2), \
274
+ (locktag).locktag_field3 = (id3), \
275
+ (locktag).locktag_field4 = (id4), \
276
+ (locktag).locktag_type = LOCKTAG_ADVISORY, \
277
+ (locktag).locktag_lockmethodid = USER_LOCKMETHOD)
278
+
279
+
280
+ /*
281
+ * Per-locked-object lock information:
282
+ *
283
+ * tag -- uniquely identifies the object being locked
284
+ * grantMask -- bitmask for all lock types currently granted on this object.
285
+ * waitMask -- bitmask for all lock types currently awaited on this object.
286
+ * procLocks -- list of PROCLOCK objects for this lock.
287
+ * waitProcs -- queue of processes waiting for this lock.
288
+ * requested -- count of each lock type currently requested on the lock
289
+ * (includes requests already granted!!).
290
+ * nRequested -- total requested locks of all types.
291
+ * granted -- count of each lock type currently granted on the lock.
292
+ * nGranted -- total granted locks of all types.
293
+ *
294
+ * Note: these counts count 1 for each backend. Internally to a backend,
295
+ * there may be multiple grabs on a particular lock, but this is not reflected
296
+ * into shared memory.
297
+ */
298
+ typedef struct LOCK
299
+ {
300
+ /* hash key */
301
+ LOCKTAG tag; /* unique identifier of lockable object */
302
+
303
+ /* data */
304
+ LOCKMASK grantMask; /* bitmask for lock types already granted */
305
+ LOCKMASK waitMask; /* bitmask for lock types awaited */
306
+ SHM_QUEUE procLocks; /* list of PROCLOCK objects assoc. with lock */
307
+ PROC_QUEUE waitProcs; /* list of PGPROC objects waiting on lock */
308
+ int requested[MAX_LOCKMODES]; /* counts of requested locks */
309
+ int nRequested; /* total of requested[] array */
310
+ int granted[MAX_LOCKMODES]; /* counts of granted locks */
311
+ int nGranted; /* total of granted[] array */
312
+ } LOCK;
313
+
314
+ #define LOCK_LOCKMETHOD(lock) ((LOCKMETHODID) (lock).tag.locktag_lockmethodid)
315
+ #define LOCK_LOCKTAG(lock) ((LockTagType) (lock).tag.locktag_type)
316
+
317
+
318
+ /*
319
+ * We may have several different backends holding or awaiting locks
320
+ * on the same lockable object. We need to store some per-holder/waiter
321
+ * information for each such holder (or would-be holder). This is kept in
322
+ * a PROCLOCK struct.
323
+ *
324
+ * PROCLOCKTAG is the key information needed to look up a PROCLOCK item in the
325
+ * proclock hashtable. A PROCLOCKTAG value uniquely identifies the combination
326
+ * of a lockable object and a holder/waiter for that object. (We can use
327
+ * pointers here because the PROCLOCKTAG need only be unique for the lifespan
328
+ * of the PROCLOCK, and it will never outlive the lock or the proc.)
329
+ *
330
+ * Internally to a backend, it is possible for the same lock to be held
331
+ * for different purposes: the backend tracks transaction locks separately
332
+ * from session locks. However, this is not reflected in the shared-memory
333
+ * state: we only track which backend(s) hold the lock. This is OK since a
334
+ * backend can never block itself.
335
+ *
336
+ * The holdMask field shows the already-granted locks represented by this
337
+ * proclock. Note that there will be a proclock object, possibly with
338
+ * zero holdMask, for any lock that the process is currently waiting on.
339
+ * Otherwise, proclock objects whose holdMasks are zero are recycled
340
+ * as soon as convenient.
341
+ *
342
+ * releaseMask is workspace for LockReleaseAll(): it shows the locks due
343
+ * to be released during the current call. This must only be examined or
344
+ * set by the backend owning the PROCLOCK.
345
+ *
346
+ * Each PROCLOCK object is linked into lists for both the associated LOCK
347
+ * object and the owning PGPROC object. Note that the PROCLOCK is entered
348
+ * into these lists as soon as it is created, even if no lock has yet been
349
+ * granted. A PGPROC that is waiting for a lock to be granted will also be
350
+ * linked into the lock's waitProcs queue.
351
+ */
352
+ typedef struct PROCLOCKTAG
353
+ {
354
+ /* NB: we assume this struct contains no padding! */
355
+ LOCK *myLock; /* link to per-lockable-object information */
356
+ PGPROC *myProc; /* link to PGPROC of owning backend */
357
+ } PROCLOCKTAG;
358
+
359
+ typedef struct PROCLOCK
360
+ {
361
+ /* tag */
362
+ PROCLOCKTAG tag; /* unique identifier of proclock object */
363
+
364
+ /* data */
365
+ PGPROC *groupLeader; /* proc's lock group leader, or proc itself */
366
+ LOCKMASK holdMask; /* bitmask for lock types currently held */
367
+ LOCKMASK releaseMask; /* bitmask for lock types to be released */
368
+ SHM_QUEUE lockLink; /* list link in LOCK's list of proclocks */
369
+ SHM_QUEUE procLink; /* list link in PGPROC's list of proclocks */
370
+ } PROCLOCK;
371
+
372
+ #define PROCLOCK_LOCKMETHOD(proclock) \
373
+ LOCK_LOCKMETHOD(*((proclock).tag.myLock))
374
+
375
+ /*
376
+ * Each backend also maintains a local hash table with information about each
377
+ * lock it is currently interested in. In particular the local table counts
378
+ * the number of times that lock has been acquired. This allows multiple
379
+ * requests for the same lock to be executed without additional accesses to
380
+ * shared memory. We also track the number of lock acquisitions per
381
+ * ResourceOwner, so that we can release just those locks belonging to a
382
+ * particular ResourceOwner.
383
+ *
384
+ * When holding a lock taken "normally", the lock and proclock fields always
385
+ * point to the associated objects in shared memory. However, if we acquired
386
+ * the lock via the fast-path mechanism, the lock and proclock fields are set
387
+ * to NULL, since there probably aren't any such objects in shared memory.
388
+ * (If the lock later gets promoted to normal representation, we may eventually
389
+ * update our locallock's lock/proclock fields after finding the shared
390
+ * objects.)
391
+ *
392
+ * Caution: a locallock object can be left over from a failed lock acquisition
393
+ * attempt. In this case its lock/proclock fields are untrustworthy, since
394
+ * the shared lock object is neither held nor awaited, and hence is available
395
+ * to be reclaimed. If nLocks > 0 then these pointers must either be valid or
396
+ * NULL, but when nLocks == 0 they should be considered garbage.
397
+ */
398
+ typedef struct LOCALLOCKTAG
399
+ {
400
+ LOCKTAG lock; /* identifies the lockable object */
401
+ LOCKMODE mode; /* lock mode for this table entry */
402
+ } LOCALLOCKTAG;
403
+
404
+ typedef struct LOCALLOCKOWNER
405
+ {
406
+ /*
407
+ * Note: if owner is NULL then the lock is held on behalf of the session;
408
+ * otherwise it is held on behalf of my current transaction.
409
+ *
410
+ * Must use a forward struct reference to avoid circularity.
411
+ */
412
+ struct ResourceOwnerData *owner;
413
+ int64 nLocks; /* # of times held by this owner */
414
+ } LOCALLOCKOWNER;
415
+
416
+ typedef struct LOCALLOCK
417
+ {
418
+ /* tag */
419
+ LOCALLOCKTAG tag; /* unique identifier of locallock entry */
420
+
421
+ /* data */
422
+ uint32 hashcode; /* copy of LOCKTAG's hash value */
423
+ LOCK *lock; /* associated LOCK object, if any */
424
+ PROCLOCK *proclock; /* associated PROCLOCK object, if any */
425
+ int64 nLocks; /* total number of times lock is held */
426
+ int numLockOwners; /* # of relevant ResourceOwners */
427
+ int maxLockOwners; /* allocated size of array */
428
+ LOCALLOCKOWNER *lockOwners; /* dynamically resizable array */
429
+ bool holdsStrongLockCount; /* bumped FastPathStrongRelationLocks */
430
+ bool lockCleared; /* we read all sinval msgs for lock */
431
+ } LOCALLOCK;
432
+
433
+ #define LOCALLOCK_LOCKMETHOD(llock) ((llock).tag.lock.locktag_lockmethodid)
434
+ #define LOCALLOCK_LOCKTAG(llock) ((LockTagType) (llock).tag.lock.locktag_type)
435
+
436
+
437
+ /*
438
+ * These structures hold information passed from lmgr internals to the lock
439
+ * listing user-level functions (in lockfuncs.c).
440
+ */
441
+
442
+ typedef struct LockInstanceData
443
+ {
444
+ LOCKTAG locktag; /* tag for locked object */
445
+ LOCKMASK holdMask; /* locks held by this PGPROC */
446
+ LOCKMODE waitLockMode; /* lock awaited by this PGPROC, if any */
447
+ BackendId backend; /* backend ID of this PGPROC */
448
+ LocalTransactionId lxid; /* local transaction ID of this PGPROC */
449
+ int pid; /* pid of this PGPROC */
450
+ int leaderPid; /* pid of group leader; = pid if no group */
451
+ bool fastpath; /* taken via fastpath? */
452
+ } LockInstanceData;
453
+
454
+ typedef struct LockData
455
+ {
456
+ int nelements; /* The length of the array */
457
+ LockInstanceData *locks; /* Array of per-PROCLOCK information */
458
+ } LockData;
459
+
460
+ typedef struct BlockedProcData
461
+ {
462
+ int pid; /* pid of a blocked PGPROC */
463
+ /* Per-PROCLOCK information about PROCLOCKs of the lock the pid awaits */
464
+ /* (these fields refer to indexes in BlockedProcsData.locks[]) */
465
+ int first_lock; /* index of first relevant LockInstanceData */
466
+ int num_locks; /* number of relevant LockInstanceDatas */
467
+ /* PIDs of PGPROCs that are ahead of "pid" in the lock's wait queue */
468
+ /* (these fields refer to indexes in BlockedProcsData.waiter_pids[]) */
469
+ int first_waiter; /* index of first preceding waiter */
470
+ int num_waiters; /* number of preceding waiters */
471
+ } BlockedProcData;
472
+
473
+ typedef struct BlockedProcsData
474
+ {
475
+ BlockedProcData *procs; /* Array of per-blocked-proc information */
476
+ LockInstanceData *locks; /* Array of per-PROCLOCK information */
477
+ int *waiter_pids; /* Array of PIDs of other blocked PGPROCs */
478
+ int nprocs; /* # of valid entries in procs[] array */
479
+ int maxprocs; /* Allocated length of procs[] array */
480
+ int nlocks; /* # of valid entries in locks[] array */
481
+ int maxlocks; /* Allocated length of locks[] array */
482
+ int npids; /* # of valid entries in waiter_pids[] array */
483
+ int maxpids; /* Allocated length of waiter_pids[] array */
484
+ } BlockedProcsData;
485
+
486
+
487
+ /* Result codes for LockAcquire() */
488
+ typedef enum
489
+ {
490
+ LOCKACQUIRE_NOT_AVAIL, /* lock not available, and dontWait=true */
491
+ LOCKACQUIRE_OK, /* lock successfully acquired */
492
+ LOCKACQUIRE_ALREADY_HELD, /* incremented count for lock already held */
493
+ LOCKACQUIRE_ALREADY_CLEAR /* incremented count for lock already clear */
494
+ } LockAcquireResult;
495
+
496
+ /* Deadlock states identified by DeadLockCheck() */
497
+ typedef enum
498
+ {
499
+ DS_NOT_YET_CHECKED, /* no deadlock check has run yet */
500
+ DS_NO_DEADLOCK, /* no deadlock detected */
501
+ DS_SOFT_DEADLOCK, /* deadlock avoided by queue rearrangement */
502
+ DS_HARD_DEADLOCK, /* deadlock, no way out but ERROR */
503
+ DS_BLOCKED_BY_AUTOVACUUM /* no deadlock; queue blocked by autovacuum
504
+ * worker */
505
+ } DeadLockState;
506
+
507
+ /*
508
+ * The lockmgr's shared hash tables are partitioned to reduce contention.
509
+ * To determine which partition a given locktag belongs to, compute the tag's
510
+ * hash code with LockTagHashCode(), then apply one of these macros.
511
+ * NB: NUM_LOCK_PARTITIONS must be a power of 2!
512
+ */
513
+ #define LockHashPartition(hashcode) \
514
+ ((hashcode) % NUM_LOCK_PARTITIONS)
515
+ #define LockHashPartitionLock(hashcode) \
516
+ (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + \
517
+ LockHashPartition(hashcode)].lock)
518
+ #define LockHashPartitionLockByIndex(i) \
519
+ (&MainLWLockArray[LOCK_MANAGER_LWLOCK_OFFSET + (i)].lock)
520
+
521
+ /*
522
+ * The deadlock detector needs to be able to access lockGroupLeader and
523
+ * related fields in the PGPROC, so we arrange for those fields to be protected
524
+ * by one of the lock hash partition locks. Since the deadlock detector
525
+ * acquires all such locks anyway, this makes it safe for it to access these
526
+ * fields without doing anything extra. To avoid contention as much as
527
+ * possible, we map different PGPROCs to different partition locks. The lock
528
+ * used for a given lock group is determined by the group leader's pgprocno.
529
+ */
530
+ #define LockHashPartitionLockByProc(leader_pgproc) \
531
+ LockHashPartitionLock((leader_pgproc)->pgprocno)
532
+
533
+ /*
534
+ * function prototypes
535
+ */
536
+ extern void InitLocks(void);
537
+ extern LockMethod GetLocksMethodTable(const LOCK *lock);
538
+ extern LockMethod GetLockTagsMethodTable(const LOCKTAG *locktag);
539
+ extern uint32 LockTagHashCode(const LOCKTAG *locktag);
540
+ extern bool DoLockModesConflict(LOCKMODE mode1, LOCKMODE mode2);
541
+ extern LockAcquireResult LockAcquire(const LOCKTAG *locktag,
542
+ LOCKMODE lockmode,
543
+ bool sessionLock,
544
+ bool dontWait);
545
+ extern LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag,
546
+ LOCKMODE lockmode,
547
+ bool sessionLock,
548
+ bool dontWait,
549
+ bool reportMemoryError,
550
+ LOCALLOCK **locallockp);
551
+ extern void AbortStrongLockAcquire(void);
552
+ extern void MarkLockClear(LOCALLOCK *locallock);
553
+ extern bool LockRelease(const LOCKTAG *locktag,
554
+ LOCKMODE lockmode, bool sessionLock);
555
+ extern void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks);
556
+ extern void LockReleaseSession(LOCKMETHODID lockmethodid);
557
+ extern void LockReleaseCurrentOwner(LOCALLOCK **locallocks, int nlocks);
558
+ extern void LockReassignCurrentOwner(LOCALLOCK **locallocks, int nlocks);
559
+ extern bool LockHeldByMe(const LOCKTAG *locktag, LOCKMODE lockmode);
560
+ #ifdef USE_ASSERT_CHECKING
561
+ extern HTAB *GetLockMethodLocalHash(void);
562
+ #endif
563
+ extern bool LockHasWaiters(const LOCKTAG *locktag,
564
+ LOCKMODE lockmode, bool sessionLock);
565
+ extern VirtualTransactionId *GetLockConflicts(const LOCKTAG *locktag,
566
+ LOCKMODE lockmode, int *countp);
567
+ extern void AtPrepare_Locks(void);
568
+ extern void PostPrepare_Locks(TransactionId xid);
569
+ extern bool LockCheckConflicts(LockMethod lockMethodTable,
570
+ LOCKMODE lockmode,
571
+ LOCK *lock, PROCLOCK *proclock);
572
+ extern void GrantLock(LOCK *lock, PROCLOCK *proclock, LOCKMODE lockmode);
573
+ extern void GrantAwaitedLock(void);
574
+ extern void RemoveFromWaitQueue(PGPROC *proc, uint32 hashcode);
575
+ extern Size LockShmemSize(void);
576
+ extern LockData *GetLockStatusData(void);
577
+ extern BlockedProcsData *GetBlockerStatusData(int blocked_pid);
578
+
579
+ extern xl_standby_lock *GetRunningTransactionLocks(int *nlocks);
580
+ extern const char *GetLockmodeName(LOCKMETHODID lockmethodid, LOCKMODE mode);
581
+
582
+ extern void lock_twophase_recover(TransactionId xid, uint16 info,
583
+ void *recdata, uint32 len);
584
+ extern void lock_twophase_postcommit(TransactionId xid, uint16 info,
585
+ void *recdata, uint32 len);
586
+ extern void lock_twophase_postabort(TransactionId xid, uint16 info,
587
+ void *recdata, uint32 len);
588
+ extern void lock_twophase_standby_recover(TransactionId xid, uint16 info,
589
+ void *recdata, uint32 len);
590
+
591
+ extern DeadLockState DeadLockCheck(PGPROC *proc);
592
+ extern PGPROC *GetBlockingAutoVacuumPgproc(void);
593
+ extern void DeadLockReport(void) pg_attribute_noreturn();
594
+ extern void RememberSimpleDeadLock(PGPROC *proc1,
595
+ LOCKMODE lockmode,
596
+ LOCK *lock,
597
+ PGPROC *proc2);
598
+ extern void InitDeadLockChecking(void);
599
+
600
+ extern int LockWaiterCount(const LOCKTAG *locktag);
601
+
602
+ #ifdef LOCK_DEBUG
603
+ extern void DumpLocks(PGPROC *proc);
604
+ extern void DumpAllLocks(void);
605
+ #endif
606
+
607
+ /* Lock a VXID (used to wait for a transaction to finish) */
608
+ extern void VirtualXactLockTableInsert(VirtualTransactionId vxid);
609
+ extern void VirtualXactLockTableCleanup(void);
610
+ extern bool VirtualXactLock(VirtualTransactionId vxid, bool wait);
611
+
612
+ #endif /* LOCK_H_ */