pax_global_header00006660000000000000000000000064141131511110014477gustar00rootroot0000000000000052 comment=c9b00aa8c093fa77e08b256bb09d33069a30db86 postgres-decoderbufs-1.8.0.Final/000077500000000000000000000000001411315111100166665ustar00rootroot00000000000000postgres-decoderbufs-1.8.0.Final/.clang-format000066400000000000000000000025661411315111100212520ustar00rootroot00000000000000--- # BasedOnStyle: Mozilla AccessModifierOffset: -2 ConstructorInitializerIndentWidth: 4 AlignEscapedNewlinesLeft: false AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: false AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakTemplateDeclarations: false AlwaysBreakBeforeMultilineStrings: false BreakBeforeBinaryOperators: false BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false BinPackParameters: true ColumnLimit: 80 ConstructorInitializerAllOnOneLineOrOnePerLine: true DerivePointerBinding: true ExperimentalAutoDetectBinPacking: false IndentCaseLabels: true MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCSpaceBeforeProtocolList: false PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakComment: 60 PenaltyBreakString: 1000 PenaltyBreakFirstLessLess: 120 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerBindsToType: true SpacesBeforeTrailingComments: 1 Cpp11BracedListStyle: false Standard: Cpp03 IndentWidth: 2 TabWidth: 8 UseTab: Never BreakBeforeBraces: Attach IndentFunctionDeclarationAfterType: false SpacesInParentheses: false SpacesInAngles: false SpaceInEmptyParentheses: false SpacesInCStyleCastParentheses: false SpaceAfterControlStatementKeyword: true SpaceBeforeAssignmentOperators: true ContinuationIndentWidth: 4 ... postgres-decoderbufs-1.8.0.Final/.gitignore000066400000000000000000000003561411315111100206620ustar00rootroot00000000000000# Object files *.o *.ko *.obj *.elf # Libraries *.lib *.a # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex # Eclipse .cproject .project .settings # Xcode *.xcodeprojpostgres-decoderbufs-1.8.0.Final/LICENSE000066400000000000000000000020721411315111100176740ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014 Xavier Stevens Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. postgres-decoderbufs-1.8.0.Final/Makefile000066400000000000000000000006771411315111100203400ustar00rootroot00000000000000MODULE_big = decoderbufs EXTENSION = decoderbufs PROTOBUF_C_CFLAGS = $(shell pkg-config --cflags 'libprotobuf-c >= 1.0.0') PROTOBUF_C_LDFLAGS = $(shell pkg-config --libs 'libprotobuf-c >= 1.0.0') PG_CPPFLAGS += -std=c11 $(PROTOBUF_C_CFLAGS) -I/usr/local/include $(C_PARAMS) SHLIB_LINK += $(PROTOBUF_C_LDFLAGS) OBJS = src/decoderbufs.o src/proto/pg_logicaldec.pb-c.o PG_CONFIG ?= pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) postgres-decoderbufs-1.8.0.Final/README.md000066400000000000000000000155231411315111100201530ustar00rootroot00000000000000[![License](https://img.shields.io/badge/license-MIT-brightgreen.svg?maxAge=2592000)](https://opensource.org/licenses/MIT) [![Version](https://img.shields.io/badge/version-0.1.0-brightgreen.svg?maxAge=2592000)]() [![User chat](https://img.shields.io/badge/chat-users-brightgreen.svg)](https://gitter.im/debezium/user) [![Developer chat](https://img.shields.io/badge/chat-devs-brightgreen.svg)](https://gitter.im/debezium/dev) [![Google Group](https://img.shields.io/:mailing%20list-debezium-brightgreen.svg)](https://groups.google.com/forum/#!forum/debezium) [![Stack Overflow](http://img.shields.io/:stack%20overflow-debezium-brightgreen.svg)](http://stackoverflow.com/questions/tagged/debezium) # Postgres Decoderbufs A PostgreSQL logical decoder output plugin to deliver data as [Protocol Buffers](https://developers.google.com/protocol-buffers), adapted for Debezium ## Thanks to - The original [Decoderbufs Project](https://github.com/xstevens/decoderbufs) on which this is based - [The PostgreSQL Team](https://postgresql.org) for adding [logical decoding](http://www.postgresql.org/docs/9.4/static/logicaldecoding.html) support ## Dependencies This code depends on the following libraries and requires them for compilation: * [PostgreSQL](http://www.postgresql.org) 9.6+ * [Protobuf-c](https://github.com/protobuf-c/protobuf-c) 1.2+ - used for data serialization * [PostGIS](http://www.postgis.net/) 2.1+ - used for Postgres geometric types support ## Building `postgres-decoderbufs` has to be built from source after installing required dependencies. The required dependencies are first PostgreSQL (for pg_config), PostgreSQL server development packages, protobuf-c for the Protocol Buffer support and some PostGIS development packages. ### Installing Dependencies #### Debian # Core build utilities apt-get update && apt-get install -f -y software-properties-common build-essential pkg-config git postgresql-server-dev-9.6 # PostGIS dependency apt-get install -f -y libproj-dev liblwgeom-dev # Protobuf-c dependency (requires a non-stable Debian repo) add-apt-repository "deb http://ftp.debian.org/debian testing main contrib" && apt-get update apt-get install -y libprotobuf-c-dev=1.2.1-1+b1 When updating the ProtoBuf definition, also install the ProtoBuf C compiler: apt-get install -y protobuf-c-compiler=1.2.* The above are taken from the Debezium [container images](https://github.com/debezium/docker-images). #### Other Linux distributions You just need to make sure the above software packages (_or some flavour thereof_) are installed for your distro. Note that the last step from the above sequence is only required for Debian to be able to install `libprotobuf-c-dev:1.2.1` ### Getting the source code If you have all of the above prerequisites installed, clone this git repo to build from source: git clone https://github.com/debezium/postgres-decoderbufs.git cd postgres-decoderbufs ### Optional: Re-generating ProtoBuf code This is only needed after changes to the ProtoBuf definition (_proto/pg_logicaldec.proto): cd proto protoc-c --c_out=../src/proto pg_logicaldec.proto cd .. Commit the generated files to git then. ### Building and installing decoderbufs If you have multiple Postgres versions installed, you can select which version to install decoderbufs into by altering your `$PATH` to point to the right version. Then `make` and `make install` for each version. Here is an example: # Install for Postgres 9.6 if I have multiple local versions export PATH=/usr/lib/postgresql/9.6/bin:$PATH make make install Once the extension has been installed you just need to enable it and logical replication in postgresql.conf: # MODULES shared_preload_libraries = 'decoderbufs' # REPLICATION wal_level = logical # minimal, archive, hot_standby, or logical (change requires restart) max_wal_senders = 8 # max number of walsender processes (change requires restart) wal_keep_segments = 4 # in logfile segments, 16MB each; 0 disables #wal_sender_timeout = 60s # in milliseconds; 0 disables max_replication_slots = 4 # max number of replication slots (change requires restart) In addition, permissions will have to be added for the user that connects to the DB to be able to replicate. This can be modified in _pg\_hba.conf_ like so: local replication trust host replication 127.0.0.1/32 trust host replication ::1/128 trust And restart PostgreSQL. ## Usage -- can use SQL for demo purposes select * from pg_create_logical_replication_slot('decoderbufs_demo', 'decoderbufs'); -- DO SOME TABLE MODIFICATIONS (see below about UPDATE/DELETE) -- peek at WAL changes using decoderbufs debug mode for SQL console select data from pg_logical_slot_peek_changes('decoderbufs_demo', NULL, NULL, 'debug-mode', '1'); -- get WAL changes using decoderbufs to update the WAL position select data from pg_logical_slot_get_changes('decoderbufs_demo', NULL, NULL, 'debug-mode', '1'); -- check the WAL position of logical replicators select * from pg_replication_slots where slot_type = 'logical'; If you're performing an UPDATE/DELETE on your table and you don't see results for those operations from logical decoding, make sure you have set [REPLICA IDENTITY](http://www.postgresql.org/docs/9.4/static/sql-altertable.html#SQL-CREATETABLE-REPLICA-IDENTITY) appropriately for your use case. The binary format will be consumed by the Debezium Postgres Connector. ## Type Mappings The following table shows how current PostgreSQL type OIDs are mapped to which decoderbuf fields: | PostgreSQL Type OID | Decoderbuf Field | |---------------------|---------------| | BOOLOID | datum_boolean | | INT2OID | datum_int32 | | INT4OID | datum_int32 | | INT8OID | datum_int64 | | OIDOID | datum_int64 | | FLOAT4OID | datum_float | | FLOAT8OID | datum_double | | NUMERICOID | datum_double | | CHAROID | datum_string | | VARCHAROID | datum_string | | BPCHAROID | datum_string | | TEXTOID | datum_string | | JSONOID | datum_string | | XMLOID | datum_string | | UUIDOID | datum_string | | TIMESTAMPOID | datum_string | | TIMESTAMPTZOID | datum_string | | BYTEAOID | datum_bytes | | POINTOID | datum_point | | PostGIS geometry | datum_point | | PostGIS geography | datum_point | ## Support File bug reports and feature requests using [Debezium's JIRA](https://issues.jboss.org/browse/DBZ) and the [postgresql-connector](https://issues.jboss.org/browse/DBZ/component/12323543) component postgres-decoderbufs-1.8.0.Final/decoderbufs.control000066400000000000000000000002211411315111100225500ustar00rootroot00000000000000comment = 'Logical decoding plugin that delivers WAL stream changes using a Protocol Buffer format' default_version = '0.1.0' relocatable = true postgres-decoderbufs-1.8.0.Final/proto/000077500000000000000000000000001411315111100200315ustar00rootroot00000000000000postgres-decoderbufs-1.8.0.Final/proto/pg_logicaldec.proto000066400000000000000000000021131411315111100236670ustar00rootroot00000000000000package decoderbufs; option java_package="io.debezium.connector.postgresql.proto"; option java_outer_classname = "PgProto"; option optimize_for = SPEED; enum Op { UNKNOWN = -1; INSERT = 0; UPDATE = 1; DELETE = 2; BEGIN = 3; COMMIT = 4; } message Point { required double x = 1; required double y = 2; } message DatumMessage { optional string column_name = 1; optional int64 column_type = 2; oneof datum { int32 datum_int32 = 3; int64 datum_int64 = 4; float datum_float = 5; double datum_double = 6; bool datum_bool = 7; string datum_string = 8; bytes datum_bytes = 9; Point datum_point = 10; bool datum_missing = 11; } } message TypeInfo { required string modifier = 1; required bool value_optional = 2; } message RowMessage { optional uint32 transaction_id = 1; optional uint64 commit_time = 2; optional string table = 3; optional Op op = 4; repeated DatumMessage new_tuple = 5; repeated DatumMessage old_tuple = 6; repeated TypeInfo new_typeinfo = 7; } postgres-decoderbufs-1.8.0.Final/rpms/000077500000000000000000000000001411315111100176475ustar00rootroot00000000000000postgres-decoderbufs-1.8.0.Final/rpms/postgres-decoderbufs.spec000066400000000000000000000020061411315111100246520ustar00rootroot00000000000000Name: postgres-decoderbufs Version: 0.10.0 Release: 1%{?dist} Summary: PostgreSQL Protocol Buffers logical decoder plugin License: MIT URL: https://github.com/debezium/postgres-decoderbufs %global full_version %{version}.Final Source0: https://github.com/debezium/%{name}/archive/v%{full_version}.tar.gz BuildRequires: gcc BuildRequires: postgresql-devel >= 9.6, postgresql-server-devel >= 9.6 BuildRequires: postgis-devel >= 2 BuildRequires: protobuf-c-devel Requires: protobuf-c %{?postgresql_module_requires} Recommends: postgis %description A PostgreSQL logical decoder output plugin to deliver data as Protocol Buffers messages. %prep %setup -qn postgres-decoderbufs-%{full_version} %build %make_build %install %make_install %files %doc README.md %license LICENSE %{_libdir}/pgsql/decoderbufs.so %{_datadir}/pgsql/extension/decoderbufs.control %changelog * Wed Oct 9 2019 - Jiri Pechanec 0.10.0-1 * Tue May 14 2019 - Jiri Pechanec 0.9.5-1 - Initial RPM packaging postgres-decoderbufs-1.8.0.Final/src/000077500000000000000000000000001411315111100174555ustar00rootroot00000000000000postgres-decoderbufs-1.8.0.Final/src/decoderbufs.c000066400000000000000000000611141411315111100221110ustar00rootroot00000000000000/* * decoderbufs - PostgreSQL output plug-in for logical replication to Protocol * Buffers * * Copyright (c) 2014 Xavier Stevens * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #if defined(__linux__) #include #elif defined(__APPLE__) #include #include #define htobe64(x) OSSwapHostToBigInt64(x) #endif #include #include "postgres.h" #include "funcapi.h" #include "catalog/pg_class.h" #include "catalog/pg_type.h" #include "catalog/namespace.h" #include "executor/spi.h" #include "replication/output_plugin.h" #include "replication/logical.h" #include "utils/builtins.h" #include "utils/lsyscache.h" #include "utils/geo_decls.h" #include "utils/json.h" #include "utils/memutils.h" #include "utils/numeric.h" #include "utils/rel.h" #include "utils/relcache.h" #include "utils/syscache.h" #include "utils/typcache.h" #include "utils/uuid.h" #include "utils/timestamp.h" #include "utils/date.h" #include "utils/cash.h" #include "proto/pg_logicaldec.pb-c.h" #ifndef HAVE_INT64_TIMESTAMP #error Expecting timestamps to be represented as integers, not as floating-point. #endif PG_MODULE_MAGIC; /* define a time macro to convert TimestampTz into something more sane, * which in this case is microseconds since epoch. This is because PG stores internally the timestamps relative to * 2000-01-01T00:00:00Z and not the Unix epoch. */ #define TIMESTAMPTZ_TO_USEC_SINCE_EPOCH(t) t + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * USECS_PER_DAY; #define DATE_TO_DAYS_SINCE_EPOCH(t) t + (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE); typedef struct { MemoryContext context; bool debug_mode; } DecoderData; /* these must be available to pg_dlsym() */ extern void _PG_init(void); extern void _PG_output_plugin_init(OutputPluginCallbacks *cb); static void pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is_init); static void pg_decode_shutdown(LogicalDecodingContext *ctx); static void pg_decode_begin_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn); static void pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr commit_lsn); static void pg_decode_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, Relation rel, ReorderBufferChange *change); void _PG_init(void) {} /* specify output plugin callbacks */ void _PG_output_plugin_init(OutputPluginCallbacks *cb) { AssertVariableIsOfType(&_PG_output_plugin_init, LogicalOutputPluginInit); cb->startup_cb = pg_decode_startup; cb->begin_cb = pg_decode_begin_txn; cb->change_cb = pg_decode_change; cb->commit_cb = pg_decode_commit_txn; cb->shutdown_cb = pg_decode_shutdown; } /* initialize this plugin */ static void pg_decode_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt, bool is_init) { ListCell *option; DecoderData *data; elog(DEBUG1, "Entering startup callback"); data = palloc(sizeof(DecoderData)); #if PG_VERSION_NUM >= 90600 data->context = AllocSetContextCreate( ctx->context, "decoderbufs context", ALLOCSET_DEFAULT_SIZES); #else data->context = AllocSetContextCreate( ctx->context, "decoderbufs context", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); #endif data->debug_mode = false; opt->output_type = OUTPUT_PLUGIN_BINARY_OUTPUT; foreach(option, ctx->output_plugin_options) { DefElem *elem = lfirst(option); Assert(elem->arg == NULL || IsA(elem->arg, String)); if (strcmp(elem->defname, "debug-mode") == 0) { if (elem->arg == NULL) { data->debug_mode = false; } else if (!parse_bool(strVal(elem->arg), &data->debug_mode)) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not parse value \"%s\" for parameter \"%s\"", strVal(elem->arg), elem->defname))); } if (data->debug_mode) { elog(NOTICE, "Decoderbufs DEBUG MODE is ON."); opt->output_type = OUTPUT_PLUGIN_TEXTUAL_OUTPUT; } else { elog(NOTICE, "Decoderbufs DEBUG MODE is OFF."); } } else { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("option \"%s\" = \"%s\" is unknown", elem->defname, elem->arg ? strVal(elem->arg) : "(null)"))); } } ctx->output_plugin_private = data; elog(INFO, "Exiting startup callback"); } /* cleanup this plugin's resources */ static void pg_decode_shutdown(LogicalDecodingContext *ctx) { DecoderData *data; elog(DEBUG1, "Entering decode_shutdown callback"); data = ctx->output_plugin_private; /* cleanup our own resources via memory context reset */ MemoryContextDelete(data->context); } /* print tuple datums (only used for debug-mode) */ static void print_tuple_datums(StringInfo out, Decoderbufs__DatumMessage **tup, size_t n) { if (tup) { for (int i = 0; i < n; i++) { Decoderbufs__DatumMessage *dmsg = tup[i]; if (dmsg->column_name) appendStringInfo(out, "column_name[%s]", dmsg->column_name); if (dmsg->has_column_type) appendStringInfo(out, ", column_type[%" PRId64 "]", dmsg->column_type); switch (dmsg->datum_case) { case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT32: appendStringInfo(out, ", datum[%d]", dmsg->datum_int32); break; case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64: appendStringInfo(out, ", datum[%" PRId64 "]", dmsg->datum_int64); break; case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_FLOAT: appendStringInfo(out, ", datum[%f]", dmsg->datum_float); break; case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_DOUBLE: appendStringInfo(out, ", datum[%f]", dmsg->datum_double); break; case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_BOOL: appendStringInfo(out, ", datum[%d]", dmsg->datum_bool); break; case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_STRING: appendStringInfo(out, ", datum[%s]", dmsg->datum_string); break; case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_BYTES: break; case DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_POINT: appendStringInfo(out, ", datum[POINT(%f, %f)]", dmsg->datum_point->x, dmsg->datum_point->y); break; case DECODERBUFS__DATUM_MESSAGE__DATUM__NOT_SET: // intentional fall-through default: appendStringInfo(out, ", datum[!NOT SET!]"); break; } appendStringInfo(out, "\n"); } } } /* print a row message (only used for debug-mode) */ static void print_row_msg(StringInfo out, Decoderbufs__RowMessage *rmsg) { if (!rmsg) return; if (rmsg->has_transaction_id) appendStringInfo(out, "txid[%d]", rmsg->transaction_id); if (rmsg->has_commit_time) appendStringInfo(out, ", commit_time[%" PRId64 "]", rmsg->commit_time); if (rmsg->table) appendStringInfo(out, ", table[%s]", rmsg->table); if (rmsg->has_op) appendStringInfo(out, ", op[%d]", rmsg->op); if (rmsg->old_tuple) { appendStringInfo(out, "\nOLD TUPLE: \n"); print_tuple_datums(out, rmsg->old_tuple, rmsg->n_old_tuple); appendStringInfo(out, "\n"); } if (rmsg->new_tuple) { appendStringInfo(out, "\nNEW TUPLE: \n"); print_tuple_datums(out, rmsg->new_tuple, rmsg->n_new_tuple); appendStringInfo(out, "\n"); } } /* set a datum value based on its OID specified by typid */ static void set_datum_value(Decoderbufs__DatumMessage *datum_msg, Oid typid, Oid typoutput, Datum datum) { bytea *valptr = NULL; const char *output = NULL; Point *p = NULL; Timestamp ts; TimeTzADT *timetz = NULL; Decoderbufs__Point dp = DECODERBUFS__POINT__INIT; int size = 0; switch (typid) { case BOOLOID: datum_msg->datum_bool = DatumGetBool(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_BOOL; break; case INT2OID: datum_msg->datum_int32 = DatumGetInt16(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT32; break; case INT4OID: datum_msg->datum_int32 = DatumGetInt32(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT32; break; case INT8OID: datum_msg->datum_int64 = DatumGetInt64(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64; break; case OIDOID: datum_msg->datum_int64 = (Oid) DatumGetUInt64(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64; break; case FLOAT4OID: datum_msg->datum_float = DatumGetFloat4(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_FLOAT; break; case FLOAT8OID: datum_msg->datum_double = DatumGetFloat8(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_DOUBLE; break; case CASHOID: datum_msg->datum_int64 = DatumGetCash(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64; break; case NUMERICOID: case CHAROID: case VARCHAROID: case BPCHAROID: case TEXTOID: case JSONOID: case JSONBOID: case XMLOID: case BITOID: case VARBITOID: case UUIDOID: case INTERVALOID: output = OidOutputFunctionCall(typoutput, datum); datum_msg->datum_string = pnstrdup(output, strlen(output)); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_STRING; break; case TIMESTAMPOID: ts = DatumGetTimestamp(datum); if (TIMESTAMP_NOT_FINITE(ts)) { datum_msg->datum_int64 = ts; } else { datum_msg->datum_int64 = TIMESTAMPTZ_TO_USEC_SINCE_EPOCH(ts); } datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64; break; case TIMESTAMPTZOID: ts = DatumGetTimestampTz(datum); if (TIMESTAMP_NOT_FINITE(ts)) { datum_msg->datum_int64 = ts; } else { datum_msg->datum_int64 = TIMESTAMPTZ_TO_USEC_SINCE_EPOCH(ts); } datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64; break; case DATEOID: /* simply get the number of days as the stored 32 bit value and convert to EPOCH */ datum_msg->datum_int32 = DATE_TO_DAYS_SINCE_EPOCH(DatumGetDateADT(datum)); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT32; break; case TIMEOID: datum_msg->datum_int64 = DatumGetTimeADT(datum); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64; break; case TIMETZOID: timetz = DatumGetTimeTzADTP(datum); /* use GMT-equivalent time */ datum_msg->datum_double = (double) (timetz->time + (timetz->zone * 1000000.0)); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_DOUBLE; break; case BYTEAOID: valptr = DatumGetByteaPCopy(datum); size = VARSIZE(valptr) - VARHDRSZ; datum_msg->datum_bytes.data = palloc(size); memcpy(datum_msg->datum_bytes.data, (uint8_t *)VARDATA(valptr), size); datum_msg->datum_bytes.len = size; datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_BYTES; break; case POINTOID: p = DatumGetPointP(datum); dp.x = p->x; dp.y = p->y; datum_msg->datum_point = palloc(sizeof(Decoderbufs__Point)); memcpy(datum_msg->datum_point, &dp, sizeof(dp)); datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_POINT; break; default: { int len; elog(DEBUG1, "Encountered unknown typid: %d, using bytes", typid); output = OidOutputFunctionCall(typoutput, datum); len = strlen(output); size = sizeof(char) * len; datum_msg->datum_bytes.data = palloc(size); memcpy(datum_msg->datum_bytes.data, (uint8_t *)output, size); datum_msg->datum_bytes.len = len; datum_msg->datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_BYTES; } break; } } /* return the number of valid attributes from the tuple */ static int valid_attributes_count_from(TupleDesc tupdesc) { int natt; int count = 0; for (natt = 0; natt < tupdesc->natts; natt++) { Form_pg_attribute attr = TupleDescAttr(tupdesc, natt); /* skip dropped columns and system columns */ if (attr->attisdropped || attr->attnum < 0) { continue; } count++; } return count; } /* convert a PG tuple to an array of DatumMessage(s) */ static void tuple_to_tuple_msg(Decoderbufs__DatumMessage **tmsg, Relation relation, HeapTuple tuple, TupleDesc tupdesc) { int natt; int valid_attr_cnt = 0; elog(DEBUG1, "processing tuple with %d columns", tupdesc->natts); /* build column names and values */ for (natt = 0; natt < tupdesc->natts; natt++) { Form_pg_attribute attr; Datum origval; bool isnull; const char *attrName; Oid typoutput; bool typisvarlena; Decoderbufs__DatumMessage datum_msg = DECODERBUFS__DATUM_MESSAGE__INIT; attr = TupleDescAttr(tupdesc, natt); /* skip dropped columns and system columns */ if (attr->attisdropped || attr->attnum < 0) { elog(DEBUG1, "skipping column %d because %s", natt + 1, attr->attisdropped ? "it's a dropped column" : "it's a system column"); continue; } attrName = quote_identifier(NameStr(attr->attname)); elog(DEBUG1, "processing column %d with name %s", natt + 1, attrName); /* set the column name */ datum_msg.column_name = (char *)attrName; /* set datum from tuple */ origval = heap_getattr(tuple, natt + 1, tupdesc, &isnull); /* get output function */ datum_msg.column_type = attr->atttypid; datum_msg.has_column_type = true; /* query output function */ getTypeOutputInfo(attr->atttypid, &typoutput, &typisvarlena); if (!isnull) { if (typisvarlena && VARATT_IS_EXTERNAL_ONDISK(origval)) { datum_msg.datum_missing = true; datum_msg.datum_case = DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_MISSING; elog(DEBUG1, "Not handling external on disk varlena at the moment."); } else if (!typisvarlena) { set_datum_value(&datum_msg, attr->atttypid, typoutput, origval); } else { Datum val = PointerGetDatum(PG_DETOAST_DATUM(origval)); set_datum_value(&datum_msg, attr->atttypid, typoutput, val); } } else { elog(DEBUG1, "column %s is null, ignoring value", attrName); } tmsg[valid_attr_cnt] = palloc(sizeof(datum_msg)); memcpy(tmsg[valid_attr_cnt], &datum_msg, sizeof(datum_msg)); valid_attr_cnt++; } } /* provide a metadata for new tuple */ static void add_metadata_to_msg(Decoderbufs__TypeInfo **tmsg, Relation relation, HeapTuple tuple, TupleDesc tupdesc) { int natt; int valid_attr_cnt = 0; elog(DEBUG1, "Adding metadata for %d columns", tupdesc->natts); /* build column names and values */ for (natt = 0; natt < tupdesc->natts; natt++) { Form_pg_attribute attr; char *typ_mod; Decoderbufs__TypeInfo typeinfo = DECODERBUFS__TYPE_INFO__INIT; bool not_null; attr = TupleDescAttr(tupdesc, natt); /* skip dropped columns and system columns */ if (attr->attisdropped || attr->attnum < 0) { elog(DEBUG1, "skipping column %d because %s", natt + 1, attr->attisdropped ? "it's a dropped column" : "it's a system column"); continue; } not_null = attr->attnotnull; typ_mod = TextDatumGetCString(DirectFunctionCall2(format_type, attr->atttypid, attr->atttypmod)); elog(DEBUG1, "Adding typemodifier '%s' for column %d, optional %s", typ_mod, natt, !not_null ? "true" : "false"); typeinfo.modifier = typ_mod; typeinfo.value_optional = !not_null; tmsg[valid_attr_cnt] = palloc(sizeof(typeinfo)); memcpy(tmsg[valid_attr_cnt], &typeinfo, sizeof(typeinfo)); valid_attr_cnt++; } } /* BEGIN callback */ static void pg_decode_begin_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn) { DecoderData *data; MemoryContext old; Decoderbufs__RowMessage rmsg = DECODERBUFS__ROW_MESSAGE__INIT; elog(DEBUG1, "Entering begin callback"); /* Avoid leaking memory by using and resetting our own context */ data = ctx->output_plugin_private; old = MemoryContextSwitchTo(data->context); rmsg.op = DECODERBUFS__OP__BEGIN; rmsg.has_op = true; rmsg.transaction_id = txn->xid; rmsg.has_transaction_id = true; rmsg.commit_time = TIMESTAMPTZ_TO_USEC_SINCE_EPOCH(txn->commit_time); rmsg.has_commit_time = true; /* write msg */ OutputPluginPrepareWrite(ctx, true); if (data->debug_mode) { print_row_msg(ctx->out, &rmsg); } else { size_t psize = decoderbufs__row_message__get_packed_size(&rmsg); void *packed = palloc(psize); size_t ssize = decoderbufs__row_message__pack(&rmsg, packed); appendBinaryStringInfo(ctx->out, packed, ssize); } OutputPluginWrite(ctx, true); /* Cleanup, freeing memory */ MemoryContextSwitchTo(old); MemoryContextReset(data->context); } /* COMMIT callback */ static void pg_decode_commit_txn(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, XLogRecPtr commit_lsn) { DecoderData *data; MemoryContext old; Decoderbufs__RowMessage rmsg = DECODERBUFS__ROW_MESSAGE__INIT; elog(DEBUG1, "Entering commit callback"); /* Avoid leaking memory by using and resetting our own context */ data = ctx->output_plugin_private; old = MemoryContextSwitchTo(data->context); rmsg.op = DECODERBUFS__OP__COMMIT; rmsg.has_op = true; rmsg.transaction_id = txn->xid; rmsg.has_transaction_id = true; rmsg.commit_time = TIMESTAMPTZ_TO_USEC_SINCE_EPOCH(txn->commit_time); rmsg.has_commit_time = true; /* write msg */ OutputPluginPrepareWrite(ctx, true); if (data->debug_mode) { print_row_msg(ctx->out, &rmsg); } else { size_t psize = decoderbufs__row_message__get_packed_size(&rmsg); void *packed = palloc(psize); size_t ssize = decoderbufs__row_message__pack(&rmsg, packed); appendBinaryStringInfo(ctx->out, packed, ssize); } OutputPluginWrite(ctx, true); /* Cleanup, freeing memory */ MemoryContextSwitchTo(old); MemoryContextReset(data->context); } /* callback for individual changed tuples */ static void pg_decode_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change) { DecoderData *data; MemoryContext old; Form_pg_class class_form; char replident; bool is_rel_non_selective; const char *selectiveInfo; TupleDesc tupdesc; Decoderbufs__RowMessage rmsg = DECODERBUFS__ROW_MESSAGE__INIT; elog(DEBUG1, "Entering decode_change callback"); /* Avoid leaking memory by using and resetting our own context */ data = ctx->output_plugin_private; old = MemoryContextSwitchTo(data->context); replident = relation->rd_rel->relreplident; class_form = RelationGetForm(relation); RelationGetIndexList(relation); is_rel_non_selective = (replident == REPLICA_IDENTITY_NOTHING || (replident == REPLICA_IDENTITY_DEFAULT && !OidIsValid(relation->rd_replidindex))); selectiveInfo = is_rel_non_selective ? "non selective" : "selective"; /* set common fields */ rmsg.transaction_id = txn->xid; rmsg.has_transaction_id = true; rmsg.commit_time = TIMESTAMPTZ_TO_USEC_SINCE_EPOCH(txn->commit_time); rmsg.has_commit_time = true; rmsg.table = pstrdup(quote_qualified_identifier(get_namespace_name(get_rel_namespace(RelationGetRelid(relation))), NameStr(class_form->relname))); /* decode different operation types */ switch (change->action) { case REORDER_BUFFER_CHANGE_INSERT: elog(DEBUG1, "decoding INSERT for table %s; relation is %s", rmsg.table, selectiveInfo); rmsg.op = DECODERBUFS__OP__INSERT; rmsg.has_op = true; if (change->data.tp.newtuple != NULL) { elog(DEBUG1, "decoding new tuple information"); tupdesc = RelationGetDescr(relation); rmsg.n_new_tuple = valid_attributes_count_from(tupdesc); rmsg.new_tuple = palloc(sizeof(Decoderbufs__DatumMessage*) * rmsg.n_new_tuple); tuple_to_tuple_msg(rmsg.new_tuple, relation, &change->data.tp.newtuple->tuple, tupdesc); rmsg.n_new_typeinfo = rmsg.n_new_tuple; rmsg.new_typeinfo = palloc(sizeof(Decoderbufs__TypeInfo*) * rmsg.n_new_typeinfo); add_metadata_to_msg(rmsg.new_typeinfo, relation, &change->data.tp.newtuple->tuple, tupdesc); } break; case REORDER_BUFFER_CHANGE_UPDATE: rmsg.op = DECODERBUFS__OP__UPDATE; rmsg.has_op = true; elog(DEBUG1, "decoding UPDATE for table %s; relation is %s", rmsg.table, selectiveInfo); if (!is_rel_non_selective) { if (change->data.tp.oldtuple != NULL) { elog(DEBUG1, "decoding old tuple information"); tupdesc = RelationGetDescr(relation); rmsg.n_old_tuple = valid_attributes_count_from(tupdesc); rmsg.old_tuple = palloc(sizeof(Decoderbufs__DatumMessage*) * rmsg.n_old_tuple); tuple_to_tuple_msg(rmsg.old_tuple, relation, &change->data.tp.oldtuple->tuple, tupdesc); } if (change->data.tp.newtuple != NULL) { elog(DEBUG1, "decoding new tuple information"); tupdesc = RelationGetDescr(relation); rmsg.n_new_tuple = valid_attributes_count_from(tupdesc); rmsg.new_tuple = palloc(sizeof(Decoderbufs__DatumMessage*) * rmsg.n_new_tuple); tuple_to_tuple_msg(rmsg.new_tuple, relation, &change->data.tp.newtuple->tuple, tupdesc); rmsg.n_new_typeinfo = rmsg.n_new_tuple; rmsg.new_typeinfo = palloc(sizeof(Decoderbufs__TypeInfo*) * rmsg.n_new_typeinfo); add_metadata_to_msg(rmsg.new_typeinfo, relation, &change->data.tp.newtuple->tuple, tupdesc); } } break; case REORDER_BUFFER_CHANGE_DELETE: rmsg.op = DECODERBUFS__OP__DELETE; rmsg.has_op = true; elog(DEBUG1, "decoding DELETE for table %s; relation is %s", rmsg.table, selectiveInfo); /* if there was no PK, we only know that a delete happened */ if (!is_rel_non_selective && change->data.tp.oldtuple != NULL) { elog(DEBUG1, "decoding old tuple information"); tupdesc = RelationGetDescr(relation); rmsg.n_old_tuple = valid_attributes_count_from(tupdesc); rmsg.old_tuple = palloc(sizeof(Decoderbufs__DatumMessage*) * rmsg.n_old_tuple); tuple_to_tuple_msg(rmsg.old_tuple, relation, &change->data.tp.oldtuple->tuple, tupdesc); } else { elog(DEBUG1, "no information to decode from DELETE because either no PK is present or REPLICA IDENTITY NOTHING or invalid "); } break; default: elog(WARNING, "unknown change action"); Assert(0); break; } /* write msg */ OutputPluginPrepareWrite(ctx, true); if (data->debug_mode) { //protobuf_c_text_to_string(ctx->out, (ProtobufCMessage*)&rmsg); print_row_msg(ctx->out, &rmsg); } else { size_t psize = decoderbufs__row_message__get_packed_size(&rmsg); void *packed = palloc(psize); size_t ssize = decoderbufs__row_message__pack(&rmsg, packed); appendBinaryStringInfo(ctx->out, packed, ssize); } OutputPluginWrite(ctx, true); /* Cleanup, freeing memory */ MemoryContextSwitchTo(old); MemoryContextReset(data->context); } postgres-decoderbufs-1.8.0.Final/src/proto/000077500000000000000000000000001411315111100206205ustar00rootroot00000000000000postgres-decoderbufs-1.8.0.Final/src/proto/pg_logicaldec.pb-c.c000066400000000000000000000450211411315111100243620ustar00rootroot00000000000000/* Generated by the protocol buffer compiler. DO NOT EDIT! */ /* Generated from: pg_logicaldec.proto */ /* Do not generate deprecated warnings for self */ #ifndef PROTOBUF_C__NO_DEPRECATED #define PROTOBUF_C__NO_DEPRECATED #endif #include "pg_logicaldec.pb-c.h" void decoderbufs__point__init (Decoderbufs__Point *message) { static Decoderbufs__Point init_value = DECODERBUFS__POINT__INIT; *message = init_value; } size_t decoderbufs__point__get_packed_size (const Decoderbufs__Point *message) { assert(message->base.descriptor == &decoderbufs__point__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } size_t decoderbufs__point__pack (const Decoderbufs__Point *message, uint8_t *out) { assert(message->base.descriptor == &decoderbufs__point__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } size_t decoderbufs__point__pack_to_buffer (const Decoderbufs__Point *message, ProtobufCBuffer *buffer) { assert(message->base.descriptor == &decoderbufs__point__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } Decoderbufs__Point * decoderbufs__point__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { return (Decoderbufs__Point *) protobuf_c_message_unpack (&decoderbufs__point__descriptor, allocator, len, data); } void decoderbufs__point__free_unpacked (Decoderbufs__Point *message, ProtobufCAllocator *allocator) { assert(message->base.descriptor == &decoderbufs__point__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } void decoderbufs__datum_message__init (Decoderbufs__DatumMessage *message) { static Decoderbufs__DatumMessage init_value = DECODERBUFS__DATUM_MESSAGE__INIT; *message = init_value; } size_t decoderbufs__datum_message__get_packed_size (const Decoderbufs__DatumMessage *message) { assert(message->base.descriptor == &decoderbufs__datum_message__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } size_t decoderbufs__datum_message__pack (const Decoderbufs__DatumMessage *message, uint8_t *out) { assert(message->base.descriptor == &decoderbufs__datum_message__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } size_t decoderbufs__datum_message__pack_to_buffer (const Decoderbufs__DatumMessage *message, ProtobufCBuffer *buffer) { assert(message->base.descriptor == &decoderbufs__datum_message__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } Decoderbufs__DatumMessage * decoderbufs__datum_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { return (Decoderbufs__DatumMessage *) protobuf_c_message_unpack (&decoderbufs__datum_message__descriptor, allocator, len, data); } void decoderbufs__datum_message__free_unpacked (Decoderbufs__DatumMessage *message, ProtobufCAllocator *allocator) { assert(message->base.descriptor == &decoderbufs__datum_message__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } void decoderbufs__type_info__init (Decoderbufs__TypeInfo *message) { static Decoderbufs__TypeInfo init_value = DECODERBUFS__TYPE_INFO__INIT; *message = init_value; } size_t decoderbufs__type_info__get_packed_size (const Decoderbufs__TypeInfo *message) { assert(message->base.descriptor == &decoderbufs__type_info__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } size_t decoderbufs__type_info__pack (const Decoderbufs__TypeInfo *message, uint8_t *out) { assert(message->base.descriptor == &decoderbufs__type_info__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } size_t decoderbufs__type_info__pack_to_buffer (const Decoderbufs__TypeInfo *message, ProtobufCBuffer *buffer) { assert(message->base.descriptor == &decoderbufs__type_info__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } Decoderbufs__TypeInfo * decoderbufs__type_info__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { return (Decoderbufs__TypeInfo *) protobuf_c_message_unpack (&decoderbufs__type_info__descriptor, allocator, len, data); } void decoderbufs__type_info__free_unpacked (Decoderbufs__TypeInfo *message, ProtobufCAllocator *allocator) { assert(message->base.descriptor == &decoderbufs__type_info__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } void decoderbufs__row_message__init (Decoderbufs__RowMessage *message) { static Decoderbufs__RowMessage init_value = DECODERBUFS__ROW_MESSAGE__INIT; *message = init_value; } size_t decoderbufs__row_message__get_packed_size (const Decoderbufs__RowMessage *message) { assert(message->base.descriptor == &decoderbufs__row_message__descriptor); return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); } size_t decoderbufs__row_message__pack (const Decoderbufs__RowMessage *message, uint8_t *out) { assert(message->base.descriptor == &decoderbufs__row_message__descriptor); return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); } size_t decoderbufs__row_message__pack_to_buffer (const Decoderbufs__RowMessage *message, ProtobufCBuffer *buffer) { assert(message->base.descriptor == &decoderbufs__row_message__descriptor); return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); } Decoderbufs__RowMessage * decoderbufs__row_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { return (Decoderbufs__RowMessage *) protobuf_c_message_unpack (&decoderbufs__row_message__descriptor, allocator, len, data); } void decoderbufs__row_message__free_unpacked (Decoderbufs__RowMessage *message, ProtobufCAllocator *allocator) { assert(message->base.descriptor == &decoderbufs__row_message__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } static const ProtobufCFieldDescriptor decoderbufs__point__field_descriptors[2] = { { "x", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_DOUBLE, 0, /* quantifier_offset */ offsetof(Decoderbufs__Point, x), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "y", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_DOUBLE, 0, /* quantifier_offset */ offsetof(Decoderbufs__Point, y), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; static const unsigned decoderbufs__point__field_indices_by_name[] = { 0, /* field[0] = x */ 1, /* field[1] = y */ }; static const ProtobufCIntRange decoderbufs__point__number_ranges[1 + 1] = { { 1, 0 }, { 0, 2 } }; const ProtobufCMessageDescriptor decoderbufs__point__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, "decoderbufs.Point", "Point", "Decoderbufs__Point", "decoderbufs", sizeof(Decoderbufs__Point), 2, decoderbufs__point__field_descriptors, decoderbufs__point__field_indices_by_name, 1, decoderbufs__point__number_ranges, (ProtobufCMessageInit) decoderbufs__point__init, NULL,NULL,NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor decoderbufs__datum_message__field_descriptors[11] = { { "column_name", 1, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_STRING, 0, /* quantifier_offset */ offsetof(Decoderbufs__DatumMessage, column_name), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "column_type", 2, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT64, offsetof(Decoderbufs__DatumMessage, has_column_type), offsetof(Decoderbufs__DatumMessage, column_type), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_int32", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT32, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_int32), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_int64", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT64, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_int64), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_float", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_FLOAT, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_float), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_double", 6, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_DOUBLE, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_double), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_bool", 7, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_bool), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_string", 8, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_STRING, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_string), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_bytes", 9, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BYTES, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_bytes), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_point", 10, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_point), &decoderbufs__point__descriptor, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "datum_missing", 11, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, offsetof(Decoderbufs__DatumMessage, datum_case), offsetof(Decoderbufs__DatumMessage, datum_missing), NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; static const unsigned decoderbufs__datum_message__field_indices_by_name[] = { 0, /* field[0] = column_name */ 1, /* field[1] = column_type */ 6, /* field[6] = datum_bool */ 8, /* field[8] = datum_bytes */ 5, /* field[5] = datum_double */ 4, /* field[4] = datum_float */ 2, /* field[2] = datum_int32 */ 3, /* field[3] = datum_int64 */ 10, /* field[10] = datum_missing */ 9, /* field[9] = datum_point */ 7, /* field[7] = datum_string */ }; static const ProtobufCIntRange decoderbufs__datum_message__number_ranges[1 + 1] = { { 1, 0 }, { 0, 11 } }; const ProtobufCMessageDescriptor decoderbufs__datum_message__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, "decoderbufs.DatumMessage", "DatumMessage", "Decoderbufs__DatumMessage", "decoderbufs", sizeof(Decoderbufs__DatumMessage), 11, decoderbufs__datum_message__field_descriptors, decoderbufs__datum_message__field_indices_by_name, 1, decoderbufs__datum_message__number_ranges, (ProtobufCMessageInit) decoderbufs__datum_message__init, NULL,NULL,NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor decoderbufs__type_info__field_descriptors[2] = { { "modifier", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, 0, /* quantifier_offset */ offsetof(Decoderbufs__TypeInfo, modifier), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "value_optional", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_BOOL, 0, /* quantifier_offset */ offsetof(Decoderbufs__TypeInfo, value_optional), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; static const unsigned decoderbufs__type_info__field_indices_by_name[] = { 0, /* field[0] = modifier */ 1, /* field[1] = value_optional */ }; static const ProtobufCIntRange decoderbufs__type_info__number_ranges[1 + 1] = { { 1, 0 }, { 0, 2 } }; const ProtobufCMessageDescriptor decoderbufs__type_info__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, "decoderbufs.TypeInfo", "TypeInfo", "Decoderbufs__TypeInfo", "decoderbufs", sizeof(Decoderbufs__TypeInfo), 2, decoderbufs__type_info__field_descriptors, decoderbufs__type_info__field_indices_by_name, 1, decoderbufs__type_info__number_ranges, (ProtobufCMessageInit) decoderbufs__type_info__init, NULL,NULL,NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor decoderbufs__row_message__field_descriptors[7] = { { "transaction_id", 1, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_UINT32, offsetof(Decoderbufs__RowMessage, has_transaction_id), offsetof(Decoderbufs__RowMessage, transaction_id), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "commit_time", 2, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_UINT64, offsetof(Decoderbufs__RowMessage, has_commit_time), offsetof(Decoderbufs__RowMessage, commit_time), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "table", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_STRING, 0, /* quantifier_offset */ offsetof(Decoderbufs__RowMessage, table), NULL, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "op", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_ENUM, offsetof(Decoderbufs__RowMessage, has_op), offsetof(Decoderbufs__RowMessage, op), &decoderbufs__op__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "new_tuple", 5, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, offsetof(Decoderbufs__RowMessage, n_new_tuple), offsetof(Decoderbufs__RowMessage, new_tuple), &decoderbufs__datum_message__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "old_tuple", 6, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, offsetof(Decoderbufs__RowMessage, n_old_tuple), offsetof(Decoderbufs__RowMessage, old_tuple), &decoderbufs__datum_message__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { "new_typeinfo", 7, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, offsetof(Decoderbufs__RowMessage, n_new_typeinfo), offsetof(Decoderbufs__RowMessage, new_typeinfo), &decoderbufs__type_info__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; static const unsigned decoderbufs__row_message__field_indices_by_name[] = { 1, /* field[1] = commit_time */ 4, /* field[4] = new_tuple */ 6, /* field[6] = new_typeinfo */ 5, /* field[5] = old_tuple */ 3, /* field[3] = op */ 2, /* field[2] = table */ 0, /* field[0] = transaction_id */ }; static const ProtobufCIntRange decoderbufs__row_message__number_ranges[1 + 1] = { { 1, 0 }, { 0, 7 } }; const ProtobufCMessageDescriptor decoderbufs__row_message__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, "decoderbufs.RowMessage", "RowMessage", "Decoderbufs__RowMessage", "decoderbufs", sizeof(Decoderbufs__RowMessage), 7, decoderbufs__row_message__field_descriptors, decoderbufs__row_message__field_indices_by_name, 1, decoderbufs__row_message__number_ranges, (ProtobufCMessageInit) decoderbufs__row_message__init, NULL,NULL,NULL /* reserved[123] */ }; static const ProtobufCEnumValue decoderbufs__op__enum_values_by_number[6] = { { "UNKNOWN", "DECODERBUFS__OP__UNKNOWN", -1 }, { "INSERT", "DECODERBUFS__OP__INSERT", 0 }, { "UPDATE", "DECODERBUFS__OP__UPDATE", 1 }, { "DELETE", "DECODERBUFS__OP__DELETE", 2 }, { "BEGIN", "DECODERBUFS__OP__BEGIN", 3 }, { "COMMIT", "DECODERBUFS__OP__COMMIT", 4 }, }; static const ProtobufCIntRange decoderbufs__op__value_ranges[] = { {-1, 0},{0, 6} }; static const ProtobufCEnumValueIndex decoderbufs__op__enum_values_by_name[6] = { { "BEGIN", 4 }, { "COMMIT", 5 }, { "DELETE", 3 }, { "INSERT", 1 }, { "UNKNOWN", 0 }, { "UPDATE", 2 }, }; const ProtobufCEnumDescriptor decoderbufs__op__descriptor = { PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, "decoderbufs.Op", "Op", "Decoderbufs__Op", "decoderbufs", 6, decoderbufs__op__enum_values_by_number, 6, decoderbufs__op__enum_values_by_name, 1, decoderbufs__op__value_ranges, NULL,NULL,NULL,NULL /* reserved[1234] */ }; postgres-decoderbufs-1.8.0.Final/src/proto/pg_logicaldec.pb-c.h000066400000000000000000000203451411315111100243710ustar00rootroot00000000000000/* Generated by the protocol buffer compiler. DO NOT EDIT! */ /* Generated from: pg_logicaldec.proto */ #ifndef PROTOBUF_C_pg_5flogicaldec_2eproto__INCLUDED #define PROTOBUF_C_pg_5flogicaldec_2eproto__INCLUDED #include PROTOBUF_C__BEGIN_DECLS #if PROTOBUF_C_VERSION_NUMBER < 1000000 # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. #elif 1002001 < PROTOBUF_C_MIN_COMPILER_VERSION # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. #endif typedef struct _Decoderbufs__Point Decoderbufs__Point; typedef struct _Decoderbufs__DatumMessage Decoderbufs__DatumMessage; typedef struct _Decoderbufs__TypeInfo Decoderbufs__TypeInfo; typedef struct _Decoderbufs__RowMessage Decoderbufs__RowMessage; /* --- enums --- */ typedef enum _Decoderbufs__Op { DECODERBUFS__OP__UNKNOWN = -1, DECODERBUFS__OP__INSERT = 0, DECODERBUFS__OP__UPDATE = 1, DECODERBUFS__OP__DELETE = 2, DECODERBUFS__OP__BEGIN = 3, DECODERBUFS__OP__COMMIT = 4 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(DECODERBUFS__OP) } Decoderbufs__Op; /* --- messages --- */ struct _Decoderbufs__Point { ProtobufCMessage base; double x; double y; }; #define DECODERBUFS__POINT__INIT \ { PROTOBUF_C_MESSAGE_INIT (&decoderbufs__point__descriptor) \ , 0, 0 } typedef enum { DECODERBUFS__DATUM_MESSAGE__DATUM__NOT_SET = 0, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT32 = 3, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_INT64 = 4, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_FLOAT = 5, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_DOUBLE = 6, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_BOOL = 7, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_STRING = 8, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_BYTES = 9, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_POINT = 10, DECODERBUFS__DATUM_MESSAGE__DATUM_DATUM_MISSING = 11, } Decoderbufs__DatumMessage__DatumCase; struct _Decoderbufs__DatumMessage { ProtobufCMessage base; char *column_name; protobuf_c_boolean has_column_type; int64_t column_type; Decoderbufs__DatumMessage__DatumCase datum_case; union { int32_t datum_int32; int64_t datum_int64; float datum_float; double datum_double; protobuf_c_boolean datum_bool; char *datum_string; ProtobufCBinaryData datum_bytes; Decoderbufs__Point *datum_point; protobuf_c_boolean datum_missing; }; }; #define DECODERBUFS__DATUM_MESSAGE__INIT \ { PROTOBUF_C_MESSAGE_INIT (&decoderbufs__datum_message__descriptor) \ , NULL, 0,0, DECODERBUFS__DATUM_MESSAGE__DATUM__NOT_SET, {0} } struct _Decoderbufs__TypeInfo { ProtobufCMessage base; char *modifier; protobuf_c_boolean value_optional; }; #define DECODERBUFS__TYPE_INFO__INIT \ { PROTOBUF_C_MESSAGE_INIT (&decoderbufs__type_info__descriptor) \ , NULL, 0 } struct _Decoderbufs__RowMessage { ProtobufCMessage base; protobuf_c_boolean has_transaction_id; uint32_t transaction_id; protobuf_c_boolean has_commit_time; uint64_t commit_time; char *table; protobuf_c_boolean has_op; Decoderbufs__Op op; size_t n_new_tuple; Decoderbufs__DatumMessage **new_tuple; size_t n_old_tuple; Decoderbufs__DatumMessage **old_tuple; size_t n_new_typeinfo; Decoderbufs__TypeInfo **new_typeinfo; }; #define DECODERBUFS__ROW_MESSAGE__INIT \ { PROTOBUF_C_MESSAGE_INIT (&decoderbufs__row_message__descriptor) \ , 0,0, 0,0, NULL, 0,0, 0,NULL, 0,NULL, 0,NULL } /* Decoderbufs__Point methods */ void decoderbufs__point__init (Decoderbufs__Point *message); size_t decoderbufs__point__get_packed_size (const Decoderbufs__Point *message); size_t decoderbufs__point__pack (const Decoderbufs__Point *message, uint8_t *out); size_t decoderbufs__point__pack_to_buffer (const Decoderbufs__Point *message, ProtobufCBuffer *buffer); Decoderbufs__Point * decoderbufs__point__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); void decoderbufs__point__free_unpacked (Decoderbufs__Point *message, ProtobufCAllocator *allocator); /* Decoderbufs__DatumMessage methods */ void decoderbufs__datum_message__init (Decoderbufs__DatumMessage *message); size_t decoderbufs__datum_message__get_packed_size (const Decoderbufs__DatumMessage *message); size_t decoderbufs__datum_message__pack (const Decoderbufs__DatumMessage *message, uint8_t *out); size_t decoderbufs__datum_message__pack_to_buffer (const Decoderbufs__DatumMessage *message, ProtobufCBuffer *buffer); Decoderbufs__DatumMessage * decoderbufs__datum_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); void decoderbufs__datum_message__free_unpacked (Decoderbufs__DatumMessage *message, ProtobufCAllocator *allocator); /* Decoderbufs__TypeInfo methods */ void decoderbufs__type_info__init (Decoderbufs__TypeInfo *message); size_t decoderbufs__type_info__get_packed_size (const Decoderbufs__TypeInfo *message); size_t decoderbufs__type_info__pack (const Decoderbufs__TypeInfo *message, uint8_t *out); size_t decoderbufs__type_info__pack_to_buffer (const Decoderbufs__TypeInfo *message, ProtobufCBuffer *buffer); Decoderbufs__TypeInfo * decoderbufs__type_info__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); void decoderbufs__type_info__free_unpacked (Decoderbufs__TypeInfo *message, ProtobufCAllocator *allocator); /* Decoderbufs__RowMessage methods */ void decoderbufs__row_message__init (Decoderbufs__RowMessage *message); size_t decoderbufs__row_message__get_packed_size (const Decoderbufs__RowMessage *message); size_t decoderbufs__row_message__pack (const Decoderbufs__RowMessage *message, uint8_t *out); size_t decoderbufs__row_message__pack_to_buffer (const Decoderbufs__RowMessage *message, ProtobufCBuffer *buffer); Decoderbufs__RowMessage * decoderbufs__row_message__unpack (ProtobufCAllocator *allocator, size_t len, const uint8_t *data); void decoderbufs__row_message__free_unpacked (Decoderbufs__RowMessage *message, ProtobufCAllocator *allocator); /* --- per-message closures --- */ typedef void (*Decoderbufs__Point_Closure) (const Decoderbufs__Point *message, void *closure_data); typedef void (*Decoderbufs__DatumMessage_Closure) (const Decoderbufs__DatumMessage *message, void *closure_data); typedef void (*Decoderbufs__TypeInfo_Closure) (const Decoderbufs__TypeInfo *message, void *closure_data); typedef void (*Decoderbufs__RowMessage_Closure) (const Decoderbufs__RowMessage *message, void *closure_data); /* --- services --- */ /* --- descriptors --- */ extern const ProtobufCEnumDescriptor decoderbufs__op__descriptor; extern const ProtobufCMessageDescriptor decoderbufs__point__descriptor; extern const ProtobufCMessageDescriptor decoderbufs__datum_message__descriptor; extern const ProtobufCMessageDescriptor decoderbufs__type_info__descriptor; extern const ProtobufCMessageDescriptor decoderbufs__row_message__descriptor; PROTOBUF_C__END_DECLS #endif /* PROTOBUF_C_pg_5flogicaldec_2eproto__INCLUDED */