debi12345 писал(а):Как там приткнуть Паскаль - ума не приложу. Только если бы весь Постгрес был был на Паскале написан
Очень разумное суждение, если разработчики API не ориентировались на препроцессор, то API был бы намного лучше.
хорошо. Предлагаю хотя бы одну функцию рассмотреть.
- Код: Выделить всё
Datum
numeric_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
#ifdef NOT_USED
Oid typelem = PG_GETARG_OID(1);
#endif
int32 typmod = PG_GETARG_INT32(2);
NumericVar value;
Numeric res;
/*
* Check for NaN
*/
if (pg_strcasecmp(str, "NaN") == 0)
PG_RETURN_NUMERIC(make_result(&const_nan));
/*
* Use set_var_from_str() to parse the input string and return it in the
* packed DB storage format
*/
init_var(&value);
set_var_from_str(str, &value);
apply_typmod(&value, typmod);
res = make_result(&value);
free_var(&value);
PG_RETURN_NUMERIC(res);
}
Вся свистопляска PG_ макросов начинается с
PG_FUNCTION_ARGS.
PG_FUNCTION_ARGS - диктует имя параметра переданного в функцию fcinfo (тип FunctionCallInfo)
Все остальные макросы вроде PG_GETARG_CSTRING или PG_GETARG_INT32, реализованы через PG_GETARG_DATUM, который строго привязан к PG_FUNCTION_ARGS, т.к. зависит от имени параметра функции fcinfo.
Перенести на паскаль один в один не получится, но если добавить в получающиеся PG_хххх функции параметр для fcinfo, то остальное переносится на раз.
хеадер (

) postgresapi в паскале может выглядеть примерно так:
- Код: Выделить всё
unit postgresapi;
interface
const
FUNC_MAX_ARGS = 100;
type
Datum = PtrUInt;
FunctionCallInfoData = record
// blah
arg : array [0..FUNC_MAX_ARGS-1] of Datum;
// blah
end;
FunctionCallInfo = ^FunctionCallInfoData;
function PG_GETARG_DATUM(fcinfo: FunctionCallInfo; n: integer): Integer; inline;
function PG_GETARG_INT32(fcinfo: FunctionCallInfo; n: integer): Integer; inline;
function PG_GETARG_CSTRING(fcinfo: FunctionCallInfo; n: integer): PChar; inline; // DatumGetCString(PG_GETARG_DATUM(n))
function DatumGetInt32(const d: Datum): Integer; inline;
function DatumGetCString(const d: Datum): PChar; inline;
function DatumGetPointer(const d: Datum): Pointer; inline;
function GET_4_BYTES(const d: Datum): LongWord; inline;
implementation
function GET_4_BYTES(const d: Datum): LongWord; inline;
begin
Result:=d and $FFFFFFFF;
end;
function PG_GETARG_DATUM(fcinfo: FunctionCallInfo; n: integer): Datum;
begin
Result:=fcinfo^.arg[n];
end;
function PG_GETARG_INT32(fcinfo: FunctionCallInfo; n: integer): Integer;
begin
Result:=DatumGetInt32(PG_GETARG_DATUM(fcinfo, n));
end;
function DatumGetInt32(const d: Datum): Integer; inline;
begin
Result:=Integer(GET_4_BYTES(d));
end;
function PG_GETARG_CSTRING(fcinfo: FunctionCallInfo; n: integer): PChar; inline;
begin
Result:=DatumGetCString(PG_GETARG_DATUM(fcinfo, n));
end;
function DatumGetCString(const d: Datum): PChar; inline;
begin
Result:=PChar(DatumGetPointer(d));
end;
function DatumGetPointer(const d: Datum): Pointer; inline;
begin
Result:=Pointer(d);
end;
end.
соотстветнно использование этих функций следующее. Основное отличие от С, что fcinfo нужно передавать явно.
- Код: Выделить всё
uses
postgres;
function numeric_in(fcinfo: FunctionCallInfo): Datum;
var
str: PChar;
typmod: integer;
begin
str := PG_GETARG_CSTRING(fcinfo, 0);
...
typmod := PG_GETARG_INT32(fcinfo, 2);
Ковырять дальше к PG_RETURN_NUMERIC , или конкретные места интересуют?