[Groonga-commit] pgroonga/pgroonga at 8dfc54b [master] Support writing XLog for insert data

Back to archive index

Kouhei Sutou null+****@clear*****
Mon Oct 24 00:05:05 JST 2016


Kouhei Sutou	2016-10-24 00:05:05 +0900 (Mon, 24 Oct 2016)

  New Revision: 8dfc54b4c4a8275b43f7b1084c88acbdccb91164
  https://github.com/pgroonga/pgroonga/commit/8dfc54b4c4a8275b43f7b1084c88acbdccb91164

  Message:
    Support writing XLog for insert data
    
    It's a experimental feature.
    
    TODO:
    
      * Support writing XLog for index creation.
      * Support applying XLog.

  Added files:
    src/pgrn_xlog.c
    src/pgrn_xlog.h
  Modified files:
    Makefile
    sources.am
    src/pgrn_compatible.h
    src/pgrn_jsonb.c
    src/pgrn_jsonb.h
    src/pgrn_variables.c
    src/pgroonga.c

  Modified: Makefile (+10 -3)
===================================================================
--- Makefile    2016-10-23 00:44:10 +0900 (fba31b6)
+++ Makefile    2016-10-24 00:05:05 +0900 (41b2738)
@@ -1,5 +1,9 @@
 REQUIRED_GROONGA_VERSION = 5.1.2
 GROONGA_PKG = "groonga >= $(REQUIRED_GROONGA_VERSION)"
+PACKAGES = $(GROONGA_PKG)
+ifdef HAVE_MSGPACK
+PACKAGES += msgpack
+endif
 
 MODULE_big = pgroonga
 include sources.am
@@ -17,15 +21,18 @@ DATA =						\
 	$(shell echo pgroonga--*--*.sql)
 endif
 
-PG_CPPFLAGS = $(shell pkg-config --cflags $(GROONGA_PKG))
-SHLIB_LINK = $(shell pkg-config --libs $(GROONGA_PKG)) -lm
+PG_CPPFLAGS = $(shell pkg-config --cflags $(PACKAGES))
+SHLIB_LINK = $(shell pkg-config --libs $(PACKAGES)) -lm
 REGRESS = $(shell find sql -name '*.sql' | sed -e 's,\(^sql/\|\.sql$$\),,g')
 REGRESS_OPTS = --load-extension=pgroonga
 
 COPT += -Ivendor/xxHash
+ifdef HAVE_MSGPACK
+COPT += -DPGRN_HAVE_MSGPACK
+endif
 ifdef DEBUG
 COPT += -O0 -g3 -DPGROONGA_DEBUG=1
-SHLIB_LINK += -Wl,--rpath=$(shell pkg-config --libs-only-L $(GROONGA_PKG) | sed -e 's/^-L//')
+SHLIB_LINK += -Wl,--rpath=$(shell pkg-config --libs-only-L $(PACKAGES) | sed -e 's/^-L//')
 endif
 
 PG_CONFIG = pg_config

  Modified: sources.am (+1 -0)
===================================================================
--- sources.am    2016-10-23 00:44:10 +0900 (820c22b)
+++ sources.am    2016-10-24 00:05:05 +0900 (2105f3b)
@@ -16,4 +16,5 @@ SRCS =						\
 	src/pgrn_snippet_html.c			\
 	src/pgrn_value.c			\
 	src/pgrn_variables.c			\
+	src/pgrn_xlog.c				\
 	vendor/xxHash/xxhash.c

  Modified: src/pgrn_compatible.h (+1 -1)
===================================================================
--- src/pgrn_compatible.h    2016-10-23 00:44:10 +0900 (f806415)
+++ src/pgrn_compatible.h    2016-10-24 00:05:05 +0900 (a89531a)
@@ -20,7 +20,7 @@
 #	define PGRN_SUPPORT_CREATE_ACCESS_METHOD
 #endif
 
-#if PG_VERSION_NUM >= 90600
+#if PG_VERSION_NUM >= 90600 && defined(PGRN_HAVE_MSGPACK)
 #	define PGRN_SUPPORT_XLOG
 #endif
 

  Modified: src/pgrn_jsonb.c (+11 -1)
