在使用C语言开发PostgreSQL后端(backend)、客户端(client)应用时,Datum无处不在,所以必须要对Datum有很清楚的了解。这里的backend应用是指诸如自户自定义函数、扩展等同PostgreSQL服务一起工作的应用;客户端则是通过调用libpq访问数据库的应用。Datum数据类型在postgres.h中定义,这个头文件通常是第一个要include的,对于客户端应用则是postgres_fe.h。
根据官方文档的解释,Datum包含一个按值传递类型(通常是比较简单的数据类型,比如整数)或者一个引用类型(通常是一个指针,指向一些比较复杂的类型,比如struct),因此有如下要求:
sizeof(Datum) ==sizeof(void*) ==4or8
Datum定义如下:
typedefuintptr_tDatum;
PostgreSQL提供了一些函数用于在Datum与适当的类型间进行转换。
NullableDatum
NullableDatum结构用于保存Datum数据或者数据为空值时指示数据为空。
typedefstructNullableDatum{ Datumvalue; boolisnull; /* due to alignment padding this could be used for flags for free */} NullableDatum;
DatumGetBool
从datum中返回bool值,非0值会被转换成true。
staticinlineboolDatumGetBool(DatumX) { return (X!=0); }
BoolGetDatum
将bool值转换成datum,非零值被转换成true。
staticinlineDatumBoolGetDatum(boolX) { return (Datum) (X?1 : 0); }
DatumGetChar
从datum返回char值。
staticinlinecharDatumGetChar(DatumX) { return (char) X; }
CharGetDatum
/** CharGetDatum* Returns datum representation for a character.*/staticinlineDatumCharGetDatum(charX) { return (Datum) X; }
Int8GetDatum
/** Int8GetDatum* Returns datum representation for an 8-bit integer.*/staticinlineDatumInt8GetDatum(int8X) { return (Datum) X; }
DatumGetUInt8
/** DatumGetUInt8* Returns 8-bit unsigned integer value of a datum.*/staticinlineuint8DatumGetUInt8(DatumX) { return (uint8) X; }
UInt8GetDatum
/** UInt8GetDatum* Returns datum representation for an 8-bit unsigned integer.*/staticinlineDatumUInt8GetDatum(uint8X) { return (Datum) X; }
DatumGetInt16
/** DatumGetInt16* Returns 16-bit integer value of a datum.*/staticinlineint16DatumGetInt16(DatumX) { return (int16) X; }
Int16GetDatum
/** Int16GetDatum* Returns datum representation for a 16-bit integer.*/staticinlineDatumInt16GetDatum(int16X) { return (Datum) X; }
DatumGetUInt16
/** DatumGetUInt16* Returns 16-bit unsigned integer value of a datum.*/staticinlineuint16DatumGetUInt16(DatumX) { return (uint16) X; }
UInt16GetDatum
/** UInt16GetDatum* Returns datum representation for a 16-bit unsigned integer.*/staticinlineDatumUInt16GetDatum(uint16X) { return (Datum) X; }
DatumGetInt32
/** DatumGetInt32* Returns 32-bit integer value of a datum.*/staticinlineint32DatumGetInt32(DatumX) { return (int32) X; }
Int32GetDatum
/** Int32GetDatum* Returns datum representation for a 32-bit integer.*/staticinlineDatumInt32GetDatum(int32X) { return (Datum) X; }
DatumGetUInt32
/** DatumGetUInt32* Returns 32-bit unsigned integer value of a datum.*/staticinlineuint32DatumGetUInt32(DatumX) { return (uint32) X; }
UInt32GetDatum
/** UInt32GetDatum* Returns datum representation for a 32-bit unsigned integer.*/staticinlineDatumUInt32GetDatum(uint32X) { return (Datum) X; }
DatumGetObjectId
/** DatumGetObjectId* Returns object identifier value of a datum.*/staticinlineOidDatumGetObjectId(DatumX) { return (Oid) X; }
ObjectIdGetDatum
/** ObjectIdGetDatum* Returns datum representation for an object identifier.*/staticinlineDatumObjectIdGetDatum(OidX) { return (Datum) X; }
DatumGetTransactionId
/** DatumGetTransactionId* Returns transaction identifier value of a datum.*/staticinlineTransactionIdDatumGetTransactionId(DatumX) { return (TransactionId) X; }
TransactionIdGetDatum
/** TransactionIdGetDatum* Returns datum representation for a transaction identifier.*/staticinlineDatumTransactionIdGetDatum(TransactionIdX) { return (Datum) X; }
MultiXactIdGetDatum
/** MultiXactIdGetDatum* Returns datum representation for a multixact identifier.*/staticinlineDatumMultiXactIdGetDatum(MultiXactIdX) { return (Datum) X; }
DatumGetCommandId
/** DatumGetCommandId* Returns command identifier value of a datum.*/staticinlineCommandIdDatumGetCommandId(DatumX) { return (CommandId) X; }
CommandIdGetDatum
/** CommandIdGetDatum* Returns datum representation for a command identifier.*/staticinlineDatumCommandIdGetDatum(CommandIdX) { return (Datum) X; }
DatumGetPointer
/** DatumGetPointer* Returns pointer value of a datum.*/staticinlinePointerDatumGetPointer(DatumX) { return (Pointer) X; }
PointerGetDatum
/** PointerGetDatum* Returns datum representation for a pointer.*/staticinlineDatumPointerGetDatum(constvoid*X) { return (Datum) X; }
DatumGetCString
/** DatumGetCString* Returns C string (null-terminated string) value of a datum.** Note: C string is not a full-fledged Postgres type at present,* but type input functions use this conversion for their inputs.*/staticinlinechar*DatumGetCString(DatumX) { return (char*) DatumGetPointer(X); }
CStringGetDatum
/** CStringGetDatum* Returns datum representation for a C string (null-terminated string).** Note: C string is not a full-fledged Postgres type at present,* but type output functions use this conversion for their outputs.* Note: CString is pass-by-reference; caller must ensure the pointed-to* value has adequate lifetime.*/staticinlineDatumCStringGetDatum(constchar*X) { returnPointerGetDatum(X); }
DatumGetName
/** DatumGetName* Returns name value of a datum.*/staticinlineNameDatumGetName(DatumX) { return (Name) DatumGetPointer(X); }
NameGetDatum
/** NameGetDatum* Returns datum representation for a name.** Note: Name is pass-by-reference; caller must ensure the pointed-to* value has adequate lifetime.*/staticinlineDatumNameGetDatum(constNameData*X) { returnCStringGetDatum(NameStr(*X)); }
DatumGetInt64
/** DatumGetInt64* Returns 64-bit integer value of a datum.** Note: this function hides whether int64 is pass by value or by reference.*/staticinlineint64DatumGetInt64(DatumX) { return (int64) X; return*((int64*) DatumGetPointer(X)); }
Int64GetDatum
/** Int64GetDatum* Returns datum representation for a 64-bit integer.** Note: if int64 is pass by reference, this function returns a reference* to palloc'd space.*/staticinlineDatumInt64GetDatum(int64X) { return (Datum) X; } externDatumInt64GetDatum(int64X);
DatumGetUInt64
/** DatumGetUInt64* Returns 64-bit unsigned integer value of a datum.** Note: this function hides whether int64 is pass by value or by reference.*/staticinlineuint64DatumGetUInt64(DatumX) { return (uint64) X; return*((uint64*) DatumGetPointer(X)); }
UInt64GetDatum
/** UInt64GetDatum* Returns datum representation for a 64-bit unsigned integer.** Note: if int64 is pass by reference, this function returns a reference* to palloc'd space.*/staticinlineDatumUInt64GetDatum(uint64X) { return (Datum) X; returnInt64GetDatum((int64) X); }
DatumGetFloat4
/** Float <-> Datum conversions** These have to be implemented as inline functions rather than macros, when* passing by value, because many machines pass int and float function* parameters/results differently; so we need to play weird games with unions.*//** DatumGetFloat4* Returns 4-byte floating point value of a datum.*/staticinlinefloat4DatumGetFloat4(DatumX) { union { int32value; float4retval; } myunion; myunion.value=DatumGetInt32(X); returnmyunion.retval; }
Float4GetDatum
/** Float4GetDatum* Returns datum representation for a 4-byte floating point number.*/staticinlineDatumFloat4GetDatum(float4X) { union { float4value; int32retval; } myunion; myunion.value=X; returnInt32GetDatum(myunion.retval); }
DatumGetFloat8
/** DatumGetFloat8* Returns 8-byte floating point value of a datum.** Note: this function hides whether float8 is pass by value or by reference.*/staticinlinefloat8DatumGetFloat8(DatumX) { union { int64value; float8retval; } myunion; myunion.value=DatumGetInt64(X); returnmyunion.retval; return*((float8*) DatumGetPointer(X)); }
Float8GetDatum
/** Float8GetDatum* Returns datum representation for an 8-byte floating point number.** Note: if float8 is pass by reference, this function returns a reference* to palloc'd space.*/staticinlineDatumFloat8GetDatum(float8X) { union { float8value; int64retval; } myunion; myunion.value=X; returnInt64GetDatum(myunion.retval); } externDatumFloat8GetDatum(float8X);