pg_query 4.2.1 → 6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -0
- data/README.md +7 -9
- data/Rakefile +5 -6
- data/ext/pg_query/ext_symbols_freebsd.sym +1 -0
- data/ext/pg_query/ext_symbols_freebsd_with_ruby_abi_version.sym +2 -0
- data/ext/pg_query/ext_symbols_openbsd.sym +1 -0
- data/ext/pg_query/ext_symbols_openbsd_with_ruby_abi_version.sym +2 -0
- data/ext/pg_query/ext_symbols_with_ruby_abi_version.sym +2 -0
- data/ext/pg_query/extconf.rb +33 -9
- data/ext/pg_query/include/pg_query.h +28 -3
- data/ext/pg_query/include/pg_query_enum_defs.c +599 -167
- data/ext/pg_query/include/pg_query_fingerprint_conds.c +640 -520
- data/ext/pg_query/include/pg_query_fingerprint_defs.c +6400 -4633
- data/ext/pg_query/include/pg_query_outfuncs_conds.c +433 -343
- data/ext/pg_query/include/pg_query_outfuncs_defs.c +1472 -1152
- data/ext/pg_query/include/pg_query_readfuncs_conds.c +154 -124
- data/ext/pg_query/include/pg_query_readfuncs_defs.c +1886 -1506
- data/ext/pg_query/include/postgres/access/amapi.h +303 -0
- data/ext/pg_query/include/postgres/access/attmap.h +54 -0
- data/ext/pg_query/include/postgres/access/attnum.h +64 -0
- data/ext/pg_query/include/postgres/access/brin_internal.h +116 -0
- data/ext/pg_query/include/postgres/access/brin_tuple.h +112 -0
- data/ext/pg_query/include/postgres/access/clog.h +62 -0
- data/ext/pg_query/include/postgres/access/commit_ts.h +73 -0
- data/ext/pg_query/include/postgres/access/detoast.h +82 -0
- data/ext/pg_query/include/postgres/access/genam.h +246 -0
- data/ext/pg_query/include/postgres/access/gin.h +91 -0
- data/ext/pg_query/include/postgres/access/htup.h +89 -0
- data/ext/pg_query/include/postgres/access/htup_details.h +811 -0
- data/ext/pg_query/include/postgres/access/itup.h +170 -0
- data/ext/pg_query/include/postgres/access/parallel.h +81 -0
- data/ext/pg_query/include/postgres/access/printtup.h +35 -0
- data/ext/pg_query/include/postgres/access/relation.h +28 -0
- data/ext/pg_query/include/postgres/access/relscan.h +191 -0
- data/ext/pg_query/include/postgres/access/rmgrlist.h +49 -0
- data/ext/pg_query/include/postgres/access/sdir.h +67 -0
- data/ext/pg_query/include/postgres/access/skey.h +151 -0
- data/ext/pg_query/include/postgres/access/slru.h +218 -0
- data/ext/pg_query/include/postgres/access/stratnum.h +85 -0
- data/ext/pg_query/include/postgres/access/sysattr.h +29 -0
- data/ext/pg_query/include/postgres/access/table.h +28 -0
- data/ext/pg_query/include/postgres/access/tableam.h +2110 -0
- data/ext/pg_query/include/postgres/access/tidstore.h +50 -0
- data/ext/pg_query/include/postgres/access/toast_compression.h +73 -0
- data/ext/pg_query/include/postgres/access/transam.h +418 -0
- data/ext/pg_query/include/postgres/access/tsmapi.h +82 -0
- data/ext/pg_query/include/postgres/access/tupconvert.h +54 -0
- data/ext/pg_query/include/postgres/access/tupdesc.h +154 -0
- data/ext/pg_query/include/postgres/access/tupmacs.h +207 -0
- data/ext/pg_query/include/postgres/access/twophase.h +65 -0
- data/ext/pg_query/include/postgres/access/xact.h +530 -0
- data/ext/pg_query/include/postgres/access/xlog.h +310 -0
- data/ext/pg_query/include/postgres/access/xlog_internal.h +405 -0
- data/ext/pg_query/include/postgres/access/xlogbackup.h +43 -0
- data/ext/pg_query/include/postgres/access/xlogdefs.h +82 -0
- data/ext/pg_query/include/postgres/access/xlogprefetcher.h +55 -0
- data/ext/pg_query/include/postgres/access/xlogreader.h +444 -0
- data/ext/pg_query/include/postgres/access/xlogrecord.h +248 -0
- data/ext/pg_query/include/postgres/access/xlogrecovery.h +158 -0
- data/ext/pg_query/include/postgres/archive/archive_module.h +67 -0
- data/ext/pg_query/include/postgres/c.h +1374 -0
- data/ext/pg_query/include/postgres/catalog/catalog.h +47 -0
- data/ext/pg_query/include/postgres/catalog/catversion.h +62 -0
- data/ext/pg_query/include/postgres/catalog/dependency.h +228 -0
- data/ext/pg_query/include/postgres/catalog/genbki.h +149 -0
- data/ext/pg_query/include/postgres/catalog/index.h +218 -0
- data/ext/pg_query/include/postgres/catalog/indexing.h +54 -0
- data/ext/pg_query/include/postgres/catalog/namespace.h +189 -0
- data/ext/pg_query/include/postgres/catalog/objectaccess.h +267 -0
- data/ext/pg_query/include/postgres/catalog/objectaddress.h +93 -0
- data/ext/pg_query/include/postgres/catalog/pg_aggregate.h +182 -0
- data/ext/pg_query/include/postgres/catalog/pg_aggregate_d.h +78 -0
- data/ext/pg_query/include/postgres/catalog/pg_am.h +66 -0
- data/ext/pg_query/include/postgres/catalog/pg_am_d.h +47 -0
- data/ext/pg_query/include/postgres/catalog/pg_attribute.h +240 -0
- data/ext/pg_query/include/postgres/catalog/pg_attribute_d.h +62 -0
- data/ext/pg_query/include/postgres/catalog/pg_authid.h +66 -0
- data/ext/pg_query/include/postgres/catalog/pg_authid_d.h +60 -0
- data/ext/pg_query/include/postgres/catalog/pg_class.h +235 -0
- data/ext/pg_query/include/postgres/catalog/pg_class_d.h +134 -0
- data/ext/pg_query/include/postgres/catalog/pg_collation.h +106 -0
- data/ext/pg_query/include/postgres/catalog/pg_collation_d.h +66 -0
- data/ext/pg_query/include/postgres/catalog/pg_constraint.h +278 -0
- data/ext/pg_query/include/postgres/catalog/pg_constraint_d.h +74 -0
- data/ext/pg_query/include/postgres/catalog/pg_control.h +260 -0
- data/ext/pg_query/include/postgres/catalog/pg_conversion.h +79 -0
- data/ext/pg_query/include/postgres/catalog/pg_conversion_d.h +38 -0
- data/ext/pg_query/include/postgres/catalog/pg_database.h +129 -0
- data/ext/pg_query/include/postgres/catalog/pg_database_d.h +53 -0
- data/ext/pg_query/include/postgres/catalog/pg_depend.h +77 -0
- data/ext/pg_query/include/postgres/catalog/pg_depend_d.h +36 -0
- data/ext/pg_query/include/postgres/catalog/pg_event_trigger.h +60 -0
- data/ext/pg_query/include/postgres/catalog/pg_event_trigger_d.h +36 -0
- data/ext/pg_query/include/postgres/catalog/pg_index.h +92 -0
- data/ext/pg_query/include/postgres/catalog/pg_index_d.h +59 -0
- data/ext/pg_query/include/postgres/catalog/pg_language.h +75 -0
- data/ext/pg_query/include/postgres/catalog/pg_language_d.h +41 -0
- data/ext/pg_query/include/postgres/catalog/pg_namespace.h +67 -0
- data/ext/pg_query/include/postgres/catalog/pg_namespace_d.h +36 -0
- data/ext/pg_query/include/postgres/catalog/pg_opclass.h +91 -0
- data/ext/pg_query/include/postgres/catalog/pg_opclass_d.h +51 -0
- data/ext/pg_query/include/postgres/catalog/pg_operator.h +124 -0
- data/ext/pg_query/include/postgres/catalog/pg_operator_d.h +142 -0
- data/ext/pg_query/include/postgres/catalog/pg_opfamily.h +67 -0
- data/ext/pg_query/include/postgres/catalog/pg_opfamily_d.h +51 -0
- data/ext/pg_query/include/postgres/catalog/pg_partitioned_table.h +76 -0
- data/ext/pg_query/include/postgres/catalog/pg_partitioned_table_d.h +36 -0
- data/ext/pg_query/include/postgres/catalog/pg_proc.h +223 -0
- data/ext/pg_query/include/postgres/catalog/pg_proc_d.h +101 -0
- data/ext/pg_query/include/postgres/catalog/pg_publication.h +161 -0
- data/ext/pg_query/include/postgres/catalog/pg_publication_d.h +38 -0
- data/ext/pg_query/include/postgres/catalog/pg_replication_origin.h +65 -0
- data/ext/pg_query/include/postgres/catalog/pg_replication_origin_d.h +33 -0
- data/ext/pg_query/include/postgres/catalog/pg_statistic.h +288 -0
- data/ext/pg_query/include/postgres/catalog/pg_statistic_d.h +199 -0
- data/ext/pg_query/include/postgres/catalog/pg_statistic_ext.h +91 -0
- data/ext/pg_query/include/postgres/catalog/pg_statistic_ext_d.h +45 -0
- data/ext/pg_query/include/postgres/catalog/pg_transform.h +51 -0
- data/ext/pg_query/include/postgres/catalog/pg_transform_d.h +34 -0
- data/ext/pg_query/include/postgres/catalog/pg_trigger.h +153 -0
- data/ext/pg_query/include/postgres/catalog/pg_trigger_d.h +109 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_config.h +56 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_config_d.h +34 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_dict.h +62 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_dict_d.h +35 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_parser.h +63 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_parser_d.h +37 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_template.h +54 -0
- data/ext/pg_query/include/postgres/catalog/pg_ts_template_d.h +34 -0
- data/ext/pg_query/include/postgres/catalog/pg_type.h +407 -0
- data/ext/pg_query/include/postgres/catalog/pg_type_d.h +324 -0
- data/ext/pg_query/include/postgres/catalog/storage.h +50 -0
- data/ext/pg_query/include/postgres/catalog/syscache_ids.h +104 -0
- data/ext/pg_query/include/postgres/commands/async.h +49 -0
- data/ext/pg_query/include/postgres/commands/dbcommands.h +37 -0
- data/ext/pg_query/include/postgres/commands/defrem.h +161 -0
- data/ext/pg_query/include/postgres/commands/event_trigger.h +97 -0
- data/ext/pg_query/include/postgres/commands/explain.h +145 -0
- data/ext/pg_query/include/postgres/commands/prepare.h +61 -0
- data/ext/pg_query/include/postgres/commands/tablespace.h +69 -0
- data/ext/pg_query/include/postgres/commands/trigger.h +288 -0
- data/ext/pg_query/include/postgres/commands/user.h +43 -0
- data/ext/pg_query/include/postgres/commands/vacuum.h +388 -0
- data/ext/pg_query/include/postgres/common/cryptohash.h +39 -0
- data/ext/pg_query/include/postgres/common/file_perm.h +56 -0
- data/ext/pg_query/include/postgres/common/file_utils.h +65 -0
- data/ext/pg_query/include/postgres/common/hashfn.h +119 -0
- data/ext/pg_query/include/postgres/common/hashfn_unstable.h +407 -0
- data/ext/pg_query/include/postgres/common/int.h +512 -0
- data/ext/pg_query/include/postgres/common/keywords.h +29 -0
- data/ext/pg_query/include/postgres/common/kwlookup.h +44 -0
- data/ext/pg_query/include/postgres/common/pg_prng.h +62 -0
- data/ext/pg_query/include/postgres/common/relpath.h +97 -0
- data/ext/pg_query/include/postgres/common/scram-common.h +70 -0
- data/ext/pg_query/include/postgres/common/sha2.h +32 -0
- data/ext/pg_query/include/postgres/common/string.h +44 -0
- data/ext/pg_query/include/postgres/common/unicode_east_asian_fw_table.h +124 -0
- data/ext/pg_query/include/postgres/common/unicode_nonspacing_table.h +326 -0
- data/ext/pg_query/include/postgres/copyfuncs.funcs.c +5261 -0
- data/ext/pg_query/include/postgres/copyfuncs.switch.c +989 -0
- data/ext/pg_query/include/postgres/datatype/timestamp.h +269 -0
- data/ext/pg_query/include/postgres/equalfuncs.funcs.c +3310 -0
- data/ext/pg_query/include/postgres/equalfuncs.switch.c +836 -0
- data/ext/pg_query/include/postgres/executor/execdesc.h +70 -0
- data/ext/pg_query/include/postgres/executor/executor.h +681 -0
- data/ext/pg_query/include/postgres/executor/functions.h +56 -0
- data/ext/pg_query/include/postgres/executor/instrument.h +120 -0
- data/ext/pg_query/include/postgres/executor/spi.h +207 -0
- data/ext/pg_query/include/postgres/executor/tablefunc.h +67 -0
- data/ext/pg_query/include/postgres/executor/tuptable.h +523 -0
- data/ext/pg_query/include/postgres/fmgr.h +800 -0
- data/ext/pg_query/include/postgres/foreign/fdwapi.h +294 -0
- data/ext/pg_query/include/postgres/funcapi.h +360 -0
- data/ext/pg_query/include/postgres/gram.h +1168 -0
- data/ext/pg_query/include/postgres/gramparse.h +75 -0
- data/ext/pg_query/include/postgres/jit/jit.h +106 -0
- data/ext/pg_query/include/postgres/kwlist_d.h +1164 -0
- data/ext/pg_query/include/postgres/lib/dshash.h +130 -0
- data/ext/pg_query/include/postgres/lib/ilist.h +1159 -0
- data/ext/pg_query/include/postgres/lib/pairingheap.h +102 -0
- data/ext/pg_query/include/postgres/lib/simplehash.h +1206 -0
- data/ext/pg_query/include/postgres/lib/sort_template.h +445 -0
- data/ext/pg_query/include/postgres/lib/stringinfo.h +243 -0
- data/ext/pg_query/include/postgres/libpq/auth.h +37 -0
- data/ext/pg_query/include/postgres/libpq/crypt.h +47 -0
- data/ext/pg_query/include/postgres/libpq/hba.h +186 -0
- data/ext/pg_query/include/postgres/libpq/libpq-be.h +361 -0
- data/ext/pg_query/include/postgres/libpq/libpq.h +143 -0
- data/ext/pg_query/include/postgres/libpq/pqcomm.h +169 -0
- data/ext/pg_query/include/postgres/libpq/pqformat.h +209 -0
- data/ext/pg_query/include/postgres/libpq/pqsignal.h +54 -0
- data/ext/pg_query/include/postgres/libpq/protocol.h +89 -0
- data/ext/pg_query/include/postgres/libpq/sasl.h +136 -0
- data/ext/pg_query/include/postgres/libpq/scram.h +37 -0
- data/ext/pg_query/include/postgres/mb/pg_wchar.h +793 -0
- data/ext/pg_query/include/postgres/mb/stringinfo_mb.h +24 -0
- data/ext/pg_query/include/postgres/miscadmin.h +527 -0
- data/ext/pg_query/include/postgres/nodes/bitmapset.h +140 -0
- data/ext/pg_query/include/postgres/nodes/execnodes.h +2855 -0
- data/ext/pg_query/include/postgres/nodes/extensible.h +164 -0
- data/ext/pg_query/include/postgres/nodes/lockoptions.h +61 -0
- data/ext/pg_query/include/postgres/nodes/makefuncs.h +127 -0
- data/ext/pg_query/include/postgres/nodes/memnodes.h +152 -0
- data/ext/pg_query/include/postgres/nodes/miscnodes.h +56 -0
- data/ext/pg_query/include/postgres/nodes/nodeFuncs.h +222 -0
- data/ext/pg_query/include/postgres/nodes/nodes.h +435 -0
- data/ext/pg_query/include/postgres/nodes/nodetags.h +491 -0
- data/ext/pg_query/include/postgres/nodes/params.h +170 -0
- data/ext/pg_query/include/postgres/nodes/parsenodes.h +4233 -0
- data/ext/pg_query/include/postgres/nodes/pathnodes.h +3438 -0
- data/ext/pg_query/include/postgres/nodes/pg_list.h +686 -0
- data/ext/pg_query/include/postgres/nodes/plannodes.h +1593 -0
- data/ext/pg_query/include/postgres/nodes/primnodes.h +2339 -0
- data/ext/pg_query/include/postgres/nodes/print.h +34 -0
- data/ext/pg_query/include/postgres/nodes/queryjumble.h +86 -0
- data/ext/pg_query/include/postgres/nodes/replnodes.h +132 -0
- data/ext/pg_query/include/postgres/nodes/supportnodes.h +346 -0
- data/ext/pg_query/include/postgres/nodes/tidbitmap.h +75 -0
- data/ext/pg_query/include/postgres/nodes/value.h +90 -0
- data/ext/pg_query/include/postgres/optimizer/cost.h +216 -0
- data/ext/pg_query/include/postgres/optimizer/geqo.h +90 -0
- data/ext/pg_query/include/postgres/optimizer/geqo_gene.h +45 -0
- data/ext/pg_query/include/postgres/optimizer/optimizer.h +205 -0
- data/ext/pg_query/include/postgres/optimizer/paths.h +271 -0
- data/ext/pg_query/include/postgres/optimizer/planmain.h +123 -0
- data/ext/pg_query/include/postgres/parser/analyze.h +66 -0
- data/ext/pg_query/include/postgres/parser/kwlist.h +518 -0
- data/ext/pg_query/include/postgres/parser/parse_agg.h +65 -0
- data/ext/pg_query/include/postgres/parser/parse_coerce.h +105 -0
- data/ext/pg_query/include/postgres/parser/parse_expr.h +25 -0
- data/ext/pg_query/include/postgres/parser/parse_func.h +74 -0
- data/ext/pg_query/include/postgres/parser/parse_node.h +358 -0
- data/ext/pg_query/include/postgres/parser/parse_oper.h +68 -0
- data/ext/pg_query/include/postgres/parser/parse_relation.h +129 -0
- data/ext/pg_query/include/postgres/parser/parse_type.h +61 -0
- data/ext/pg_query/include/postgres/parser/parser.h +68 -0
- data/ext/pg_query/include/postgres/parser/parsetree.h +61 -0
- data/ext/pg_query/include/postgres/parser/scanner.h +152 -0
- data/ext/pg_query/include/postgres/parser/scansup.h +27 -0
- data/ext/pg_query/include/postgres/partitioning/partdefs.h +26 -0
- data/ext/pg_query/include/postgres/pg_config.h +985 -0
- data/ext/pg_query/include/postgres/pg_config_manual.h +385 -0
- data/ext/pg_query/include/postgres/pg_config_os.h +8 -0
- data/ext/pg_query/include/postgres/pg_getopt.h +56 -0
- data/ext/pg_query/include/postgres/pg_trace.h +17 -0
- data/ext/pg_query/include/postgres/pgstat.h +780 -0
- data/ext/pg_query/include/postgres/pgtime.h +94 -0
- data/ext/pg_query/include/postgres/pl_gram.h +385 -0
- data/ext/pg_query/include/postgres/pl_reserved_kwlist.h +52 -0
- data/ext/pg_query/include/postgres/pl_reserved_kwlist_d.h +114 -0
- data/ext/pg_query/include/postgres/pl_unreserved_kwlist.h +112 -0
- data/ext/pg_query/include/postgres/pl_unreserved_kwlist_d.h +246 -0
- data/ext/pg_query/include/postgres/plerrcodes.h +998 -0
- data/ext/pg_query/include/postgres/plpgsql.h +1342 -0
- data/ext/pg_query/include/postgres/port/atomics/arch-arm.h +32 -0
- data/ext/pg_query/include/postgres/port/atomics/arch-hppa.h +17 -0
- data/ext/pg_query/include/postgres/port/atomics/arch-ppc.h +256 -0
- data/ext/pg_query/include/postgres/port/atomics/arch-x86.h +254 -0
- data/ext/pg_query/include/postgres/port/atomics/fallback.h +170 -0
- data/ext/pg_query/include/postgres/port/atomics/generic-gcc.h +323 -0
- data/ext/pg_query/include/postgres/port/atomics/generic-msvc.h +119 -0
- data/ext/pg_query/include/postgres/port/atomics/generic-sunpro.h +121 -0
- data/ext/pg_query/include/postgres/port/atomics/generic.h +437 -0
- data/ext/pg_query/include/postgres/port/atomics.h +606 -0
- data/ext/pg_query/include/postgres/port/pg_bitutils.h +421 -0
- data/ext/pg_query/include/postgres/port/pg_bswap.h +161 -0
- data/ext/pg_query/include/postgres/port/pg_crc32c.h +110 -0
- data/ext/pg_query/include/postgres/port/pg_iovec.h +117 -0
- data/ext/pg_query/include/postgres/port/simd.h +422 -0
- data/ext/pg_query/include/postgres/port/win32/arpa/inet.h +3 -0
- data/ext/pg_query/include/postgres/port/win32/dlfcn.h +1 -0
- data/ext/pg_query/include/postgres/port/win32/grp.h +1 -0
- data/ext/pg_query/include/postgres/port/win32/netdb.h +7 -0
- data/ext/pg_query/include/postgres/port/win32/netinet/in.h +3 -0
- data/ext/pg_query/include/postgres/port/win32/netinet/tcp.h +7 -0
- data/ext/pg_query/include/postgres/port/win32/pwd.h +3 -0
- data/ext/pg_query/include/postgres/port/win32/sys/resource.h +20 -0
- data/ext/pg_query/include/postgres/port/win32/sys/select.h +3 -0
- data/ext/pg_query/include/postgres/port/win32/sys/socket.h +34 -0
- data/ext/pg_query/include/postgres/port/win32/sys/un.h +17 -0
- data/ext/pg_query/include/postgres/port/win32/sys/wait.h +3 -0
- data/ext/pg_query/include/postgres/port/win32.h +59 -0
- data/ext/pg_query/include/postgres/port/win32_msvc/dirent.h +34 -0
- data/ext/pg_query/include/postgres/port/win32_msvc/sys/file.h +1 -0
- data/ext/pg_query/include/postgres/port/win32_msvc/sys/param.h +1 -0
- data/ext/pg_query/include/postgres/port/win32_msvc/sys/time.h +1 -0
- data/ext/pg_query/include/postgres/port/win32_msvc/unistd.h +9 -0
- data/ext/pg_query/include/postgres/port/win32_msvc/utime.h +3 -0
- data/ext/pg_query/include/postgres/port/win32_port.h +582 -0
- data/ext/pg_query/include/postgres/port.h +555 -0
- data/ext/pg_query/include/postgres/portability/instr_time.h +197 -0
- data/ext/pg_query/include/postgres/postgres.h +579 -0
- data/ext/pg_query/include/postgres/postgres_ext.h +73 -0
- data/ext/pg_query/include/postgres/postmaster/autovacuum.h +69 -0
- data/ext/pg_query/include/postgres/postmaster/bgworker.h +164 -0
- data/ext/pg_query/include/postgres/postmaster/bgworker_internals.h +60 -0
- data/ext/pg_query/include/postgres/postmaster/bgwriter.h +45 -0
- data/ext/pg_query/include/postgres/postmaster/interrupt.h +32 -0
- data/ext/pg_query/include/postgres/postmaster/pgarch.h +36 -0
- data/ext/pg_query/include/postgres/postmaster/postmaster.h +101 -0
- data/ext/pg_query/include/postgres/postmaster/startup.h +41 -0
- data/ext/pg_query/include/postgres/postmaster/syslogger.h +101 -0
- data/ext/pg_query/include/postgres/postmaster/walsummarizer.h +35 -0
- data/ext/pg_query/include/postgres/postmaster/walwriter.h +23 -0
- data/ext/pg_query/include/postgres/regex/regex.h +272 -0
- data/ext/pg_query/include/postgres/replication/logicallauncher.h +34 -0
- data/ext/pg_query/include/postgres/replication/logicalproto.h +274 -0
- data/ext/pg_query/include/postgres/replication/logicalworker.h +33 -0
- data/ext/pg_query/include/postgres/replication/origin.h +73 -0
- data/ext/pg_query/include/postgres/replication/reorderbuffer.h +734 -0
- data/ext/pg_query/include/postgres/replication/slot.h +289 -0
- data/ext/pg_query/include/postgres/replication/slotsync.h +38 -0
- data/ext/pg_query/include/postgres/replication/syncrep.h +109 -0
- data/ext/pg_query/include/postgres/replication/walreceiver.h +504 -0
- data/ext/pg_query/include/postgres/replication/walsender.h +76 -0
- data/ext/pg_query/include/postgres/rewrite/prs2lock.h +46 -0
- data/ext/pg_query/include/postgres/rewrite/rewriteHandler.h +41 -0
- data/ext/pg_query/include/postgres/rewrite/rewriteManip.h +96 -0
- data/ext/pg_query/include/postgres/rewrite/rewriteSupport.h +26 -0
- data/ext/pg_query/include/postgres/storage/block.h +108 -0
- data/ext/pg_query/include/postgres/storage/buf.h +46 -0
- data/ext/pg_query/include/postgres/storage/bufmgr.h +411 -0
- data/ext/pg_query/include/postgres/storage/bufpage.h +510 -0
- data/ext/pg_query/include/postgres/storage/condition_variable.h +73 -0
- data/ext/pg_query/include/postgres/storage/dsm.h +61 -0
- data/ext/pg_query/include/postgres/storage/dsm_impl.h +79 -0
- data/ext/pg_query/include/postgres/storage/fd.h +219 -0
- data/ext/pg_query/include/postgres/storage/fileset.h +40 -0
- data/ext/pg_query/include/postgres/storage/ipc.h +87 -0
- data/ext/pg_query/include/postgres/storage/item.h +19 -0
- data/ext/pg_query/include/postgres/storage/itemid.h +184 -0
- data/ext/pg_query/include/postgres/storage/itemptr.h +245 -0
- data/ext/pg_query/include/postgres/storage/large_object.h +100 -0
- data/ext/pg_query/include/postgres/storage/latch.h +196 -0
- data/ext/pg_query/include/postgres/storage/lmgr.h +126 -0
- data/ext/pg_query/include/postgres/storage/lock.h +624 -0
- data/ext/pg_query/include/postgres/storage/lockdefs.h +61 -0
- data/ext/pg_query/include/postgres/storage/lwlock.h +228 -0
- data/ext/pg_query/include/postgres/storage/lwlocknames.h +47 -0
- data/ext/pg_query/include/postgres/storage/off.h +57 -0
- data/ext/pg_query/include/postgres/storage/pg_sema.h +61 -0
- data/ext/pg_query/include/postgres/storage/pg_shmem.h +93 -0
- data/ext/pg_query/include/postgres/storage/pmsignal.h +105 -0
- data/ext/pg_query/include/postgres/storage/predicate.h +83 -0
- data/ext/pg_query/include/postgres/storage/proc.h +488 -0
- data/ext/pg_query/include/postgres/storage/procarray.h +103 -0
- data/ext/pg_query/include/postgres/storage/proclist_types.h +53 -0
- data/ext/pg_query/include/postgres/storage/procnumber.h +43 -0
- data/ext/pg_query/include/postgres/storage/procsignal.h +75 -0
- data/ext/pg_query/include/postgres/storage/read_stream.h +65 -0
- data/ext/pg_query/include/postgres/storage/relfilelocator.h +100 -0
- data/ext/pg_query/include/postgres/storage/s_lock.h +847 -0
- data/ext/pg_query/include/postgres/storage/sharedfileset.h +37 -0
- data/ext/pg_query/include/postgres/storage/shm_mq.h +86 -0
- data/ext/pg_query/include/postgres/storage/shm_toc.h +58 -0
- data/ext/pg_query/include/postgres/storage/shmem.h +59 -0
- data/ext/pg_query/include/postgres/storage/sinval.h +153 -0
- data/ext/pg_query/include/postgres/storage/smgr.h +130 -0
- data/ext/pg_query/include/postgres/storage/spin.h +77 -0
- data/ext/pg_query/include/postgres/storage/standby.h +109 -0
- data/ext/pg_query/include/postgres/storage/standbydefs.h +74 -0
- data/ext/pg_query/include/postgres/storage/sync.h +66 -0
- data/ext/pg_query/include/postgres/tcop/cmdtag.h +62 -0
- data/ext/pg_query/include/postgres/tcop/cmdtaglist.h +219 -0
- data/ext/pg_query/include/postgres/tcop/deparse_utility.h +108 -0
- data/ext/pg_query/include/postgres/tcop/dest.h +148 -0
- data/ext/pg_query/include/postgres/tcop/fastpath.h +20 -0
- data/ext/pg_query/include/postgres/tcop/pquery.h +51 -0
- data/ext/pg_query/include/postgres/tcop/tcopprot.h +98 -0
- data/ext/pg_query/include/postgres/tcop/utility.h +112 -0
- data/ext/pg_query/include/postgres/tsearch/ts_cache.h +96 -0
- data/ext/pg_query/include/postgres/utils/acl.h +290 -0
- data/ext/pg_query/include/postgres/utils/aclchk_internal.h +45 -0
- data/ext/pg_query/include/postgres/utils/array.h +481 -0
- data/ext/pg_query/include/postgres/utils/ascii.h +84 -0
- data/ext/pg_query/include/postgres/utils/backend_progress.h +46 -0
- data/ext/pg_query/include/postgres/utils/backend_status.h +340 -0
- data/ext/pg_query/include/postgres/utils/builtins.h +139 -0
- data/ext/pg_query/include/postgres/utils/bytea.h +28 -0
- data/ext/pg_query/include/postgres/utils/catcache.h +231 -0
- data/ext/pg_query/include/postgres/utils/date.h +118 -0
- data/ext/pg_query/include/postgres/utils/datetime.h +367 -0
- data/ext/pg_query/include/postgres/utils/datum.h +76 -0
- data/ext/pg_query/include/postgres/utils/dsa.h +166 -0
- data/ext/pg_query/include/postgres/utils/elog.h +540 -0
- data/ext/pg_query/include/postgres/utils/errcodes.h +352 -0
- data/ext/pg_query/include/postgres/utils/expandeddatum.h +170 -0
- data/ext/pg_query/include/postgres/utils/expandedrecord.h +241 -0
- data/ext/pg_query/include/postgres/utils/float.h +357 -0
- data/ext/pg_query/include/postgres/utils/fmgroids.h +3347 -0
- data/ext/pg_query/include/postgres/utils/fmgrprotos.h +2904 -0
- data/ext/pg_query/include/postgres/utils/fmgrtab.h +49 -0
- data/ext/pg_query/include/postgres/utils/guc.h +456 -0
- data/ext/pg_query/include/postgres/utils/guc_hooks.h +184 -0
- data/ext/pg_query/include/postgres/utils/guc_tables.h +323 -0
- data/ext/pg_query/include/postgres/utils/hsearch.h +153 -0
- data/ext/pg_query/include/postgres/utils/injection_point.h +44 -0
- data/ext/pg_query/include/postgres/utils/inval.h +68 -0
- data/ext/pg_query/include/postgres/utils/logtape.h +77 -0
- data/ext/pg_query/include/postgres/utils/lsyscache.h +215 -0
- data/ext/pg_query/include/postgres/utils/memdebug.h +82 -0
- data/ext/pg_query/include/postgres/utils/memutils.h +193 -0
- data/ext/pg_query/include/postgres/utils/memutils_internal.h +176 -0
- data/ext/pg_query/include/postgres/utils/memutils_memorychunk.h +253 -0
- data/ext/pg_query/include/postgres/utils/numeric.h +110 -0
- data/ext/pg_query/include/postgres/utils/palloc.h +151 -0
- data/ext/pg_query/include/postgres/utils/partcache.h +103 -0
- data/ext/pg_query/include/postgres/utils/pg_locale.h +136 -0
- data/ext/pg_query/include/postgres/utils/pgstat_internal.h +827 -0
- data/ext/pg_query/include/postgres/utils/plancache.h +238 -0
- data/ext/pg_query/include/postgres/utils/portal.h +252 -0
- data/ext/pg_query/include/postgres/utils/probes.h +114 -0
- data/ext/pg_query/include/postgres/utils/ps_status.h +47 -0
- data/ext/pg_query/include/postgres/utils/queryenvironment.h +74 -0
- data/ext/pg_query/include/postgres/utils/regproc.h +39 -0
- data/ext/pg_query/include/postgres/utils/rel.h +711 -0
- data/ext/pg_query/include/postgres/utils/relcache.h +155 -0
- data/ext/pg_query/include/postgres/utils/reltrigger.h +81 -0
- data/ext/pg_query/include/postgres/utils/resowner.h +167 -0
- data/ext/pg_query/include/postgres/utils/ruleutils.h +52 -0
- data/ext/pg_query/include/postgres/utils/sharedtuplestore.h +61 -0
- data/ext/pg_query/include/postgres/utils/snapmgr.h +130 -0
- data/ext/pg_query/include/postgres/utils/snapshot.h +219 -0
- data/ext/pg_query/include/postgres/utils/sortsupport.h +391 -0
- data/ext/pg_query/include/postgres/utils/syscache.h +136 -0
- data/ext/pg_query/include/postgres/utils/timeout.h +96 -0
- data/ext/pg_query/include/postgres/utils/timestamp.h +147 -0
- data/ext/pg_query/include/postgres/utils/tuplesort.h +472 -0
- data/ext/pg_query/include/postgres/utils/tuplestore.h +88 -0
- data/ext/pg_query/include/postgres/utils/typcache.h +210 -0
- data/ext/pg_query/include/postgres/utils/varlena.h +53 -0
- data/ext/pg_query/include/postgres/utils/wait_event.h +108 -0
- data/ext/pg_query/include/postgres/utils/wait_event_types.h +218 -0
- data/ext/pg_query/include/postgres/utils/xml.h +94 -0
- data/ext/pg_query/include/postgres/varatt.h +358 -0
- data/ext/pg_query/include/protobuf/pg_query.pb-c.h +7723 -6368
- data/ext/pg_query/include/protobuf/pg_query.pb.h +120022 -87031
- data/ext/pg_query/pg_query.c +10 -1
- data/ext/pg_query/pg_query.pb-c.c +22595 -17738
- data/ext/pg_query/pg_query_deparse.c +1 -10635
- data/ext/pg_query/pg_query_fingerprint.c +12 -8
- data/ext/pg_query/pg_query_fingerprint.h +1 -1
- data/ext/pg_query/pg_query_internal.h +1 -1
- data/ext/pg_query/pg_query_json_plpgsql.c +1 -0
- data/ext/pg_query/pg_query_normalize.c +43 -2
- data/ext/pg_query/pg_query_outfuncs_json.c +9 -1
- data/ext/pg_query/pg_query_outfuncs_protobuf.c +3 -2
- data/ext/pg_query/pg_query_parse.c +47 -5
- data/ext/pg_query/pg_query_parse_plpgsql.c +19 -18
- data/ext/pg_query/pg_query_readfuncs_protobuf.c +3 -2
- data/ext/pg_query/pg_query_ruby.c +5 -0
- data/ext/pg_query/pg_query_scan.c +2 -2
- data/ext/pg_query/pg_query_split.c +3 -3
- data/ext/pg_query/postgres_deparse.c +11496 -0
- data/ext/pg_query/postgres_deparse.h +9 -0
- data/ext/pg_query/src_backend_catalog_namespace.c +243 -63
- data/ext/pg_query/src_backend_catalog_pg_proc.c +1 -3
- data/ext/pg_query/src_backend_commands_define.c +2 -3
- data/ext/pg_query/src_backend_nodes_bitmapset.c +140 -156
- data/ext/pg_query/src_backend_nodes_copyfuncs.c +96 -6202
- data/ext/pg_query/src_backend_nodes_equalfuncs.c +95 -4068
- data/ext/pg_query/src_backend_nodes_extensible.c +6 -29
- data/ext/pg_query/src_backend_nodes_list.c +16 -8
- data/ext/pg_query/src_backend_nodes_makefuncs.c +134 -1
- data/ext/pg_query/src_backend_nodes_nodeFuncs.c +391 -133
- data/ext/pg_query/src_backend_nodes_value.c +1 -1
- data/ext/pg_query/src_backend_parser_gram.c +43710 -39953
- data/ext/pg_query/src_backend_parser_parser.c +34 -8
- data/ext/pg_query/src_backend_parser_scan.c +6971 -3373
- data/ext/pg_query/src_backend_parser_scansup.c +2 -1
- data/ext/pg_query/src_backend_storage_ipc_ipc.c +1 -1
- data/ext/pg_query/src_backend_tcop_postgres.c +99 -96
- data/ext/pg_query/src_backend_utils_activity_pgstat_database.c +2 -2
- data/ext/pg_query/src_backend_utils_adt_datum.c +2 -2
- data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +1 -1
- data/ext/pg_query/src_backend_utils_adt_format_type.c +1 -1
- data/ext/pg_query/src_backend_utils_adt_numutils.c +488 -0
- data/ext/pg_query/src_backend_utils_adt_ruleutils.c +177 -30
- data/ext/pg_query/src_backend_utils_error_assert.c +4 -7
- data/ext/pg_query/src_backend_utils_error_elog.c +397 -270
- data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +36 -2
- data/ext/pg_query/src_backend_utils_init_globals.c +20 -5
- data/ext/pg_query/src_backend_utils_mb_mbutils.c +31 -84
- data/ext/pg_query/src_backend_utils_misc_guc_tables.c +502 -0
- data/ext/pg_query/src_backend_utils_mmgr_alignedalloc.c +166 -0
- data/ext/pg_query/src_backend_utils_mmgr_aset.c +704 -497
- data/ext/pg_query/src_backend_utils_mmgr_bump.c +728 -0
- data/ext/pg_query/src_backend_utils_mmgr_generation.c +1115 -0
- data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +637 -233
- data/ext/pg_query/src_backend_utils_mmgr_slab.c +1079 -0
- data/ext/pg_query/src_common_encnames.c +46 -44
- data/ext/pg_query/src_common_hashfn.c +1 -1
- data/ext/pg_query/src_common_keywords.c +1 -1
- data/ext/pg_query/src_common_kwlist_d.h +586 -517
- data/ext/pg_query/src_common_kwlookup.c +1 -1
- data/ext/pg_query/src_common_psprintf.c +3 -3
- data/ext/pg_query/src_common_stringinfo.c +21 -4
- data/ext/pg_query/src_common_wchar.c +100 -116
- data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +99 -5
- data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +3 -1
- data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +829 -763
- data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +1 -1
- data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +1 -1
- data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +19 -1
- data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +48 -46
- data/ext/pg_query/src_port_pg_bitutils.c +251 -32
- data/ext/pg_query/src_port_pgstrcasecmp.c +57 -1
- data/ext/pg_query/src_port_snprintf.c +20 -27
- data/ext/pg_query/src_port_strerror.c +1 -3
- data/ext/pg_query/src_port_strlcpy.c +79 -0
- data/lib/pg_query/fingerprint.rb +5 -8
- data/lib/pg_query/node.rb +16 -11
- data/lib/pg_query/param_refs.rb +2 -2
- data/lib/pg_query/parse.rb +6 -8
- data/lib/pg_query/parse_error.rb +1 -0
- data/lib/pg_query/pg_query_pb.rb +173 -3196
- data/lib/pg_query/scan.rb +1 -0
- data/lib/pg_query/treewalker.rb +52 -11
- data/lib/pg_query/truncate.rb +18 -20
- data/lib/pg_query/version.rb +1 -1
- metadata +443 -442
- data/ext/pg_query/guc-file.c +0 -0
- data/ext/pg_query/include/access/amapi.h +0 -290
- data/ext/pg_query/include/access/attmap.h +0 -52
- data/ext/pg_query/include/access/attnum.h +0 -64
- data/ext/pg_query/include/access/clog.h +0 -63
- data/ext/pg_query/include/access/commit_ts.h +0 -74
- data/ext/pg_query/include/access/detoast.h +0 -82
- data/ext/pg_query/include/access/genam.h +0 -231
- data/ext/pg_query/include/access/gin.h +0 -78
- data/ext/pg_query/include/access/htup.h +0 -89
- data/ext/pg_query/include/access/htup_details.h +0 -807
- data/ext/pg_query/include/access/itup.h +0 -167
- data/ext/pg_query/include/access/parallel.h +0 -82
- data/ext/pg_query/include/access/printtup.h +0 -35
- data/ext/pg_query/include/access/relation.h +0 -28
- data/ext/pg_query/include/access/relscan.h +0 -191
- data/ext/pg_query/include/access/rmgrlist.h +0 -49
- data/ext/pg_query/include/access/sdir.h +0 -58
- data/ext/pg_query/include/access/skey.h +0 -151
- data/ext/pg_query/include/access/stratnum.h +0 -85
- data/ext/pg_query/include/access/sysattr.h +0 -29
- data/ext/pg_query/include/access/table.h +0 -28
- data/ext/pg_query/include/access/tableam.h +0 -2077
- data/ext/pg_query/include/access/toast_compression.h +0 -73
- data/ext/pg_query/include/access/transam.h +0 -375
- data/ext/pg_query/include/access/tupconvert.h +0 -51
- data/ext/pg_query/include/access/tupdesc.h +0 -154
- data/ext/pg_query/include/access/tupmacs.h +0 -247
- data/ext/pg_query/include/access/twophase.h +0 -65
- data/ext/pg_query/include/access/xact.h +0 -523
- data/ext/pg_query/include/access/xlog.h +0 -303
- data/ext/pg_query/include/access/xlog_internal.h +0 -366
- data/ext/pg_query/include/access/xlogdefs.h +0 -101
- data/ext/pg_query/include/access/xlogprefetcher.h +0 -55
- data/ext/pg_query/include/access/xlogreader.h +0 -443
- data/ext/pg_query/include/access/xlogrecord.h +0 -236
- data/ext/pg_query/include/access/xlogrecovery.h +0 -157
- data/ext/pg_query/include/c.h +0 -1391
- data/ext/pg_query/include/catalog/catalog.h +0 -44
- data/ext/pg_query/include/catalog/catversion.h +0 -58
- data/ext/pg_query/include/catalog/dependency.h +0 -269
- data/ext/pg_query/include/catalog/genbki.h +0 -142
- data/ext/pg_query/include/catalog/index.h +0 -214
- data/ext/pg_query/include/catalog/indexing.h +0 -54
- data/ext/pg_query/include/catalog/namespace.h +0 -190
- data/ext/pg_query/include/catalog/objectaccess.h +0 -265
- data/ext/pg_query/include/catalog/objectaddress.h +0 -89
- data/ext/pg_query/include/catalog/pg_aggregate.h +0 -180
- data/ext/pg_query/include/catalog/pg_aggregate_d.h +0 -78
- data/ext/pg_query/include/catalog/pg_am.h +0 -63
- data/ext/pg_query/include/catalog/pg_am_d.h +0 -47
- data/ext/pg_query/include/catalog/pg_attribute.h +0 -221
- data/ext/pg_query/include/catalog/pg_attribute_d.h +0 -62
- data/ext/pg_query/include/catalog/pg_authid.h +0 -63
- data/ext/pg_query/include/catalog/pg_authid_d.h +0 -57
- data/ext/pg_query/include/catalog/pg_class.h +0 -230
- data/ext/pg_query/include/catalog/pg_class_d.h +0 -132
- data/ext/pg_query/include/catalog/pg_collation.h +0 -98
- data/ext/pg_query/include/catalog/pg_collation_d.h +0 -62
- data/ext/pg_query/include/catalog/pg_constraint.h +0 -273
- data/ext/pg_query/include/catalog/pg_constraint_d.h +0 -73
- data/ext/pg_query/include/catalog/pg_control.h +0 -250
- data/ext/pg_query/include/catalog/pg_conversion.h +0 -75
- data/ext/pg_query/include/catalog/pg_conversion_d.h +0 -38
- data/ext/pg_query/include/catalog/pg_depend.h +0 -77
- data/ext/pg_query/include/catalog/pg_depend_d.h +0 -36
- data/ext/pg_query/include/catalog/pg_event_trigger.h +0 -57
- data/ext/pg_query/include/catalog/pg_event_trigger_d.h +0 -36
- data/ext/pg_query/include/catalog/pg_index.h +0 -90
- data/ext/pg_query/include/catalog/pg_index_d.h +0 -59
- data/ext/pg_query/include/catalog/pg_language.h +0 -72
- data/ext/pg_query/include/catalog/pg_language_d.h +0 -41
- data/ext/pg_query/include/catalog/pg_namespace.h +0 -64
- data/ext/pg_query/include/catalog/pg_namespace_d.h +0 -36
- data/ext/pg_query/include/catalog/pg_opclass.h +0 -88
- data/ext/pg_query/include/catalog/pg_opclass_d.h +0 -51
- data/ext/pg_query/include/catalog/pg_operator.h +0 -107
- data/ext/pg_query/include/catalog/pg_operator_d.h +0 -142
- data/ext/pg_query/include/catalog/pg_opfamily.h +0 -63
- data/ext/pg_query/include/catalog/pg_opfamily_d.h +0 -49
- data/ext/pg_query/include/catalog/pg_parameter_acl.h +0 -60
- data/ext/pg_query/include/catalog/pg_parameter_acl_d.h +0 -34
- data/ext/pg_query/include/catalog/pg_partitioned_table.h +0 -74
- data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +0 -36
- data/ext/pg_query/include/catalog/pg_proc.h +0 -220
- data/ext/pg_query/include/catalog/pg_proc_d.h +0 -101
- data/ext/pg_query/include/catalog/pg_publication.h +0 -161
- data/ext/pg_query/include/catalog/pg_publication_d.h +0 -38
- data/ext/pg_query/include/catalog/pg_replication_origin.h +0 -62
- data/ext/pg_query/include/catalog/pg_replication_origin_d.h +0 -33
- data/ext/pg_query/include/catalog/pg_statistic.h +0 -282
- data/ext/pg_query/include/catalog/pg_statistic_d.h +0 -195
- data/ext/pg_query/include/catalog/pg_statistic_ext.h +0 -88
- data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +0 -45
- data/ext/pg_query/include/catalog/pg_transform.h +0 -48
- data/ext/pg_query/include/catalog/pg_transform_d.h +0 -34
- data/ext/pg_query/include/catalog/pg_trigger.h +0 -153
- data/ext/pg_query/include/catalog/pg_trigger_d.h +0 -109
- data/ext/pg_query/include/catalog/pg_ts_config.h +0 -53
- data/ext/pg_query/include/catalog/pg_ts_config_d.h +0 -34
- data/ext/pg_query/include/catalog/pg_ts_dict.h +0 -59
- data/ext/pg_query/include/catalog/pg_ts_dict_d.h +0 -35
- data/ext/pg_query/include/catalog/pg_ts_parser.h +0 -60
- data/ext/pg_query/include/catalog/pg_ts_parser_d.h +0 -37
- data/ext/pg_query/include/catalog/pg_ts_template.h +0 -51
- data/ext/pg_query/include/catalog/pg_ts_template_d.h +0 -34
- data/ext/pg_query/include/catalog/pg_type.h +0 -404
- data/ext/pg_query/include/catalog/pg_type_d.h +0 -324
- data/ext/pg_query/include/catalog/storage.h +0 -50
- data/ext/pg_query/include/commands/async.h +0 -53
- data/ext/pg_query/include/commands/dbcommands.h +0 -36
- data/ext/pg_query/include/commands/defrem.h +0 -160
- data/ext/pg_query/include/commands/event_trigger.h +0 -88
- data/ext/pg_query/include/commands/explain.h +0 -127
- data/ext/pg_query/include/commands/prepare.h +0 -61
- data/ext/pg_query/include/commands/tablespace.h +0 -69
- data/ext/pg_query/include/commands/trigger.h +0 -287
- data/ext/pg_query/include/commands/user.h +0 -37
- data/ext/pg_query/include/commands/vacuum.h +0 -340
- data/ext/pg_query/include/commands/variable.h +0 -38
- data/ext/pg_query/include/common/file_perm.h +0 -56
- data/ext/pg_query/include/common/hashfn.h +0 -104
- data/ext/pg_query/include/common/ip.h +0 -31
- data/ext/pg_query/include/common/keywords.h +0 -29
- data/ext/pg_query/include/common/kwlookup.h +0 -44
- data/ext/pg_query/include/common/pg_prng.h +0 -60
- data/ext/pg_query/include/common/relpath.h +0 -90
- data/ext/pg_query/include/common/string.h +0 -42
- data/ext/pg_query/include/common/unicode_combining_table.h +0 -308
- data/ext/pg_query/include/common/unicode_east_asian_fw_table.h +0 -125
- data/ext/pg_query/include/datatype/timestamp.h +0 -236
- data/ext/pg_query/include/executor/execdesc.h +0 -70
- data/ext/pg_query/include/executor/executor.h +0 -663
- data/ext/pg_query/include/executor/functions.h +0 -55
- data/ext/pg_query/include/executor/instrument.h +0 -118
- data/ext/pg_query/include/executor/spi.h +0 -213
- data/ext/pg_query/include/executor/tablefunc.h +0 -67
- data/ext/pg_query/include/executor/tuptable.h +0 -487
- data/ext/pg_query/include/fmgr.h +0 -781
- data/ext/pg_query/include/funcapi.h +0 -360
- data/ext/pg_query/include/getaddrinfo.h +0 -162
- data/ext/pg_query/include/jit/jit.h +0 -105
- data/ext/pg_query/include/kwlist_d.h +0 -1095
- data/ext/pg_query/include/lib/dshash.h +0 -112
- data/ext/pg_query/include/lib/ilist.h +0 -746
- data/ext/pg_query/include/lib/pairingheap.h +0 -102
- data/ext/pg_query/include/lib/simplehash.h +0 -1184
- data/ext/pg_query/include/lib/sort_template.h +0 -432
- data/ext/pg_query/include/lib/stringinfo.h +0 -161
- data/ext/pg_query/include/libpq/auth.h +0 -31
- data/ext/pg_query/include/libpq/crypt.h +0 -47
- data/ext/pg_query/include/libpq/hba.h +0 -179
- data/ext/pg_query/include/libpq/libpq-be.h +0 -343
- data/ext/pg_query/include/libpq/libpq.h +0 -144
- data/ext/pg_query/include/libpq/pqcomm.h +0 -194
- data/ext/pg_query/include/libpq/pqformat.h +0 -210
- data/ext/pg_query/include/libpq/pqsignal.h +0 -42
- data/ext/pg_query/include/mb/pg_wchar.h +0 -755
- data/ext/pg_query/include/mb/stringinfo_mb.h +0 -24
- data/ext/pg_query/include/miscadmin.h +0 -495
- data/ext/pg_query/include/nodes/bitmapset.h +0 -122
- data/ext/pg_query/include/nodes/execnodes.h +0 -2715
- data/ext/pg_query/include/nodes/extensible.h +0 -162
- data/ext/pg_query/include/nodes/lockoptions.h +0 -61
- data/ext/pg_query/include/nodes/makefuncs.h +0 -109
- data/ext/pg_query/include/nodes/memnodes.h +0 -110
- data/ext/pg_query/include/nodes/nodeFuncs.h +0 -162
- data/ext/pg_query/include/nodes/nodes.h +0 -861
- data/ext/pg_query/include/nodes/params.h +0 -170
- data/ext/pg_query/include/nodes/parsenodes.h +0 -3812
- data/ext/pg_query/include/nodes/pathnodes.h +0 -2734
- data/ext/pg_query/include/nodes/pg_list.h +0 -612
- data/ext/pg_query/include/nodes/plannodes.h +0 -1349
- data/ext/pg_query/include/nodes/primnodes.h +0 -1593
- data/ext/pg_query/include/nodes/print.h +0 -34
- data/ext/pg_query/include/nodes/tidbitmap.h +0 -75
- data/ext/pg_query/include/nodes/value.h +0 -80
- data/ext/pg_query/include/optimizer/cost.h +0 -213
- data/ext/pg_query/include/optimizer/geqo.h +0 -90
- data/ext/pg_query/include/optimizer/geqo_gene.h +0 -45
- data/ext/pg_query/include/optimizer/optimizer.h +0 -202
- data/ext/pg_query/include/optimizer/paths.h +0 -257
- data/ext/pg_query/include/optimizer/planmain.h +0 -120
- data/ext/pg_query/include/parser/analyze.h +0 -63
- data/ext/pg_query/include/parser/gram.h +0 -1101
- data/ext/pg_query/include/parser/gramparse.h +0 -75
- data/ext/pg_query/include/parser/kwlist.h +0 -487
- data/ext/pg_query/include/parser/parse_agg.h +0 -63
- data/ext/pg_query/include/parser/parse_coerce.h +0 -100
- data/ext/pg_query/include/parser/parse_expr.h +0 -25
- data/ext/pg_query/include/parser/parse_func.h +0 -74
- data/ext/pg_query/include/parser/parse_node.h +0 -339
- data/ext/pg_query/include/parser/parse_oper.h +0 -65
- data/ext/pg_query/include/parser/parse_relation.h +0 -124
- data/ext/pg_query/include/parser/parse_type.h +0 -60
- data/ext/pg_query/include/parser/parser.h +0 -68
- data/ext/pg_query/include/parser/parsetree.h +0 -61
- data/ext/pg_query/include/parser/scanner.h +0 -152
- data/ext/pg_query/include/parser/scansup.h +0 -27
- data/ext/pg_query/include/partitioning/partdefs.h +0 -26
- data/ext/pg_query/include/pg_config.h +0 -1037
- data/ext/pg_query/include/pg_config_manual.h +0 -410
- data/ext/pg_query/include/pg_config_os.h +0 -8
- data/ext/pg_query/include/pg_getopt.h +0 -56
- data/ext/pg_query/include/pg_trace.h +0 -17
- data/ext/pg_query/include/pgstat.h +0 -699
- data/ext/pg_query/include/pgtime.h +0 -94
- data/ext/pg_query/include/pl_gram.h +0 -383
- data/ext/pg_query/include/pl_reserved_kwlist.h +0 -52
- data/ext/pg_query/include/pl_reserved_kwlist_d.h +0 -114
- data/ext/pg_query/include/pl_unreserved_kwlist.h +0 -111
- data/ext/pg_query/include/pl_unreserved_kwlist_d.h +0 -244
- data/ext/pg_query/include/plerrcodes.h +0 -998
- data/ext/pg_query/include/plpgsql.h +0 -1345
- data/ext/pg_query/include/port/atomics/arch-arm.h +0 -32
- data/ext/pg_query/include/port/atomics/arch-ppc.h +0 -254
- data/ext/pg_query/include/port/atomics/arch-x86.h +0 -252
- data/ext/pg_query/include/port/atomics/fallback.h +0 -170
- data/ext/pg_query/include/port/atomics/generic-gcc.h +0 -286
- data/ext/pg_query/include/port/atomics/generic.h +0 -401
- data/ext/pg_query/include/port/atomics.h +0 -524
- data/ext/pg_query/include/port/pg_bitutils.h +0 -302
- data/ext/pg_query/include/port/pg_bswap.h +0 -161
- data/ext/pg_query/include/port/pg_crc32c.h +0 -101
- data/ext/pg_query/include/port.h +0 -553
- data/ext/pg_query/include/portability/instr_time.h +0 -256
- data/ext/pg_query/include/postgres.h +0 -808
- data/ext/pg_query/include/postgres_ext.h +0 -74
- data/ext/pg_query/include/postmaster/autovacuum.h +0 -83
- data/ext/pg_query/include/postmaster/auxprocess.h +0 -20
- data/ext/pg_query/include/postmaster/bgworker.h +0 -162
- data/ext/pg_query/include/postmaster/bgworker_internals.h +0 -64
- data/ext/pg_query/include/postmaster/bgwriter.h +0 -45
- data/ext/pg_query/include/postmaster/fork_process.h +0 -17
- data/ext/pg_query/include/postmaster/interrupt.h +0 -32
- data/ext/pg_query/include/postmaster/pgarch.h +0 -73
- data/ext/pg_query/include/postmaster/postmaster.h +0 -78
- data/ext/pg_query/include/postmaster/startup.h +0 -39
- data/ext/pg_query/include/postmaster/syslogger.h +0 -103
- data/ext/pg_query/include/postmaster/walwriter.h +0 -21
- data/ext/pg_query/include/regex/regex.h +0 -186
- data/ext/pg_query/include/replication/logicallauncher.h +0 -29
- data/ext/pg_query/include/replication/logicalproto.h +0 -254
- data/ext/pg_query/include/replication/logicalworker.h +0 -19
- data/ext/pg_query/include/replication/origin.h +0 -73
- data/ext/pg_query/include/replication/reorderbuffer.h +0 -685
- data/ext/pg_query/include/replication/slot.h +0 -230
- data/ext/pg_query/include/replication/syncrep.h +0 -115
- data/ext/pg_query/include/replication/walreceiver.h +0 -472
- data/ext/pg_query/include/replication/walsender.h +0 -74
- data/ext/pg_query/include/rewrite/prs2lock.h +0 -46
- data/ext/pg_query/include/rewrite/rewriteHandler.h +0 -38
- data/ext/pg_query/include/rewrite/rewriteManip.h +0 -87
- data/ext/pg_query/include/rewrite/rewriteSupport.h +0 -26
- data/ext/pg_query/include/storage/backendid.h +0 -37
- data/ext/pg_query/include/storage/block.h +0 -115
- data/ext/pg_query/include/storage/buf.h +0 -46
- data/ext/pg_query/include/storage/bufmgr.h +0 -297
- data/ext/pg_query/include/storage/bufpage.h +0 -457
- data/ext/pg_query/include/storage/condition_variable.h +0 -73
- data/ext/pg_query/include/storage/dsm.h +0 -64
- data/ext/pg_query/include/storage/dsm_impl.h +0 -76
- data/ext/pg_query/include/storage/fd.h +0 -198
- data/ext/pg_query/include/storage/fileset.h +0 -40
- data/ext/pg_query/include/storage/ipc.h +0 -84
- data/ext/pg_query/include/storage/item.h +0 -19
- data/ext/pg_query/include/storage/itemid.h +0 -184
- data/ext/pg_query/include/storage/itemptr.h +0 -208
- data/ext/pg_query/include/storage/large_object.h +0 -100
- data/ext/pg_query/include/storage/latch.h +0 -186
- data/ext/pg_query/include/storage/lmgr.h +0 -115
- data/ext/pg_query/include/storage/lock.h +0 -616
- data/ext/pg_query/include/storage/lockdefs.h +0 -59
- data/ext/pg_query/include/storage/lwlock.h +0 -206
- data/ext/pg_query/include/storage/lwlocknames.h +0 -50
- data/ext/pg_query/include/storage/off.h +0 -57
- data/ext/pg_query/include/storage/pg_sema.h +0 -61
- data/ext/pg_query/include/storage/pg_shmem.h +0 -92
- data/ext/pg_query/include/storage/pmsignal.h +0 -105
- data/ext/pg_query/include/storage/predicate.h +0 -87
- data/ext/pg_query/include/storage/proc.h +0 -461
- data/ext/pg_query/include/storage/procarray.h +0 -98
- data/ext/pg_query/include/storage/proclist_types.h +0 -51
- data/ext/pg_query/include/storage/procsignal.h +0 -71
- data/ext/pg_query/include/storage/relfilenode.h +0 -99
- data/ext/pg_query/include/storage/s_lock.h +0 -1110
- data/ext/pg_query/include/storage/sharedfileset.h +0 -37
- data/ext/pg_query/include/storage/shm_mq.h +0 -86
- data/ext/pg_query/include/storage/shm_toc.h +0 -58
- data/ext/pg_query/include/storage/shmem.h +0 -81
- data/ext/pg_query/include/storage/sinval.h +0 -153
- data/ext/pg_query/include/storage/sinvaladt.h +0 -43
- data/ext/pg_query/include/storage/smgr.h +0 -111
- data/ext/pg_query/include/storage/spin.h +0 -77
- data/ext/pg_query/include/storage/standby.h +0 -98
- data/ext/pg_query/include/storage/standbydefs.h +0 -74
- data/ext/pg_query/include/storage/sync.h +0 -66
- data/ext/pg_query/include/tcop/cmdtag.h +0 -58
- data/ext/pg_query/include/tcop/cmdtaglist.h +0 -218
- data/ext/pg_query/include/tcop/deparse_utility.h +0 -108
- data/ext/pg_query/include/tcop/dest.h +0 -149
- data/ext/pg_query/include/tcop/fastpath.h +0 -20
- data/ext/pg_query/include/tcop/pquery.h +0 -51
- data/ext/pg_query/include/tcop/tcopprot.h +0 -97
- data/ext/pg_query/include/tcop/utility.h +0 -112
- data/ext/pg_query/include/tsearch/ts_cache.h +0 -98
- data/ext/pg_query/include/utils/acl.h +0 -333
- data/ext/pg_query/include/utils/aclchk_internal.h +0 -45
- data/ext/pg_query/include/utils/array.h +0 -464
- data/ext/pg_query/include/utils/backend_progress.h +0 -44
- data/ext/pg_query/include/utils/backend_status.h +0 -321
- data/ext/pg_query/include/utils/builtins.h +0 -127
- data/ext/pg_query/include/utils/bytea.h +0 -28
- data/ext/pg_query/include/utils/catcache.h +0 -231
- data/ext/pg_query/include/utils/date.h +0 -90
- data/ext/pg_query/include/utils/datetime.h +0 -344
- data/ext/pg_query/include/utils/datum.h +0 -76
- data/ext/pg_query/include/utils/dsa.h +0 -123
- data/ext/pg_query/include/utils/dynahash.h +0 -20
- data/ext/pg_query/include/utils/elog.h +0 -470
- data/ext/pg_query/include/utils/errcodes.h +0 -354
- data/ext/pg_query/include/utils/expandeddatum.h +0 -159
- data/ext/pg_query/include/utils/expandedrecord.h +0 -231
- data/ext/pg_query/include/utils/float.h +0 -356
- data/ext/pg_query/include/utils/fmgroids.h +0 -3261
- data/ext/pg_query/include/utils/fmgrprotos.h +0 -2829
- data/ext/pg_query/include/utils/fmgrtab.h +0 -49
- data/ext/pg_query/include/utils/guc.h +0 -469
- data/ext/pg_query/include/utils/guc_tables.h +0 -276
- data/ext/pg_query/include/utils/hsearch.h +0 -153
- data/ext/pg_query/include/utils/inval.h +0 -68
- data/ext/pg_query/include/utils/lsyscache.h +0 -208
- data/ext/pg_query/include/utils/memdebug.h +0 -82
- data/ext/pg_query/include/utils/memutils.h +0 -230
- data/ext/pg_query/include/utils/numeric.h +0 -90
- data/ext/pg_query/include/utils/palloc.h +0 -158
- data/ext/pg_query/include/utils/partcache.h +0 -102
- data/ext/pg_query/include/utils/pg_locale.h +0 -127
- data/ext/pg_query/include/utils/pg_lsn.h +0 -29
- data/ext/pg_query/include/utils/pgstat_internal.h +0 -784
- data/ext/pg_query/include/utils/pidfile.h +0 -56
- data/ext/pg_query/include/utils/plancache.h +0 -236
- data/ext/pg_query/include/utils/portal.h +0 -252
- data/ext/pg_query/include/utils/probes.h +0 -114
- data/ext/pg_query/include/utils/ps_status.h +0 -25
- data/ext/pg_query/include/utils/queryenvironment.h +0 -74
- data/ext/pg_query/include/utils/queryjumble.h +0 -88
- data/ext/pg_query/include/utils/regproc.h +0 -39
- data/ext/pg_query/include/utils/rel.h +0 -695
- data/ext/pg_query/include/utils/relcache.h +0 -153
- data/ext/pg_query/include/utils/reltrigger.h +0 -81
- data/ext/pg_query/include/utils/resowner.h +0 -86
- data/ext/pg_query/include/utils/rls.h +0 -50
- data/ext/pg_query/include/utils/ruleutils.h +0 -47
- data/ext/pg_query/include/utils/sharedtuplestore.h +0 -61
- data/ext/pg_query/include/utils/snapmgr.h +0 -179
- data/ext/pg_query/include/utils/snapshot.h +0 -219
- data/ext/pg_query/include/utils/sortsupport.h +0 -391
- data/ext/pg_query/include/utils/syscache.h +0 -224
- data/ext/pg_query/include/utils/timeout.h +0 -95
- data/ext/pg_query/include/utils/timestamp.h +0 -117
- data/ext/pg_query/include/utils/tuplesort.h +0 -291
- data/ext/pg_query/include/utils/tuplestore.h +0 -91
- data/ext/pg_query/include/utils/typcache.h +0 -209
- data/ext/pg_query/include/utils/tzparser.h +0 -39
- data/ext/pg_query/include/utils/varlena.h +0 -41
- data/ext/pg_query/include/utils/wait_event.h +0 -289
- data/ext/pg_query/include/utils/xml.h +0 -84
- data/ext/pg_query/src_backend_postmaster_postmaster.c +0 -2201
- data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +0 -371
- data/ext/pg_query/src_backend_utils_hash_dynahash.c +0 -1116
- data/ext/pg_query/src_backend_utils_misc_guc.c +0 -1993
- data/ext/pg_query/src_common_pg_prng.c +0 -152
- data/ext/pg_query/src_common_string.c +0 -92
- data/ext/pg_query/src_port_pgsleep.c +0 -69
- data/ext/pg_query/src_port_strnlen.c +0 -39
- /data/ext/pg_query/{pg_query_ruby.sym → ext_symbols.sym} +0 -0
- /data/ext/pg_query/include/{access → postgres/access}/rmgr.h +0 -0
- /data/ext/pg_query/include/{pg_config_ext.h → postgres/pg_config_ext.h} +0 -0
@@ -0,0 +1,1079 @@
|
|
1
|
+
/*--------------------------------------------------------------------
|
2
|
+
* Symbols referenced in this file:
|
3
|
+
* - SlabAlloc
|
4
|
+
* - SlabBlocklistIndex
|
5
|
+
* - SlabAllocInvalidSize
|
6
|
+
* - SlabAllocFromNewBlock
|
7
|
+
* - SlabGetNextFreeChunk
|
8
|
+
* - SlabFindNextBlockListIndex
|
9
|
+
* - SlabAllocSetupNewChunk
|
10
|
+
* - SlabFree
|
11
|
+
* - SlabRealloc
|
12
|
+
* - SlabReset
|
13
|
+
* - SlabDelete
|
14
|
+
* - SlabGetChunkContext
|
15
|
+
* - SlabGetChunkSpace
|
16
|
+
* - SlabIsEmpty
|
17
|
+
* - SlabStats
|
18
|
+
* - SlabCheck
|
19
|
+
*--------------------------------------------------------------------
|
20
|
+
*/
|
21
|
+
|
22
|
+
/*-------------------------------------------------------------------------
|
23
|
+
*
|
24
|
+
* slab.c
|
25
|
+
* SLAB allocator definitions.
|
26
|
+
*
|
27
|
+
* SLAB is a MemoryContext implementation designed for cases where large
|
28
|
+
* numbers of equally-sized objects can be allocated and freed efficiently
|
29
|
+
* with minimal memory wastage and fragmentation.
|
30
|
+
*
|
31
|
+
*
|
32
|
+
* Portions Copyright (c) 2017-2024, PostgreSQL Global Development Group
|
33
|
+
*
|
34
|
+
* IDENTIFICATION
|
35
|
+
* src/backend/utils/mmgr/slab.c
|
36
|
+
*
|
37
|
+
*
|
38
|
+
* NOTE:
|
39
|
+
* The constant allocation size allows significant simplification and various
|
40
|
+
* optimizations over more general purpose allocators. The blocks are carved
|
41
|
+
* into chunks of exactly the right size, wasting only the space required to
|
42
|
+
* MAXALIGN the allocated chunks.
|
43
|
+
*
|
44
|
+
* Slab can also help reduce memory fragmentation in cases where longer-lived
|
45
|
+
* chunks remain stored on blocks while most of the other chunks have already
|
46
|
+
* been pfree'd. We give priority to putting new allocations into the
|
47
|
+
* "fullest" block. This help avoid having too many sparsely used blocks
|
48
|
+
* around and allows blocks to more easily become completely unused which
|
49
|
+
* allows them to be eventually free'd.
|
50
|
+
*
|
51
|
+
* We identify the "fullest" block to put new allocations on by using a block
|
52
|
+
* from the lowest populated element of the context's "blocklist" array.
|
53
|
+
* This is an array of dlists containing blocks which we partition by the
|
54
|
+
* number of free chunks which block has. Blocks with fewer free chunks are
|
55
|
+
* stored in a lower indexed dlist array slot. Full blocks go on the 0th
|
56
|
+
* element of the blocklist array. So that we don't have to have too many
|
57
|
+
* elements in the array, each dlist in the array is responsible for a range
|
58
|
+
* of free chunks. When a chunk is palloc'd or pfree'd we may need to move
|
59
|
+
* the block onto another dlist if the number of free chunks crosses the
|
60
|
+
* range boundary that the current list is responsible for. Having just a
|
61
|
+
* few blocklist elements reduces the number of times we must move the block
|
62
|
+
* onto another dlist element.
|
63
|
+
*
|
64
|
+
* We keep track of free chunks within each block by using a block-level free
|
65
|
+
* list. We consult this list when we allocate a new chunk in the block.
|
66
|
+
* The free list is a linked list, the head of which is pointed to with
|
67
|
+
* SlabBlock's freehead field. Each subsequent list item is stored in the
|
68
|
+
* free chunk's memory. We ensure chunks are large enough to store this
|
69
|
+
* address.
|
70
|
+
*
|
71
|
+
* When we allocate a new block, technically all chunks are free, however, to
|
72
|
+
* avoid having to write out the entire block to set the linked list for the
|
73
|
+
* free chunks for every chunk in the block, we instead store a pointer to
|
74
|
+
* the next "unused" chunk on the block and keep track of how many of these
|
75
|
+
* unused chunks there are. When a new block is malloc'd, all chunks are
|
76
|
+
* unused. The unused pointer starts with the first chunk on the block and
|
77
|
+
* as chunks are allocated, the unused pointer is incremented. As chunks are
|
78
|
+
* pfree'd, the unused pointer never goes backwards. The unused pointer can
|
79
|
+
* be thought of as a high watermark for the maximum number of chunks in the
|
80
|
+
* block which have been in use concurrently. When a chunk is pfree'd the
|
81
|
+
* chunk is put onto the head of the free list and the unused pointer is not
|
82
|
+
* changed. We only consume more unused chunks if we run out of free chunks
|
83
|
+
* on the free list. This method effectively gives priority to using
|
84
|
+
* previously used chunks over previously unused chunks, which should perform
|
85
|
+
* better due to CPU caching effects.
|
86
|
+
*
|
87
|
+
*-------------------------------------------------------------------------
|
88
|
+
*/
|
89
|
+
|
90
|
+
#include "postgres.h"
|
91
|
+
|
92
|
+
#include "lib/ilist.h"
|
93
|
+
#include "utils/memdebug.h"
|
94
|
+
#include "utils/memutils.h"
|
95
|
+
#include "utils/memutils_internal.h"
|
96
|
+
#include "utils/memutils_memorychunk.h"
|
97
|
+
|
98
|
+
#define Slab_BLOCKHDRSZ MAXALIGN(sizeof(SlabBlock))
|
99
|
+
|
100
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
101
|
+
/*
|
102
|
+
* Size of the memory required to store the SlabContext.
|
103
|
+
* MEMORY_CONTEXT_CHECKING builds need some extra memory for the isChunkFree
|
104
|
+
* array.
|
105
|
+
*/
|
106
|
+
#define Slab_CONTEXT_HDRSZ(chunksPerBlock) \
|
107
|
+
(sizeof(SlabContext) + ((chunksPerBlock) * sizeof(bool)))
|
108
|
+
#else
|
109
|
+
#define Slab_CONTEXT_HDRSZ(chunksPerBlock) sizeof(SlabContext)
|
110
|
+
#endif
|
111
|
+
|
112
|
+
/*
|
113
|
+
* The number of partitions to divide the blocklist into based their number of
|
114
|
+
* free chunks. There must be at least 2.
|
115
|
+
*/
|
116
|
+
#define SLAB_BLOCKLIST_COUNT 3
|
117
|
+
|
118
|
+
/* The maximum number of completely empty blocks to keep around for reuse. */
|
119
|
+
#define SLAB_MAXIMUM_EMPTY_BLOCKS 10
|
120
|
+
|
121
|
+
/*
|
122
|
+
* SlabContext is a specialized implementation of MemoryContext.
|
123
|
+
*/
|
124
|
+
typedef struct SlabContext
|
125
|
+
{
|
126
|
+
MemoryContextData header; /* Standard memory-context fields */
|
127
|
+
/* Allocation parameters for this context: */
|
128
|
+
uint32 chunkSize; /* the requested (non-aligned) chunk size */
|
129
|
+
uint32 fullChunkSize; /* chunk size with chunk header and alignment */
|
130
|
+
uint32 blockSize; /* the size to make each block of chunks */
|
131
|
+
int32 chunksPerBlock; /* number of chunks that fit in 1 block */
|
132
|
+
int32 curBlocklistIndex; /* index into the blocklist[] element
|
133
|
+
* containing the fullest, blocks */
|
134
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
135
|
+
bool *isChunkFree; /* array to mark free chunks in a block during
|
136
|
+
* SlabCheck */
|
137
|
+
#endif
|
138
|
+
|
139
|
+
int32 blocklist_shift; /* number of bits to shift the nfree count
|
140
|
+
* by to get the index into blocklist[] */
|
141
|
+
dclist_head emptyblocks; /* empty blocks to use up first instead of
|
142
|
+
* mallocing new blocks */
|
143
|
+
|
144
|
+
/*
|
145
|
+
* Blocks with free space, grouped by the number of free chunks they
|
146
|
+
* contain. Completely full blocks are stored in the 0th element.
|
147
|
+
* Completely empty blocks are stored in emptyblocks or free'd if we have
|
148
|
+
* enough empty blocks already.
|
149
|
+
*/
|
150
|
+
dlist_head blocklist[SLAB_BLOCKLIST_COUNT];
|
151
|
+
} SlabContext;
|
152
|
+
|
153
|
+
/*
|
154
|
+
* SlabBlock
|
155
|
+
* Structure of a single slab block.
|
156
|
+
*
|
157
|
+
* slab: pointer back to the owning MemoryContext
|
158
|
+
* nfree: number of chunks on the block which are unallocated
|
159
|
+
* nunused: number of chunks on the block unallocated and not on the block's
|
160
|
+
* freelist.
|
161
|
+
* freehead: linked-list header storing a pointer to the first free chunk on
|
162
|
+
* the block. Subsequent pointers are stored in the chunk's memory. NULL
|
163
|
+
* indicates the end of the list.
|
164
|
+
* unused: pointer to the next chunk which has yet to be used.
|
165
|
+
* node: doubly-linked list node for the context's blocklist
|
166
|
+
*/
|
167
|
+
typedef struct SlabBlock
|
168
|
+
{
|
169
|
+
SlabContext *slab; /* owning context */
|
170
|
+
int32 nfree; /* number of chunks on free + unused chunks */
|
171
|
+
int32 nunused; /* number of unused chunks */
|
172
|
+
MemoryChunk *freehead; /* pointer to the first free chunk */
|
173
|
+
MemoryChunk *unused; /* pointer to the next unused chunk */
|
174
|
+
dlist_node node; /* doubly-linked list for blocklist[] */
|
175
|
+
} SlabBlock;
|
176
|
+
|
177
|
+
|
178
|
+
#define Slab_CHUNKHDRSZ sizeof(MemoryChunk)
|
179
|
+
#define SlabChunkGetPointer(chk) \
|
180
|
+
((void *) (((char *) (chk)) + sizeof(MemoryChunk)))
|
181
|
+
|
182
|
+
/*
|
183
|
+
* SlabBlockGetChunk
|
184
|
+
* Obtain a pointer to the nth (0-based) chunk in the block
|
185
|
+
*/
|
186
|
+
#define SlabBlockGetChunk(slab, block, n) \
|
187
|
+
((MemoryChunk *) ((char *) (block) + Slab_BLOCKHDRSZ \
|
188
|
+
+ ((n) * (slab)->fullChunkSize)))
|
189
|
+
|
190
|
+
#if defined(MEMORY_CONTEXT_CHECKING) || defined(USE_ASSERT_CHECKING)
|
191
|
+
|
192
|
+
/*
|
193
|
+
* SlabChunkIndex
|
194
|
+
* Get the 0-based index of how many chunks into the block the given
|
195
|
+
* chunk is.
|
196
|
+
*/
|
197
|
+
#define SlabChunkIndex(slab, block, chunk) \
|
198
|
+
(((char *) (chunk) - (char *) SlabBlockGetChunk(slab, block, 0)) / \
|
199
|
+
(slab)->fullChunkSize)
|
200
|
+
|
201
|
+
/*
|
202
|
+
* SlabChunkMod
|
203
|
+
* A MemoryChunk should always be at an address which is a multiple of
|
204
|
+
* fullChunkSize starting from the 0th chunk position. This will return
|
205
|
+
* non-zero if it's not.
|
206
|
+
*/
|
207
|
+
#define SlabChunkMod(slab, block, chunk) \
|
208
|
+
(((char *) (chunk) - (char *) SlabBlockGetChunk(slab, block, 0)) % \
|
209
|
+
(slab)->fullChunkSize)
|
210
|
+
|
211
|
+
#endif
|
212
|
+
|
213
|
+
/*
|
214
|
+
* SlabIsValid
|
215
|
+
* True iff set is a valid slab allocation set.
|
216
|
+
*/
|
217
|
+
#define SlabIsValid(set) (PointerIsValid(set) && IsA(set, SlabContext))
|
218
|
+
|
219
|
+
/*
|
220
|
+
* SlabBlockIsValid
|
221
|
+
* True iff block is a valid block of slab allocation set.
|
222
|
+
*/
|
223
|
+
#define SlabBlockIsValid(block) \
|
224
|
+
(PointerIsValid(block) && SlabIsValid((block)->slab))
|
225
|
+
|
226
|
+
/*
|
227
|
+
* SlabBlocklistIndex
|
228
|
+
* Determine the blocklist index that a block should be in for the given
|
229
|
+
* number of free chunks.
|
230
|
+
*/
|
231
|
+
static inline int32
|
232
|
+
SlabBlocklistIndex(SlabContext *slab, int nfree)
|
233
|
+
{
|
234
|
+
int32 index;
|
235
|
+
int32 blocklist_shift = slab->blocklist_shift;
|
236
|
+
|
237
|
+
Assert(nfree >= 0 && nfree <= slab->chunksPerBlock);
|
238
|
+
|
239
|
+
/*
|
240
|
+
* Determine the blocklist index based on the number of free chunks. We
|
241
|
+
* must ensure that 0 free chunks is dedicated to index 0. Everything
|
242
|
+
* else must be >= 1 and < SLAB_BLOCKLIST_COUNT.
|
243
|
+
*
|
244
|
+
* To make this as efficient as possible, we exploit some two's complement
|
245
|
+
* arithmetic where we reverse the sign before bit shifting. This results
|
246
|
+
* in an nfree of 0 using index 0 and anything non-zero staying non-zero.
|
247
|
+
* This is exploiting 0 and -0 being the same in two's complement. When
|
248
|
+
* we're done, we just need to flip the sign back over again for a
|
249
|
+
* positive index.
|
250
|
+
*/
|
251
|
+
index = -((-nfree) >> blocklist_shift);
|
252
|
+
|
253
|
+
if (nfree == 0)
|
254
|
+
Assert(index == 0);
|
255
|
+
else
|
256
|
+
Assert(index >= 1 && index < SLAB_BLOCKLIST_COUNT);
|
257
|
+
|
258
|
+
return index;
|
259
|
+
}
|
260
|
+
|
261
|
+
/*
|
262
|
+
* SlabFindNextBlockListIndex
|
263
|
+
* Search blocklist for blocks which have free chunks and return the
|
264
|
+
* index of the blocklist found containing at least 1 block with free
|
265
|
+
* chunks. If no block can be found we return 0.
|
266
|
+
*
|
267
|
+
* Note: We give priority to fuller blocks so that these are filled before
|
268
|
+
* emptier blocks. This is done to increase the chances that mostly-empty
|
269
|
+
* blocks will eventually become completely empty so they can be free'd.
|
270
|
+
*/
|
271
|
+
static int32
|
272
|
+
SlabFindNextBlockListIndex(SlabContext *slab)
|
273
|
+
{
|
274
|
+
/* start at 1 as blocklist[0] is for full blocks. */
|
275
|
+
for (int i = 1; i < SLAB_BLOCKLIST_COUNT; i++)
|
276
|
+
{
|
277
|
+
/* return the first found non-empty index */
|
278
|
+
if (!dlist_is_empty(&slab->blocklist[i]))
|
279
|
+
return i;
|
280
|
+
}
|
281
|
+
|
282
|
+
/* no blocks with free space */
|
283
|
+
return 0;
|
284
|
+
}
|
285
|
+
|
286
|
+
/*
|
287
|
+
* SlabGetNextFreeChunk
|
288
|
+
* Return the next free chunk in block and update the block to account
|
289
|
+
* for the returned chunk now being used.
|
290
|
+
*/
|
291
|
+
static inline MemoryChunk *
|
292
|
+
SlabGetNextFreeChunk(SlabContext *slab, SlabBlock *block)
|
293
|
+
{
|
294
|
+
MemoryChunk *chunk;
|
295
|
+
|
296
|
+
Assert(block->nfree > 0);
|
297
|
+
|
298
|
+
if (block->freehead != NULL)
|
299
|
+
{
|
300
|
+
chunk = block->freehead;
|
301
|
+
|
302
|
+
/*
|
303
|
+
* Pop the chunk from the linked list of free chunks. The pointer to
|
304
|
+
* the next free chunk is stored in the chunk itself.
|
305
|
+
*/
|
306
|
+
VALGRIND_MAKE_MEM_DEFINED(SlabChunkGetPointer(chunk), sizeof(MemoryChunk *));
|
307
|
+
block->freehead = *(MemoryChunk **) SlabChunkGetPointer(chunk);
|
308
|
+
|
309
|
+
/* check nothing stomped on the free chunk's memory */
|
310
|
+
Assert(block->freehead == NULL ||
|
311
|
+
(block->freehead >= SlabBlockGetChunk(slab, block, 0) &&
|
312
|
+
block->freehead <= SlabBlockGetChunk(slab, block, slab->chunksPerBlock - 1) &&
|
313
|
+
SlabChunkMod(slab, block, block->freehead) == 0));
|
314
|
+
}
|
315
|
+
else
|
316
|
+
{
|
317
|
+
Assert(block->nunused > 0);
|
318
|
+
|
319
|
+
chunk = block->unused;
|
320
|
+
block->unused = (MemoryChunk *) (((char *) block->unused) + slab->fullChunkSize);
|
321
|
+
block->nunused--;
|
322
|
+
}
|
323
|
+
|
324
|
+
block->nfree--;
|
325
|
+
|
326
|
+
return chunk;
|
327
|
+
}
|
328
|
+
|
329
|
+
/*
|
330
|
+
* SlabContextCreate
|
331
|
+
* Create a new Slab context.
|
332
|
+
*
|
333
|
+
* parent: parent context, or NULL if top-level context
|
334
|
+
* name: name of context (must be statically allocated)
|
335
|
+
* blockSize: allocation block size
|
336
|
+
* chunkSize: allocation chunk size
|
337
|
+
*
|
338
|
+
* The Slab_CHUNKHDRSZ + MAXALIGN(chunkSize + 1) may not exceed
|
339
|
+
* MEMORYCHUNK_MAX_VALUE.
|
340
|
+
* 'blockSize' may not exceed MEMORYCHUNK_MAX_BLOCKOFFSET.
|
341
|
+
*/
|
342
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
343
|
+
#else
|
344
|
+
#endif
|
345
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
346
|
+
#endif
|
347
|
+
|
348
|
+
/*
|
349
|
+
* SlabReset
|
350
|
+
* Frees all memory which is allocated in the given set.
|
351
|
+
*
|
352
|
+
* The code simply frees all the blocks in the context - we don't keep any
|
353
|
+
* keeper blocks or anything like that.
|
354
|
+
*/
|
355
|
+
void
|
356
|
+
SlabReset(MemoryContext context)
|
357
|
+
{
|
358
|
+
SlabContext *slab = (SlabContext *) context;
|
359
|
+
dlist_mutable_iter miter;
|
360
|
+
int i;
|
361
|
+
|
362
|
+
Assert(SlabIsValid(slab));
|
363
|
+
|
364
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
365
|
+
/* Check for corruption and leaks before freeing */
|
366
|
+
SlabCheck(context);
|
367
|
+
#endif
|
368
|
+
|
369
|
+
/* release any retained empty blocks */
|
370
|
+
dclist_foreach_modify(miter, &slab->emptyblocks)
|
371
|
+
{
|
372
|
+
SlabBlock *block = dlist_container(SlabBlock, node, miter.cur);
|
373
|
+
|
374
|
+
dclist_delete_from(&slab->emptyblocks, miter.cur);
|
375
|
+
|
376
|
+
#ifdef CLOBBER_FREED_MEMORY
|
377
|
+
wipe_mem(block, slab->blockSize);
|
378
|
+
#endif
|
379
|
+
free(block);
|
380
|
+
context->mem_allocated -= slab->blockSize;
|
381
|
+
}
|
382
|
+
|
383
|
+
/* walk over blocklist and free the blocks */
|
384
|
+
for (i = 0; i < SLAB_BLOCKLIST_COUNT; i++)
|
385
|
+
{
|
386
|
+
dlist_foreach_modify(miter, &slab->blocklist[i])
|
387
|
+
{
|
388
|
+
SlabBlock *block = dlist_container(SlabBlock, node, miter.cur);
|
389
|
+
|
390
|
+
dlist_delete(miter.cur);
|
391
|
+
|
392
|
+
#ifdef CLOBBER_FREED_MEMORY
|
393
|
+
wipe_mem(block, slab->blockSize);
|
394
|
+
#endif
|
395
|
+
free(block);
|
396
|
+
context->mem_allocated -= slab->blockSize;
|
397
|
+
}
|
398
|
+
}
|
399
|
+
|
400
|
+
slab->curBlocklistIndex = 0;
|
401
|
+
|
402
|
+
Assert(context->mem_allocated == 0);
|
403
|
+
}
|
404
|
+
|
405
|
+
/*
|
406
|
+
* SlabDelete
|
407
|
+
* Free all memory which is allocated in the given context.
|
408
|
+
*/
|
409
|
+
void
|
410
|
+
SlabDelete(MemoryContext context)
|
411
|
+
{
|
412
|
+
/* Reset to release all the SlabBlocks */
|
413
|
+
SlabReset(context);
|
414
|
+
/* And free the context header */
|
415
|
+
free(context);
|
416
|
+
}
|
417
|
+
|
418
|
+
/*
|
419
|
+
* Small helper for allocating a new chunk from a chunk, to avoid duplicating
|
420
|
+
* the code between SlabAlloc() and SlabAllocFromNewBlock().
|
421
|
+
*/
|
422
|
+
static inline void *
|
423
|
+
SlabAllocSetupNewChunk(MemoryContext context, SlabBlock *block,
|
424
|
+
MemoryChunk *chunk, Size size)
|
425
|
+
{
|
426
|
+
SlabContext *slab = (SlabContext *) context;
|
427
|
+
|
428
|
+
/*
|
429
|
+
* Check that the chunk pointer is actually somewhere on the block and is
|
430
|
+
* aligned as expected.
|
431
|
+
*/
|
432
|
+
Assert(chunk >= SlabBlockGetChunk(slab, block, 0));
|
433
|
+
Assert(chunk <= SlabBlockGetChunk(slab, block, slab->chunksPerBlock - 1));
|
434
|
+
Assert(SlabChunkMod(slab, block, chunk) == 0);
|
435
|
+
|
436
|
+
/* Prepare to initialize the chunk header. */
|
437
|
+
VALGRIND_MAKE_MEM_UNDEFINED(chunk, Slab_CHUNKHDRSZ);
|
438
|
+
|
439
|
+
MemoryChunkSetHdrMask(chunk, block, MAXALIGN(slab->chunkSize), MCTX_SLAB_ID);
|
440
|
+
|
441
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
442
|
+
/* slab mark to catch clobber of "unused" space */
|
443
|
+
Assert(slab->chunkSize < (slab->fullChunkSize - Slab_CHUNKHDRSZ));
|
444
|
+
set_sentinel(MemoryChunkGetPointer(chunk), size);
|
445
|
+
VALGRIND_MAKE_MEM_NOACCESS(((char *) chunk) + Slab_CHUNKHDRSZ +
|
446
|
+
slab->chunkSize,
|
447
|
+
slab->fullChunkSize -
|
448
|
+
(slab->chunkSize + Slab_CHUNKHDRSZ));
|
449
|
+
#endif
|
450
|
+
|
451
|
+
#ifdef RANDOMIZE_ALLOCATED_MEMORY
|
452
|
+
/* fill the allocated space with junk */
|
453
|
+
randomize_mem((char *) MemoryChunkGetPointer(chunk), size);
|
454
|
+
#endif
|
455
|
+
|
456
|
+
/* Disallow access to the chunk header. */
|
457
|
+
VALGRIND_MAKE_MEM_NOACCESS(chunk, Slab_CHUNKHDRSZ);
|
458
|
+
|
459
|
+
return MemoryChunkGetPointer(chunk);
|
460
|
+
}
|
461
|
+
|
462
|
+
pg_noinline
|
463
|
+
static void *
|
464
|
+
SlabAllocFromNewBlock(MemoryContext context, Size size, int flags)
|
465
|
+
{
|
466
|
+
SlabContext *slab = (SlabContext *) context;
|
467
|
+
SlabBlock *block;
|
468
|
+
MemoryChunk *chunk;
|
469
|
+
dlist_head *blocklist;
|
470
|
+
int blocklist_idx;
|
471
|
+
|
472
|
+
/* to save allocating a new one, first check the empty blocks list */
|
473
|
+
if (dclist_count(&slab->emptyblocks) > 0)
|
474
|
+
{
|
475
|
+
dlist_node *node = dclist_pop_head_node(&slab->emptyblocks);
|
476
|
+
|
477
|
+
block = dlist_container(SlabBlock, node, node);
|
478
|
+
|
479
|
+
/*
|
480
|
+
* SlabFree() should have left this block in a valid state with all
|
481
|
+
* chunks free. Ensure that's the case.
|
482
|
+
*/
|
483
|
+
Assert(block->nfree == slab->chunksPerBlock);
|
484
|
+
|
485
|
+
/* fetch the next chunk from this block */
|
486
|
+
chunk = SlabGetNextFreeChunk(slab, block);
|
487
|
+
}
|
488
|
+
else
|
489
|
+
{
|
490
|
+
block = (SlabBlock *) malloc(slab->blockSize);
|
491
|
+
|
492
|
+
if (unlikely(block == NULL))
|
493
|
+
return MemoryContextAllocationFailure(context, size, flags);
|
494
|
+
|
495
|
+
block->slab = slab;
|
496
|
+
context->mem_allocated += slab->blockSize;
|
497
|
+
|
498
|
+
/* use the first chunk in the new block */
|
499
|
+
chunk = SlabBlockGetChunk(slab, block, 0);
|
500
|
+
|
501
|
+
block->nfree = slab->chunksPerBlock - 1;
|
502
|
+
block->unused = SlabBlockGetChunk(slab, block, 1);
|
503
|
+
block->freehead = NULL;
|
504
|
+
block->nunused = slab->chunksPerBlock - 1;
|
505
|
+
}
|
506
|
+
|
507
|
+
/* find the blocklist element for storing blocks with 1 used chunk */
|
508
|
+
blocklist_idx = SlabBlocklistIndex(slab, block->nfree);
|
509
|
+
blocklist = &slab->blocklist[blocklist_idx];
|
510
|
+
|
511
|
+
/* this better be empty. We just added a block thinking it was */
|
512
|
+
Assert(dlist_is_empty(blocklist));
|
513
|
+
|
514
|
+
dlist_push_head(blocklist, &block->node);
|
515
|
+
|
516
|
+
slab->curBlocklistIndex = blocklist_idx;
|
517
|
+
|
518
|
+
return SlabAllocSetupNewChunk(context, block, chunk, size);
|
519
|
+
}
|
520
|
+
|
521
|
+
/*
|
522
|
+
* SlabAllocInvalidSize
|
523
|
+
* Handle raising an ERROR for an invalid size request. We don't do this
|
524
|
+
* in slab alloc as calling the elog functions would force the compiler
|
525
|
+
* to setup the stack frame in SlabAlloc. For performance reasons, we
|
526
|
+
* want to avoid that.
|
527
|
+
*/
|
528
|
+
pg_noinline
|
529
|
+
static void
|
530
|
+
pg_attribute_noreturn()
|
531
|
+
SlabAllocInvalidSize(MemoryContext context, Size size)
|
532
|
+
{
|
533
|
+
SlabContext *slab = (SlabContext *) context;
|
534
|
+
|
535
|
+
elog(ERROR, "unexpected alloc chunk size %zu (expected %u)", size,
|
536
|
+
slab->chunkSize);
|
537
|
+
}
|
538
|
+
|
539
|
+
/*
|
540
|
+
* SlabAlloc
|
541
|
+
* Returns a pointer to a newly allocated memory chunk or raises an ERROR
|
542
|
+
* on allocation failure, or returns NULL when flags contains
|
543
|
+
* MCXT_ALLOC_NO_OOM. 'size' must be the same size as was specified
|
544
|
+
* during SlabContextCreate().
|
545
|
+
*
|
546
|
+
* This function should only contain the most common code paths. Everything
|
547
|
+
* else should be in pg_noinline helper functions, thus avoiding the overhead
|
548
|
+
* of creating a stack frame for the common cases. Allocating memory is often
|
549
|
+
* a bottleneck in many workloads, so avoiding stack frame setup is
|
550
|
+
* worthwhile. Helper functions should always directly return the newly
|
551
|
+
* allocated memory so that we can just return that address directly as a tail
|
552
|
+
* call.
|
553
|
+
*/
|
554
|
+
void *
|
555
|
+
SlabAlloc(MemoryContext context, Size size, int flags)
|
556
|
+
{
|
557
|
+
SlabContext *slab = (SlabContext *) context;
|
558
|
+
SlabBlock *block;
|
559
|
+
MemoryChunk *chunk;
|
560
|
+
|
561
|
+
Assert(SlabIsValid(slab));
|
562
|
+
|
563
|
+
/* sanity check that this is pointing to a valid blocklist */
|
564
|
+
Assert(slab->curBlocklistIndex >= 0);
|
565
|
+
Assert(slab->curBlocklistIndex <= SlabBlocklistIndex(slab, slab->chunksPerBlock));
|
566
|
+
|
567
|
+
/*
|
568
|
+
* Make sure we only allow correct request size. This doubles as the
|
569
|
+
* MemoryContextCheckSize check.
|
570
|
+
*/
|
571
|
+
if (unlikely(size != slab->chunkSize))
|
572
|
+
SlabAllocInvalidSize(context, size);
|
573
|
+
|
574
|
+
if (unlikely(slab->curBlocklistIndex == 0))
|
575
|
+
{
|
576
|
+
/*
|
577
|
+
* Handle the case when there are no partially filled blocks
|
578
|
+
* available. This happens either when the last allocation took the
|
579
|
+
* last chunk in the block, or when SlabFree() free'd the final block.
|
580
|
+
*/
|
581
|
+
return SlabAllocFromNewBlock(context, size, flags);
|
582
|
+
}
|
583
|
+
else
|
584
|
+
{
|
585
|
+
dlist_head *blocklist = &slab->blocklist[slab->curBlocklistIndex];
|
586
|
+
int new_blocklist_idx;
|
587
|
+
|
588
|
+
Assert(!dlist_is_empty(blocklist));
|
589
|
+
|
590
|
+
/* grab the block from the blocklist */
|
591
|
+
block = dlist_head_element(SlabBlock, node, blocklist);
|
592
|
+
|
593
|
+
/* make sure we actually got a valid block, with matching nfree */
|
594
|
+
Assert(block != NULL);
|
595
|
+
Assert(slab->curBlocklistIndex == SlabBlocklistIndex(slab, block->nfree));
|
596
|
+
Assert(block->nfree > 0);
|
597
|
+
|
598
|
+
/* fetch the next chunk from this block */
|
599
|
+
chunk = SlabGetNextFreeChunk(slab, block);
|
600
|
+
|
601
|
+
/* get the new blocklist index based on the new free chunk count */
|
602
|
+
new_blocklist_idx = SlabBlocklistIndex(slab, block->nfree);
|
603
|
+
|
604
|
+
/*
|
605
|
+
* Handle the case where the blocklist index changes. This also deals
|
606
|
+
* with blocks becoming full as only full blocks go at index 0.
|
607
|
+
*/
|
608
|
+
if (unlikely(slab->curBlocklistIndex != new_blocklist_idx))
|
609
|
+
{
|
610
|
+
dlist_delete_from(blocklist, &block->node);
|
611
|
+
dlist_push_head(&slab->blocklist[new_blocklist_idx], &block->node);
|
612
|
+
|
613
|
+
if (dlist_is_empty(blocklist))
|
614
|
+
slab->curBlocklistIndex = SlabFindNextBlockListIndex(slab);
|
615
|
+
}
|
616
|
+
}
|
617
|
+
|
618
|
+
return SlabAllocSetupNewChunk(context, block, chunk, size);
|
619
|
+
}
|
620
|
+
|
621
|
+
/*
|
622
|
+
* SlabFree
|
623
|
+
* Frees allocated memory; memory is removed from the slab.
|
624
|
+
*/
|
625
|
+
void
|
626
|
+
SlabFree(void *pointer)
|
627
|
+
{
|
628
|
+
MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
|
629
|
+
SlabBlock *block;
|
630
|
+
SlabContext *slab;
|
631
|
+
int curBlocklistIdx;
|
632
|
+
int newBlocklistIdx;
|
633
|
+
|
634
|
+
/* Allow access to the chunk header. */
|
635
|
+
VALGRIND_MAKE_MEM_DEFINED(chunk, Slab_CHUNKHDRSZ);
|
636
|
+
|
637
|
+
block = MemoryChunkGetBlock(chunk);
|
638
|
+
|
639
|
+
/*
|
640
|
+
* For speed reasons we just Assert that the referenced block is good.
|
641
|
+
* Future field experience may show that this Assert had better become a
|
642
|
+
* regular runtime test-and-elog check.
|
643
|
+
*/
|
644
|
+
Assert(SlabBlockIsValid(block));
|
645
|
+
slab = block->slab;
|
646
|
+
|
647
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
648
|
+
/* Test for someone scribbling on unused space in chunk */
|
649
|
+
Assert(slab->chunkSize < (slab->fullChunkSize - Slab_CHUNKHDRSZ));
|
650
|
+
if (!sentinel_ok(pointer, slab->chunkSize))
|
651
|
+
elog(WARNING, "detected write past chunk end in %s %p",
|
652
|
+
slab->header.name, chunk);
|
653
|
+
#endif
|
654
|
+
|
655
|
+
/* push this chunk onto the head of the block's free list */
|
656
|
+
*(MemoryChunk **) pointer = block->freehead;
|
657
|
+
block->freehead = chunk;
|
658
|
+
|
659
|
+
block->nfree++;
|
660
|
+
|
661
|
+
Assert(block->nfree > 0);
|
662
|
+
Assert(block->nfree <= slab->chunksPerBlock);
|
663
|
+
|
664
|
+
#ifdef CLOBBER_FREED_MEMORY
|
665
|
+
/* don't wipe the free list MemoryChunk pointer stored in the chunk */
|
666
|
+
wipe_mem((char *) pointer + sizeof(MemoryChunk *),
|
667
|
+
slab->chunkSize - sizeof(MemoryChunk *));
|
668
|
+
#endif
|
669
|
+
|
670
|
+
curBlocklistIdx = SlabBlocklistIndex(slab, block->nfree - 1);
|
671
|
+
newBlocklistIdx = SlabBlocklistIndex(slab, block->nfree);
|
672
|
+
|
673
|
+
/*
|
674
|
+
* Check if the block needs to be moved to another element on the
|
675
|
+
* blocklist based on it now having 1 more free chunk.
|
676
|
+
*/
|
677
|
+
if (unlikely(curBlocklistIdx != newBlocklistIdx))
|
678
|
+
{
|
679
|
+
/* do the move */
|
680
|
+
dlist_delete_from(&slab->blocklist[curBlocklistIdx], &block->node);
|
681
|
+
dlist_push_head(&slab->blocklist[newBlocklistIdx], &block->node);
|
682
|
+
|
683
|
+
/*
|
684
|
+
* The blocklist[curBlocklistIdx] may now be empty or we may now be
|
685
|
+
* able to use a lower-element blocklist. We'll need to redetermine
|
686
|
+
* what the slab->curBlocklistIndex is if the current blocklist was
|
687
|
+
* changed or if a lower element one was changed. We must ensure we
|
688
|
+
* use the list with the fullest block(s).
|
689
|
+
*/
|
690
|
+
if (slab->curBlocklistIndex >= curBlocklistIdx)
|
691
|
+
{
|
692
|
+
slab->curBlocklistIndex = SlabFindNextBlockListIndex(slab);
|
693
|
+
|
694
|
+
/*
|
695
|
+
* We know there must be a block with at least 1 unused chunk as
|
696
|
+
* we just pfree'd one. Ensure curBlocklistIndex reflects this.
|
697
|
+
*/
|
698
|
+
Assert(slab->curBlocklistIndex > 0);
|
699
|
+
}
|
700
|
+
}
|
701
|
+
|
702
|
+
/* Handle when a block becomes completely empty */
|
703
|
+
if (unlikely(block->nfree == slab->chunksPerBlock))
|
704
|
+
{
|
705
|
+
/* remove the block */
|
706
|
+
dlist_delete_from(&slab->blocklist[newBlocklistIdx], &block->node);
|
707
|
+
|
708
|
+
/*
|
709
|
+
* To avoid thrashing malloc/free, we keep a list of empty blocks that
|
710
|
+
* we can reuse again instead of having to malloc a new one.
|
711
|
+
*/
|
712
|
+
if (dclist_count(&slab->emptyblocks) < SLAB_MAXIMUM_EMPTY_BLOCKS)
|
713
|
+
dclist_push_head(&slab->emptyblocks, &block->node);
|
714
|
+
else
|
715
|
+
{
|
716
|
+
/*
|
717
|
+
* When we have enough empty blocks stored already, we actually
|
718
|
+
* free the block.
|
719
|
+
*/
|
720
|
+
#ifdef CLOBBER_FREED_MEMORY
|
721
|
+
wipe_mem(block, slab->blockSize);
|
722
|
+
#endif
|
723
|
+
free(block);
|
724
|
+
slab->header.mem_allocated -= slab->blockSize;
|
725
|
+
}
|
726
|
+
|
727
|
+
/*
|
728
|
+
* Check if we need to reset the blocklist index. This is required
|
729
|
+
* when the blocklist this block is on has become completely empty.
|
730
|
+
*/
|
731
|
+
if (slab->curBlocklistIndex == newBlocklistIdx &&
|
732
|
+
dlist_is_empty(&slab->blocklist[newBlocklistIdx]))
|
733
|
+
slab->curBlocklistIndex = SlabFindNextBlockListIndex(slab);
|
734
|
+
}
|
735
|
+
}
|
736
|
+
|
737
|
+
/*
|
738
|
+
* SlabRealloc
|
739
|
+
* Change the allocated size of a chunk.
|
740
|
+
*
|
741
|
+
* As Slab is designed for allocating equally-sized chunks of memory, it can't
|
742
|
+
* do an actual chunk size change. We try to be gentle and allow calls with
|
743
|
+
* exactly the same size, as in that case we can simply return the same
|
744
|
+
* chunk. When the size differs, we throw an error.
|
745
|
+
*
|
746
|
+
* We could also allow requests with size < chunkSize. That however seems
|
747
|
+
* rather pointless - Slab is meant for chunks of constant size, and moreover
|
748
|
+
* realloc is usually used to enlarge the chunk.
|
749
|
+
*/
|
750
|
+
void *
|
751
|
+
SlabRealloc(void *pointer, Size size, int flags)
|
752
|
+
{
|
753
|
+
MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
|
754
|
+
SlabBlock *block;
|
755
|
+
SlabContext *slab;
|
756
|
+
|
757
|
+
/* Allow access to the chunk header. */
|
758
|
+
VALGRIND_MAKE_MEM_DEFINED(chunk, Slab_CHUNKHDRSZ);
|
759
|
+
|
760
|
+
block = MemoryChunkGetBlock(chunk);
|
761
|
+
|
762
|
+
/* Disallow access to the chunk header. */
|
763
|
+
VALGRIND_MAKE_MEM_NOACCESS(chunk, Slab_CHUNKHDRSZ);
|
764
|
+
|
765
|
+
/*
|
766
|
+
* Try to verify that we have a sane block pointer: the block header
|
767
|
+
* should reference a slab context. (We use a test-and-elog, not just
|
768
|
+
* Assert, because it seems highly likely that we're here in error in the
|
769
|
+
* first place.)
|
770
|
+
*/
|
771
|
+
if (!SlabBlockIsValid(block))
|
772
|
+
elog(ERROR, "could not find block containing chunk %p", chunk);
|
773
|
+
slab = block->slab;
|
774
|
+
|
775
|
+
/* can't do actual realloc with slab, but let's try to be gentle */
|
776
|
+
if (size == slab->chunkSize)
|
777
|
+
return pointer;
|
778
|
+
|
779
|
+
elog(ERROR, "slab allocator does not support realloc()");
|
780
|
+
return NULL; /* keep compiler quiet */
|
781
|
+
}
|
782
|
+
|
783
|
+
/*
|
784
|
+
* SlabGetChunkContext
|
785
|
+
* Return the MemoryContext that 'pointer' belongs to.
|
786
|
+
*/
|
787
|
+
MemoryContext
|
788
|
+
SlabGetChunkContext(void *pointer)
|
789
|
+
{
|
790
|
+
MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
|
791
|
+
SlabBlock *block;
|
792
|
+
|
793
|
+
/* Allow access to the chunk header. */
|
794
|
+
VALGRIND_MAKE_MEM_DEFINED(chunk, Slab_CHUNKHDRSZ);
|
795
|
+
|
796
|
+
block = MemoryChunkGetBlock(chunk);
|
797
|
+
|
798
|
+
/* Disallow access to the chunk header. */
|
799
|
+
VALGRIND_MAKE_MEM_NOACCESS(chunk, Slab_CHUNKHDRSZ);
|
800
|
+
|
801
|
+
Assert(SlabBlockIsValid(block));
|
802
|
+
|
803
|
+
return &block->slab->header;
|
804
|
+
}
|
805
|
+
|
806
|
+
/*
|
807
|
+
* SlabGetChunkSpace
|
808
|
+
* Given a currently-allocated chunk, determine the total space
|
809
|
+
* it occupies (including all memory-allocation overhead).
|
810
|
+
*/
|
811
|
+
Size
|
812
|
+
SlabGetChunkSpace(void *pointer)
|
813
|
+
{
|
814
|
+
MemoryChunk *chunk = PointerGetMemoryChunk(pointer);
|
815
|
+
SlabBlock *block;
|
816
|
+
SlabContext *slab;
|
817
|
+
|
818
|
+
/* Allow access to the chunk header. */
|
819
|
+
VALGRIND_MAKE_MEM_DEFINED(chunk, Slab_CHUNKHDRSZ);
|
820
|
+
|
821
|
+
block = MemoryChunkGetBlock(chunk);
|
822
|
+
|
823
|
+
/* Disallow access to the chunk header. */
|
824
|
+
VALGRIND_MAKE_MEM_NOACCESS(chunk, Slab_CHUNKHDRSZ);
|
825
|
+
|
826
|
+
Assert(SlabBlockIsValid(block));
|
827
|
+
slab = block->slab;
|
828
|
+
|
829
|
+
return slab->fullChunkSize;
|
830
|
+
}
|
831
|
+
|
832
|
+
/*
|
833
|
+
* SlabIsEmpty
|
834
|
+
* Is the slab empty of any allocated space?
|
835
|
+
*/
|
836
|
+
bool
|
837
|
+
SlabIsEmpty(MemoryContext context)
|
838
|
+
{
|
839
|
+
Assert(SlabIsValid((SlabContext *) context));
|
840
|
+
|
841
|
+
return (context->mem_allocated == 0);
|
842
|
+
}
|
843
|
+
|
844
|
+
/*
|
845
|
+
* SlabStats
|
846
|
+
* Compute stats about memory consumption of a Slab context.
|
847
|
+
*
|
848
|
+
* printfunc: if not NULL, pass a human-readable stats string to this.
|
849
|
+
* passthru: pass this pointer through to printfunc.
|
850
|
+
* totals: if not NULL, add stats about this context into *totals.
|
851
|
+
* print_to_stderr: print stats to stderr if true, elog otherwise.
|
852
|
+
*/
|
853
|
+
void
|
854
|
+
SlabStats(MemoryContext context,
|
855
|
+
MemoryStatsPrintFunc printfunc, void *passthru,
|
856
|
+
MemoryContextCounters *totals,
|
857
|
+
bool print_to_stderr)
|
858
|
+
{
|
859
|
+
SlabContext *slab = (SlabContext *) context;
|
860
|
+
Size nblocks = 0;
|
861
|
+
Size freechunks = 0;
|
862
|
+
Size totalspace;
|
863
|
+
Size freespace = 0;
|
864
|
+
int i;
|
865
|
+
|
866
|
+
Assert(SlabIsValid(slab));
|
867
|
+
|
868
|
+
/* Include context header in totalspace */
|
869
|
+
totalspace = Slab_CONTEXT_HDRSZ(slab->chunksPerBlock);
|
870
|
+
|
871
|
+
/* Add the space consumed by blocks in the emptyblocks list */
|
872
|
+
totalspace += dclist_count(&slab->emptyblocks) * slab->blockSize;
|
873
|
+
|
874
|
+
for (i = 0; i < SLAB_BLOCKLIST_COUNT; i++)
|
875
|
+
{
|
876
|
+
dlist_iter iter;
|
877
|
+
|
878
|
+
dlist_foreach(iter, &slab->blocklist[i])
|
879
|
+
{
|
880
|
+
SlabBlock *block = dlist_container(SlabBlock, node, iter.cur);
|
881
|
+
|
882
|
+
nblocks++;
|
883
|
+
totalspace += slab->blockSize;
|
884
|
+
freespace += slab->fullChunkSize * block->nfree;
|
885
|
+
freechunks += block->nfree;
|
886
|
+
}
|
887
|
+
}
|
888
|
+
|
889
|
+
if (printfunc)
|
890
|
+
{
|
891
|
+
char stats_string[200];
|
892
|
+
|
893
|
+
/* XXX should we include free chunks on empty blocks? */
|
894
|
+
snprintf(stats_string, sizeof(stats_string),
|
895
|
+
"%zu total in %zu blocks; %u empty blocks; %zu free (%zu chunks); %zu used",
|
896
|
+
totalspace, nblocks, dclist_count(&slab->emptyblocks),
|
897
|
+
freespace, freechunks, totalspace - freespace);
|
898
|
+
printfunc(context, passthru, stats_string, print_to_stderr);
|
899
|
+
}
|
900
|
+
|
901
|
+
if (totals)
|
902
|
+
{
|
903
|
+
totals->nblocks += nblocks;
|
904
|
+
totals->freechunks += freechunks;
|
905
|
+
totals->totalspace += totalspace;
|
906
|
+
totals->freespace += freespace;
|
907
|
+
}
|
908
|
+
}
|
909
|
+
|
910
|
+
|
911
|
+
#ifdef MEMORY_CONTEXT_CHECKING
|
912
|
+
|
913
|
+
/*
|
914
|
+
* SlabCheck
|
915
|
+
* Walk through all blocks looking for inconsistencies.
|
916
|
+
*
|
917
|
+
* NOTE: report errors as WARNING, *not* ERROR or FATAL. Otherwise you'll
|
918
|
+
* find yourself in an infinite loop when trouble occurs, because this
|
919
|
+
* routine will be entered again when elog cleanup tries to release memory!
|
920
|
+
*/
|
921
|
+
void
|
922
|
+
SlabCheck(MemoryContext context)
|
923
|
+
{
|
924
|
+
SlabContext *slab = (SlabContext *) context;
|
925
|
+
int i;
|
926
|
+
int nblocks = 0;
|
927
|
+
const char *name = slab->header.name;
|
928
|
+
dlist_iter iter;
|
929
|
+
|
930
|
+
Assert(SlabIsValid(slab));
|
931
|
+
Assert(slab->chunksPerBlock > 0);
|
932
|
+
|
933
|
+
/*
|
934
|
+
* Have a look at the empty blocks. These should have all their chunks
|
935
|
+
* marked as free. Ensure that's the case.
|
936
|
+
*/
|
937
|
+
dclist_foreach(iter, &slab->emptyblocks)
|
938
|
+
{
|
939
|
+
SlabBlock *block = dlist_container(SlabBlock, node, iter.cur);
|
940
|
+
|
941
|
+
if (block->nfree != slab->chunksPerBlock)
|
942
|
+
elog(WARNING, "problem in slab %s: empty block %p should have %d free chunks but has %d chunks free",
|
943
|
+
name, block, slab->chunksPerBlock, block->nfree);
|
944
|
+
}
|
945
|
+
|
946
|
+
/* walk the non-empty block lists */
|
947
|
+
for (i = 0; i < SLAB_BLOCKLIST_COUNT; i++)
|
948
|
+
{
|
949
|
+
int j,
|
950
|
+
nfree;
|
951
|
+
|
952
|
+
/* walk all blocks on this blocklist */
|
953
|
+
dlist_foreach(iter, &slab->blocklist[i])
|
954
|
+
{
|
955
|
+
SlabBlock *block = dlist_container(SlabBlock, node, iter.cur);
|
956
|
+
MemoryChunk *cur_chunk;
|
957
|
+
|
958
|
+
/*
|
959
|
+
* Make sure the number of free chunks (in the block header)
|
960
|
+
* matches the position in the blocklist.
|
961
|
+
*/
|
962
|
+
if (SlabBlocklistIndex(slab, block->nfree) != i)
|
963
|
+
elog(WARNING, "problem in slab %s: block %p is on blocklist %d but should be on blocklist %d",
|
964
|
+
name, block, i, SlabBlocklistIndex(slab, block->nfree));
|
965
|
+
|
966
|
+
/* make sure the block is not empty */
|
967
|
+
if (block->nfree >= slab->chunksPerBlock)
|
968
|
+
elog(WARNING, "problem in slab %s: empty block %p incorrectly stored on blocklist element %d",
|
969
|
+
name, block, i);
|
970
|
+
|
971
|
+
/* make sure the slab pointer correctly points to this context */
|
972
|
+
if (block->slab != slab)
|
973
|
+
elog(WARNING, "problem in slab %s: bogus slab link in block %p",
|
974
|
+
name, block);
|
975
|
+
|
976
|
+
/* reset the array of free chunks for this block */
|
977
|
+
memset(slab->isChunkFree, 0, (slab->chunksPerBlock * sizeof(bool)));
|
978
|
+
nfree = 0;
|
979
|
+
|
980
|
+
/* walk through the block's free list chunks */
|
981
|
+
cur_chunk = block->freehead;
|
982
|
+
while (cur_chunk != NULL)
|
983
|
+
{
|
984
|
+
int chunkidx = SlabChunkIndex(slab, block, cur_chunk);
|
985
|
+
|
986
|
+
/*
|
987
|
+
* Ensure the free list link points to something on the block
|
988
|
+
* at an address aligned according to the full chunk size.
|
989
|
+
*/
|
990
|
+
if (cur_chunk < SlabBlockGetChunk(slab, block, 0) ||
|
991
|
+
cur_chunk > SlabBlockGetChunk(slab, block, slab->chunksPerBlock - 1) ||
|
992
|
+
SlabChunkMod(slab, block, cur_chunk) != 0)
|
993
|
+
elog(WARNING, "problem in slab %s: bogus free list link %p in block %p",
|
994
|
+
name, cur_chunk, block);
|
995
|
+
|
996
|
+
/* count the chunk and mark it free on the free chunk array */
|
997
|
+
nfree++;
|
998
|
+
slab->isChunkFree[chunkidx] = true;
|
999
|
+
|
1000
|
+
/* read pointer of the next free chunk */
|
1001
|
+
VALGRIND_MAKE_MEM_DEFINED(MemoryChunkGetPointer(cur_chunk), sizeof(MemoryChunk *));
|
1002
|
+
cur_chunk = *(MemoryChunk **) SlabChunkGetPointer(cur_chunk);
|
1003
|
+
}
|
1004
|
+
|
1005
|
+
/* check that the unused pointer matches what nunused claims */
|
1006
|
+
if (SlabBlockGetChunk(slab, block, slab->chunksPerBlock - block->nunused) !=
|
1007
|
+
block->unused)
|
1008
|
+
elog(WARNING, "problem in slab %s: mismatch detected between nunused chunks and unused pointer in block %p",
|
1009
|
+
name, block);
|
1010
|
+
|
1011
|
+
/*
|
1012
|
+
* count the remaining free chunks that have yet to make it onto
|
1013
|
+
* the block's free list.
|
1014
|
+
*/
|
1015
|
+
cur_chunk = block->unused;
|
1016
|
+
for (j = 0; j < block->nunused; j++)
|
1017
|
+
{
|
1018
|
+
int chunkidx = SlabChunkIndex(slab, block, cur_chunk);
|
1019
|
+
|
1020
|
+
|
1021
|
+
/* count the chunk as free and mark it as so in the array */
|
1022
|
+
nfree++;
|
1023
|
+
if (chunkidx < slab->chunksPerBlock)
|
1024
|
+
slab->isChunkFree[chunkidx] = true;
|
1025
|
+
|
1026
|
+
/* move forward 1 chunk */
|
1027
|
+
cur_chunk = (MemoryChunk *) (((char *) cur_chunk) + slab->fullChunkSize);
|
1028
|
+
}
|
1029
|
+
|
1030
|
+
for (j = 0; j < slab->chunksPerBlock; j++)
|
1031
|
+
{
|
1032
|
+
if (!slab->isChunkFree[j])
|
1033
|
+
{
|
1034
|
+
MemoryChunk *chunk = SlabBlockGetChunk(slab, block, j);
|
1035
|
+
SlabBlock *chunkblock;
|
1036
|
+
|
1037
|
+
/* Allow access to the chunk header. */
|
1038
|
+
VALGRIND_MAKE_MEM_DEFINED(chunk, Slab_CHUNKHDRSZ);
|
1039
|
+
|
1040
|
+
chunkblock = (SlabBlock *) MemoryChunkGetBlock(chunk);
|
1041
|
+
|
1042
|
+
/* Disallow access to the chunk header. */
|
1043
|
+
VALGRIND_MAKE_MEM_NOACCESS(chunk, Slab_CHUNKHDRSZ);
|
1044
|
+
|
1045
|
+
/*
|
1046
|
+
* check the chunk's blockoffset correctly points back to
|
1047
|
+
* the block
|
1048
|
+
*/
|
1049
|
+
if (chunkblock != block)
|
1050
|
+
elog(WARNING, "problem in slab %s: bogus block link in block %p, chunk %p",
|
1051
|
+
name, block, chunk);
|
1052
|
+
|
1053
|
+
/* check the sentinel byte is intact */
|
1054
|
+
Assert(slab->chunkSize < (slab->fullChunkSize - Slab_CHUNKHDRSZ));
|
1055
|
+
if (!sentinel_ok(chunk, Slab_CHUNKHDRSZ + slab->chunkSize))
|
1056
|
+
elog(WARNING, "problem in slab %s: detected write past chunk end in block %p, chunk %p",
|
1057
|
+
name, block, chunk);
|
1058
|
+
}
|
1059
|
+
}
|
1060
|
+
|
1061
|
+
/*
|
1062
|
+
* Make sure we got the expected number of free chunks (as tracked
|
1063
|
+
* in the block header).
|
1064
|
+
*/
|
1065
|
+
if (nfree != block->nfree)
|
1066
|
+
elog(WARNING, "problem in slab %s: nfree in block %p is %d but %d chunk were found as free",
|
1067
|
+
name, block, block->nfree, nfree);
|
1068
|
+
|
1069
|
+
nblocks++;
|
1070
|
+
}
|
1071
|
+
}
|
1072
|
+
|
1073
|
+
/* the stored empty blocks are tracked in mem_allocated too */
|
1074
|
+
nblocks += dclist_count(&slab->emptyblocks);
|
1075
|
+
|
1076
|
+
Assert(nblocks * slab->blockSize == context->mem_allocated);
|
1077
|
+
}
|
1078
|
+
|
1079
|
+
#endif /* MEMORY_CONTEXT_CHECKING */
|