===================================================================
--- src/pgrn_jsonb.c    2016-10-23 00:44:10 +0900 (ee32aa5)
+++ src/pgrn_jsonb.c    2016-10-24 00:05:05 +0900 (51ad7d5)
@@ -7,6 +7,7 @@
 #include "pgrn_jsonb.h"
 #include "pgrn_options.h"
 #include "pgrn_value.h"
+#include "pgrn_xlog.h"
 
 #include <catalog/pg_type.h>
 #include <utils/builtins.h>
@@ -42,6 +43,7 @@ typedef struct PGrnJSONBInsertData
 	grn_obj *sizeColumn;
 	grn_obj *typeColumn;
 	grn_obj *valueIDs;
+	PGrnXLogData *xlogData;
 	grn_obj key;
 	grn_obj components;
 	grn_obj path;
@@ -490,10 +492,14 @@ PGrnJSONBInsertValueSet(PGrnJSONBInsertData *data,
 	GRN_BULK_REWIND(&(data->path));
 	PGrnJSONGenerateCompletePath(&(data->components), &(data->path));
 	if (GRN_TEXT_LEN(&(data->path)) < GRN_TABLE_MAX_KEY_SIZE)
+	{
+		/* TODO: XLog */
 		grn_obj_set_value(ctx, data->pathColumn, valueID,
 						  &(data->path), GRN_OBJ_SET);
+	}
 
 	PGrnJSONBInsertGeneratePaths(data);
+	/* TODO: XLog */
 	grn_obj_set_value(ctx, data->pathsColumn, valueID,
 					  &(data->pathIDs), GRN_OBJ_SET);
 
@@ -501,6 +507,7 @@ PGrnJSONBInsertValueSet(PGrnJSONBInsertData *data,
 		grn_obj_set_value(ctx, column, valueID, &(data->value), GRN_OBJ_SET);
 
 	GRN_TEXT_SETS(ctx, &(data->type), typeName);
+	/* TODO: XLog */
 	grn_obj_set_value(ctx, data->typeColumn, valueID,
 					  &(data->type), GRN_OBJ_SET);
 }
@@ -942,6 +949,7 @@ pgroonga_match_jsonb(PG_FUNCTION_ARGS)
 	data.valuesTable = tmpValuesTable;
 	GRN_PTR_INIT(&valueIDs, GRN_OBJ_VECTOR, grn_obj_id(ctx, data.valuesTable));
 	data.valueIDs = &valueIDs;
+	data.xlogData = NULL;
 	PGrnJSONBInsertDataInit(&data);
 	iter = JsonbIteratorInit(&(jsonb->root));
 	PGrnJSONBInsertContainer(&iter, &data);
@@ -992,7 +1000,8 @@ void
 PGrnJSONBInsert(Relation index,
 				Datum *values,
 				unsigned int nthValue,
-				grn_obj *valueIDs)
+				grn_obj *valueIDs,
+				PGrnXLogData *xlogData)
 {
 #ifdef PGRN_SUPPORT_JSONB
 	PGrnJSONBInsertData data;
@@ -1002,6 +1011,7 @@ PGrnJSONBInsert(Relation index,
 	data.pathsTable  = PGrnJSONBLookupPathsTable(index, nthValue, ERROR);
 	data.valuesTable = PGrnJSONBLookupValuesTable(index, nthValue, ERROR);
 	data.valueIDs = valueIDs;
+	data.xlogData = xlogData;
 	grn_obj_reinit(ctx, data.valueIDs,
 				   grn_obj_id(ctx, data.valuesTable),
 				   GRN_OBJ_VECTOR);

  Modified: src/pgrn_jsonb.h (+3 -1)
===================================================================
--- src/pgrn_jsonb.h    2016-10-23 00:44:10 +0900 (23956d0)
+++ src/pgrn_jsonb.h    2016-10-24 00:05:05 +0900 (8cf3c68)
@@ -5,6 +5,7 @@
 
 #include "pgrn_create.h"
 #include "pgrn_search.h"
+#include "pgrn_xlog.h"
 
 void PGrnInitializeJSONB(void);
 void PGrnFinalizeJSONB(void);
@@ -43,7 +44,8 @@ grn_obj *PGrnJSONBSetSource(Relation index, unsigned int i);
 void PGrnJSONBInsert(Relation index,
 					 Datum *values,
 					 unsigned int nthValue,
-					 grn_obj *valueIDs);
+					 grn_obj *valueIDs,
+					 PGrnXLogData *xlogData);
 
 bool PGrnJSONBBuildSearchCondition(PGrnSearchData *data,
 								   ScanKey key,

  Modified: src/pgrn_variables.c (+29 -2)
===================================================================
--- src/pgrn_variables.c    2016-10-23 00:44:10 +0900 (07ef83d)
+++ src/pgrn_variables.c    2016-10-24 00:05:05 +0900 (2ad98eb)
@@ -4,6 +4,7 @@
 #include "pgrn_global.h"
 #include "pgrn_value.h"
 #include "pgrn_variables.h"
+#include "pgrn_xlog.h"
 
 #include <utils/guc.h>
 
@@ -46,6 +47,7 @@ static struct config_enum_entry PGrnLogLevelEntries[] = {
 #endif
 
 static int PGrnLockTimeout;
+static bool PGrnEnableWAL;
 
 #ifdef PGRN_SUPPORT_ENUM_VARIABLE
 static void
@@ -157,6 +159,19 @@ PGrnLockTimeoutAssign(int new_value, void *extra)
 }
 #endif
 
+static void
+PGrnEnableWALAssign(bool new_value, void *extra)
+{
+	if (new_value)
+	{
+		PGrnXLogEnable();
+	}
+	else
+	{
+		PGrnXLogDisable();
+	}
+}
+
 void
 PGrnInitializeVariables(void)
 {
@@ -210,9 +225,9 @@ PGrnInitializeVariables(void)
 								"Try pgroonga.lock_timeout times "
 								"at 1 msec intervals to "
 								"get write lock in PGroonga.",
-								"The default is 10000000. "
+								"The default is 900000. "
 								"It means that PGroonga tries to get write lock "
-								"between about 2.7 hours.",
+								"between about 15 minutes.",
 								&PGrnLockTimeout,
 								grn_get_lock_timeout(),
 								0,
@@ -223,5 +238,17 @@ PGrnInitializeVariables(void)
 								PGrnLockTimeoutAssign,
 								NULL);
 
+	DefineCustomBoolVariable("pgroonga.enable_wal",
+							 "Enable WAL. (experimental)",
+							 "It requires PostgreSQL 9.6 or later. "
+							 "It's an experimental feature.",
+							 &PGrnEnableWAL,
+							 PGrnXLogGetEnabled(),
+							 PGC_USERSET,
+							 0,
+							 NULL,
+							 PGrnEnableWALAssign,
+							 NULL);
+
 	EmitWarningsOnPlaceholders("pgroonga");
 }

  Added: src/pgrn_xlog.c (+425 -0) 100644
===================================================================
--- /dev/null
+++ src/pgrn_xlog.c    2016-10-24 00:05:05 +0900 (dda9ed9)
@@ -0,0 +1,425 @@
+#include "pgroonga.h"
+
+#include "pgrn_compatible.h"
+
+#include "pgrn_global.h"
+#include "pgrn_xlog.h"
+
+#include <storage/bufmgr.h>
+#include <storage/bufpage.h>
+#include <storage/lmgr.h>
+#include <storage/lockdefs.h>
+
+static bool PGrnXLogEnabled = false;
+
+bool
+PGrnXLogGetEnabled(void)
+{
+	return PGrnXLogEnabled;
+}
+
+void
+PGrnXLogEnable(void)
+{
+	PGrnXLogEnabled = true;
+}
+
+void
+PGrnXLogDisable(void)
+{
+	PGrnXLogEnabled = false;
+}
+
+#ifdef PGRN_SUPPORT_XLOG
+#	include <access/generic_xlog.h>
+#	include <msgpack.h>
+#endif
+
+#ifdef PGRN_SUPPORT_XLOG
+static grn_ctx *ctx = &PGrnContext;
+#endif
+
+#ifdef PGRN_SUPPORT_XLOG
+typedef struct {
+	BlockNumber start;
+	BlockNumber current;
+	BlockNumber end;
+} PGrnMetaPageSpecial;
+
+#define PGRN_PAGE_DATA_SIZE BLCKSZ - SizeOfPageHeaderData - sizeof(OffsetNumber)
+typedef struct {
+	OffsetNumber current;
+	uint8_t data[PGRN_PAGE_DATA_SIZE];
+} PGrnPageSpecial;
+
+typedef struct {
+	GenericXLogState *state;
+	PGrnMetaPageSpecial *metaPageSpecial;
+	Buffer buffer;
+	Page page;
+	PGrnPageSpecial *special;
+} PGrnPageWriteData;
+#endif
+
+struct PGrnXLogData_
+{
+	Relation index;
+#ifdef PGRN_SUPPORT_XLOG
+	GenericXLogState *state;
+	struct
+	{
+		Buffer buffer;
+		Page page;
+		PGrnMetaPageSpecial *pageSpecial;
+	} meta;
+	struct
+	{
+		Buffer buffer;
+		Page page;
+		PGrnPageSpecial *pageSpecial;
+	} current;
+	msgpack_packer packer;
+#endif
+};
+
+#define PGRN_XLOG_META_PAGE_BLOCK_NUMBER 0
+
+#ifdef PGRN_SUPPORT_XLOG
+static void
+PGrnXLogDataInitMeta(PGrnXLogData *data)
+{
+	if (RelationGetNumberOfBlocks(data->index) == 0)
+	{
+		LockRelationForExtension(data->index, ExclusiveLock);
+		data->meta.buffer = ReadBuffer(data->index, P_NEW);
+		LockBuffer(data->meta.buffer, BUFFER_LOCK_EXCLUSIVE);
+		UnlockRelationForExtension(data->index, ExclusiveLock);
+	}
+	else
+	{
+		data->meta.buffer = ReadBuffer(data->index,
+									   PGRN_XLOG_META_PAGE_BLOCK_NUMBER);
+		LockBuffer(data->meta.buffer, BUFFER_LOCK_EXCLUSIVE);
+	}
+
+	data->meta.page = GenericXLogRegisterBuffer(data->state,
+												data->meta.buffer,
+												GENERIC_XLOG_FULL_IMAGE);
+	if (PageIsNew(data->meta.page))
+	{
+		PageInit(data->meta.page, BLCKSZ, sizeof(PGrnMetaPageSpecial));
+		data->meta.pageSpecial =
+			(PGrnMetaPageSpecial *)PageGetSpecialPointer(data->meta.page);
+		data->meta.pageSpecial->start = PGRN_XLOG_META_PAGE_BLOCK_NUMBER + 1;
+		data->meta.pageSpecial->current = data->meta.pageSpecial->start;
+		data->meta.pageSpecial->end = data->meta.pageSpecial->start;
+	}
+	else
+	{
+		data->meta.pageSpecial =
+			(PGrnMetaPageSpecial *)PageGetSpecialPointer(data->meta.page);
+	}
+}
+
+static void
+PGrnXLogDataInitCurrent(PGrnXLogData *data)
+{
+	data->current.buffer = InvalidBuffer;
+	data->current.page = NULL;
+	data->current.pageSpecial = NULL;
+}
+
+static int
+PGrnXLogPageWriter(void *userData,
+				   const char *buffer,
+				   size_t length)
+{
+	PGrnXLogData *data = userData;
+	int written = 0;
+
+	while (written < length)
+	{
+		if (BufferIsInvalid(data->current.buffer))
+		{
+			if (RelationGetNumberOfBlocks(data->index) <=
+				data->meta.pageSpecial->current)
+			{
+				LockRelationForExtension(data->index, ExclusiveLock);
+				data->current.buffer = ReadBuffer(data->index, P_NEW);
+				LockBuffer(data->current.buffer, BUFFER_LOCK_EXCLUSIVE);
+				UnlockRelationForExtension(data->index, ExclusiveLock);
+
+				data->meta.pageSpecial->current =
+					BufferGetBlockNumber(data->current.buffer);
+				data->meta.pageSpecial->end = data->meta.pageSpecial->current;
+			}
+			else
+			{
+				data->current.buffer =
+					ReadBuffer(data->index, data->meta.pageSpecial->current);
+				LockBuffer(data->current.buffer, BUFFER_LOCK_EXCLUSIVE);
+			}
+		}
+
+		if (!PageIsValid(data->current.page))
+		{
+			data->current.page =
+				GenericXLogRegisterBuffer(data->state,
+										  data->current.buffer,
+										  GENERIC_XLOG_FULL_IMAGE);
+			if (PageIsNew(data->current.page))
+			{
+				PageInit(data->current.page, BLCKSZ, sizeof(PGrnPageSpecial));
+				data->current.pageSpecial =
+					(PGrnPageSpecial *)PageGetSpecialPointer(data->current.page);
+				data->current.pageSpecial->current = 0;
+			}
+			else
+			{
+				data->current.pageSpecial =
+					(PGrnPageSpecial *)PageGetSpecialPointer(data->current.page);
+			}
+		}
+
+		if (data->current.pageSpecial->current + length <= PGRN_PAGE_DATA_SIZE)
+		{
+			memcpy(data->current.pageSpecial->data +
+				   SizeOfPageHeaderData +
+				   data->current.pageSpecial->current,
+				   buffer,
+				   length);
+			data->current.pageSpecial->current += length;
+			written += length;
+		}
+		else
+		{
+			size_t writableSize;
+
+			writableSize =
+				PGRN_PAGE_DATA_SIZE - data->current.pageSpecial->current;
+			memcpy(data->current.pageSpecial->data +
+				   SizeOfPageHeaderData +
+				   data->current.pageSpecial->current,
+				   buffer,
+				   writableSize);
+			data->current.pageSpecial->current += writableSize;
+			written += writableSize;
+			length -= writableSize;
+			buffer += writableSize;
+
+			data->current.page = NULL;
+			UnlockReleaseBuffer(data->current.buffer);
+			data->current.buffer = InvalidBuffer;
+			data->meta.pageSpecial->current++;
+		}
+	}
+
+	return written;
+}
+
+static void
+PGrnXLogDataInitMessagePack(PGrnXLogData *data)
+{
+	msgpack_packer_init(&(data->packer), data, PGrnXLogPageWriter);
+}
+#endif
+
+PGrnXLogData *
+PGrnXLogStart(Relation index)
+{
+#ifdef PGRN_SUPPORT_XLOG
+	PGrnXLogData *data;
+
+	if (!PGrnXLogEnabled)
+		return NULL;
+
+	data = palloc(sizeof(PGrnXLogData));
+
+	data->index = index;
+	data->state = GenericXLogStart(data->index);
+
+	PGrnXLogDataInitMeta(data);
+	PGrnXLogDataInitCurrent(data);
+	PGrnXLogDataInitMessagePack(data);
+
+	return data;
+#else
+	return NULL;
+#endif
+}
+
+void
+PGrnXLogFinish(PGrnXLogData *data)
+{
+#ifdef PGRN_SUPPORT_XLOG
+	if (!PGrnXLogEnabled)
+		return;
+
+	GenericXLogFinish(data->state);
+
+	if (data->current.buffer)
+	{
+		UnlockReleaseBuffer(data->current.buffer);
+	}
+	UnlockReleaseBuffer(data->meta.buffer);
+
+	pfree(data);
+#endif
+}
+
+void
+PGrnXLogAbort(PGrnXLogData *data)
+{
+#ifdef PGRN_SUPPORT_XLOG
+	if (!PGrnXLogEnabled)
+		return;
+
+	GenericXLogAbort(data->state);
+
+	if (data->current.buffer)
+	{
+		UnlockReleaseBuffer(data->current.buffer);
+	}
+	UnlockReleaseBuffer(data->meta.buffer);
+
+	pfree(data);
+#endif
+}
+
+void
+PGrnXLogInsertStart(PGrnXLogData *data,
+					size_t nColumns)
+{
+#ifdef PGRN_SUPPORT_XLOG
+	msgpack_packer *packer;
+
+	if (!PGrnXLogEnabled)
+		return;
+
+	packer = &(data->packer);
+	msgpack_pack_map(packer, nColumns);
+#endif
+}
+
+void
+PGrnXLogInsertFinish(PGrnXLogData *data)
+{
+}
+
+void
+PGrnXLogInsertColumnStart(PGrnXLogData *data,
+						  const char *name)
+{
+#ifdef PGRN_SUPPORT_XLOG
+	msgpack_packer *packer;
+	size_t nameSize;
+
+	if (!PGrnXLogEnabled)
+		return;
+
+	packer = &(data->packer);
+
+	nameSize = strlen(name);
+	msgpack_pack_str(packer, nameSize);
+	msgpack_pack_str_body(packer, name, nameSize);
+#endif
+}
+
+void
+PGrnXLogInsertColumnFinish(PGrnXLogData *data)
+{
+}
+
+void
+PGrnXLogInsertColumn(PGrnXLogData *data,
+					 const char *name,
+					 grn_obj *value)
+{
+#ifdef PGRN_SUPPORT_XLOG
+	msgpack_packer *packer;
+
+	if (!PGrnXLogEnabled)
+		return;
+
+	packer = &(data->packer);
+
+	PGrnXLogInsertColumnStart(data, name);
+
+	if (value->header.type != GRN_BULK) {
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("pgroonga: XLog: array value isn't supported yet: <%s>",
+						grn_obj_type_to_string(value->header.type))));
+	}
+
+	switch (value->header.domain)
+	{
+	case GRN_DB_BOOL:
+		if (GRN_BOOL_VALUE(value))
+		{
+			msgpack_pack_true(packer);
+		}
+		else
+		{
+			msgpack_pack_false(packer);
+		}
+		break;
+	case GRN_DB_INT8:
+		msgpack_pack_int8(packer, GRN_INT8_VALUE(value));
+		break;
+	case GRN_DB_UINT8:
+		msgpack_pack_uint8(packer, GRN_UINT8_VALUE(value));
+		break;
+	case GRN_DB_INT16:
+		msgpack_pack_int16(packer, GRN_INT16_VALUE(value));
+		break;
+	case GRN_DB_UINT16:
+		msgpack_pack_uint16(packer, GRN_UINT16_VALUE(value));
+		break;
+	case GRN_DB_INT32:
+		msgpack_pack_int32(packer, GRN_INT32_VALUE(value));
+		break;
+	case GRN_DB_UINT32:
+		msgpack_pack_uint32(packer, GRN_UINT32_VALUE(value));
+		break;
+	case GRN_DB_INT64:
+		msgpack_pack_int64(packer, GRN_INT64_VALUE(value));
+		break;
+	case GRN_DB_UINT64:
+		msgpack_pack_uint64(packer, GRN_UINT64_VALUE(value));
+		break;
+	case GRN_DB_FLOAT:
+		msgpack_pack_double(packer, GRN_FLOAT_VALUE(value));
+		break;
+	case GRN_DB_TIME:
+		msgpack_pack_int64(packer, GRN_TIME_VALUE(value));
+		break;
+	case GRN_DB_SHORT_TEXT:
+	case GRN_DB_TEXT:
+	case GRN_DB_LONG_TEXT:
+		msgpack_pack_str(packer, GRN_TEXT_LEN(value));
+		msgpack_pack_str_body(packer,
+							  GRN_TEXT_VALUE(value),
+							  GRN_TEXT_LEN(value));
+		break;
+	default:
+		{
+			char name[GRN_TABLE_MAX_KEY_SIZE];
+			int nameSize;
+
+			nameSize = grn_table_get_key(ctx,
+										 grn_ctx_db(ctx),
+										 value->header.domain,
+										 name,
+										 GRN_TABLE_MAX_KEY_SIZE);
+			ereport(ERROR,
+					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+					 errmsg("pgroonga: XLog: unsupported type: <%.*s>",
+							nameSize, name)));
+		}
+		break;
+	}
+
+	PGrnXLogInsertColumnFinish(data);
+#endif
+}

  Added: src/pgrn_xlog.h (+24 -0) 100644
