ソースコードを微調整する気がある場合は、PostgreSQL で次の操作を実行できます。
まず、いくつかの注意事項:
- それを行うのは本当に悪い考えです。これは教育目的でのみ役立ちます。1 つ目は速度が低下するため、2 つ目はサーバーがクラッシュする可能性があるためです (適切にテストしていません)。
- PostgreSQL 9.2 で次のことを試しました。他のバージョンでも動作するはずですが、試していません。
ここでのアイデアは、まず、タプルを文字列にダンプする関数を作成することです。簡単にするためにsrc/include/debugtuple.h
、次のように(pgソース内に)という名前のファイルを作成しました。
#ifndef _DEBUGTUPLE_H_
#define _DEBUGTUPLE_H_
#include "postgres.h"
#include "access/relscan.h"
#include "executor/execdebug.h"
#include "utils/rel.h"
static void InitScanRelation(SeqScanState *node, EState *estate);
static TupleTableSlot *SeqNext(SeqScanState *node);
static char *
ExecBuildSlotValueDescription(TupleTableSlot *slot, int maxfieldlen)
{
StringInfoData buf;
TupleDesc tupdesc = slot->tts_tupleDescriptor;
int i;
/* Make sure the tuple is fully deconstructed */
slot_getallattrs(slot);
initStringInfo(&buf);
appendStringInfoChar(&buf, '(');
for (i = 0; i < tupdesc->natts; i++)
{
char *val;
int vallen;
if (slot->tts_isnull[i])
val = "null";
else
{
Oid foutoid;
bool typisvarlena;
getTypeOutputInfo(tupdesc->attrs[i]->atttypid,
&foutoid, &typisvarlena);
val = OidOutputFunctionCall(foutoid, slot->tts_values[i]);
}
if (i > 0)
appendStringInfoString(&buf, ", ");
/* truncate if needed */
vallen = strlen(val);
if (vallen <= maxfieldlen)
appendStringInfoString(&buf, val);
else
{
vallen = pg_mbcliplen(val, vallen, maxfieldlen);
appendBinaryStringInfo(&buf, val, vallen);
appendStringInfoString(&buf, "...");
}
}
appendStringInfoChar(&buf, ')');
return buf.data;
}
#endif
src/backend/executor/
ここで、nodeSeqscan.c
とにある 2 つのファイルを編集する必要があります。nodeIndexscan.c
両方に、上記で作成したファイルを含めます (ファイルの先頭に)。
#include "debugtuple.h"
でnodeSeqscan.c
、関数を見つけてSeqNext
、次のように編集します (これらの 2 行だけを追加します)。
static TupleTableSlot *
SeqNext(SeqScanState *node)
{
[...]
ExecClearTuple(slot);
/* ADD THE TWO FOLLOWING LINES: */
if (slot && slot->tts_tuple)
elog(NOTICE, "Seq Scan processed: %s", ExecBuildSlotValueDescription(slot, 1000));
return slot;
}
nodeIndexscan.c
次に、関数で同じことを行いますIndexNext
:
static TupleTableSlot *
IndexNext(IndexScanState *node)
{
[...]
while ((tuple = index_getnext(scandesc, direction)) != NULL)
{
[...]
/* ADD THE TWO FOLLOWING LINES: */
if (slot && slot->tts_tuple)
elog(NOTICE, "Index Scan processed: %s", ExecBuildSlotValueDescription(slot, 1000));
return slot;
}
...
return ExecClearTuple(slot);
}
最後に、ソース コードのルートに移動して再コンパイルします。
make && make install
seqscan
現在、この変更されたバージョンは、 or indexscan
(およびそれらのみ)で処理するすべてのタプルで NOTICE メッセージを発生させます。elog
関数呼び出しで行を変更して、必要なことを行うことができます。
楽しむ。