===================================================================
--- /dev/null
+++ src/pgrn_xlog.h    2016-10-24 00:05:05 +0900 (8f185c3)
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <postgres.h>
+#include <utils/relcache.h>
+
+#include <groonga.h>
+
+typedef struct PGrnXLogData_ PGrnXLogData;
+
+bool PGrnXLogGetEnabled(void);
+void PGrnXLogEnable(void);
+void PGrnXLogDisable(void);
+
+PGrnXLogData *PGrnXLogStart(Relation index);
+void PGrnXLogFinish(PGrnXLogData *data);
+void PGrnXLogAbort(PGrnXLogData *data);
+
+void PGrnXLogInsertStart(PGrnXLogData *data, size_t nColumns);
+void PGrnXLogInsertFinish(PGrnXLogData *data);
+void PGrnXLogInsertColumnStart(PGrnXLogData *data, const char *name);
+void PGrnXLogInsertColumnFinish(PGrnXLogData *data);
+void PGrnXLogInsertColumn(PGrnXLogData *data,
+						  const char *name,
+						  grn_obj *value);

  Modified: src/pgroonga.c (+20 -6)
===================================================================
--- src/pgroonga.c    2016-10-23 00:44:10 +0900 (4e35010)
+++ src/pgroonga.c    2016-10-24 00:05:05 +0900 (d4a58d9)
@@ -16,13 +16,11 @@
 #include "pgrn_search.h"
 #include "pgrn_value.h"
 #include "pgrn_variables.h"
+#include "pgrn_xlog.h"
 
 #ifdef PGRN_SUPPORT_CREATE_ACCESS_METHOD
 #	include <access/amapi.h>
 #endif
-#ifdef PGRN_SUPPORT_XLOG
-#	include <access/generic_xlog.h>
-#endif
 #ifdef PGRN_SUPPORT_OPTIONS
 #	include <access/reloptions.h>
 #endif
@@ -1932,11 +1930,17 @@ PGrnInsert(Relation index,
 {
 	TupleDesc desc = RelationGetDescr(index);
 	grn_id id;
+	PGrnXLogData *xlogData;
 	unsigned int i;
 
 	id = grn_table_add(ctx, sourcesTable, NULL, 0, NULL);
+
+	xlogData = PGrnXLogStart(index);
+	PGrnXLogInsertStart(xlogData, desc->natts + 1);
+
 	GRN_UINT64_SET(ctx, &(buffers->ctid), CtidToUInt64(ht_ctid));
 	grn_obj_set_value(ctx, sourcesCtidColumn, id, &(buffers->ctid), GRN_OBJ_SET);
+	PGrnXLogInsertColumn(xlogData, "ctid", &(buffers->ctid));
 
 	for (i = 0; i < desc->natts; i++)
 	{
@@ -1945,6 +1949,7 @@ PGrnInsert(Relation index,
 		NameData *name;
 		grn_id domain;
 		unsigned char flags;
+		grn_obj *buffer;
 
 		name = &(attribute->attname);
 		if (isnull[i])
@@ -1952,22 +1957,31 @@ PGrnInsert(Relation index,
 
 		dataColumn = PGrnLookupColumn(sourcesTable, name->data, ERROR);
 
+		buffer = &(buffers->general);
 		if (PGrnAttributeIsJSONB(attribute->atttypid))
 		{
-			PGrnJSONBInsert(index, values, i, &(buffers->general));
+			/* PGrnXLogInsertColumnStart(xlogData, name->data); */
+			PGrnJSONBInsert(index, values, i, buffer, xlogData);
+			grn_obj_set_value(ctx, dataColumn, id, buffer, GRN_OBJ_SET);
+			/* PGrnXLogInsertColumnFinish(xlogData); */
+			PGrnXLogInsertColumn(xlogData, name->data, buffer);
 		}
 		else
 		{
 			domain = PGrnGetType(index, i, &flags);
 			grn_obj_reinit(ctx, &(buffers->general), domain, flags);
-			PGrnConvertFromData(values[i], attribute->atttypid, &(buffers->general));
+			PGrnConvertFromData(values[i], attribute->atttypid, buffer);
+			grn_obj_set_value(ctx, dataColumn, id, buffer, GRN_OBJ_SET);
+			PGrnXLogInsertColumn(xlogData, name->data, buffer);
 		}
-		grn_obj_set_value(ctx, dataColumn, id, &(buffers->general), GRN_OBJ_SET);
 		grn_obj_unlink(ctx, dataColumn);
 		if (!PGrnCheck("pgroonga: failed to set column value")) {
 			continue;
 		}
 	}
+
+	PGrnXLogInsertFinish(xlogData);
+	PGrnXLogFinish(xlogData);
 }
 
 static bool
-------------- next part --------------
HTML����������������������������...
Download 



More information about the Groonga-commit mailing list
Back to archive index