2.3. Các hàm mở rộng trong ngôn ngữ C
2.3.2. Các kiểu dữ liệu cơ sở trong C
Kiểu dữ liệu cơ sở tuõn theo một trong ba dạng sau ủõy:
• Truyền bởi giỏ trị, ủộ dài cố ủịnh (pass by value, fixed-length)
• Truyền bởi tham chiếu, ủộ dài cố ủịnh (pass by reference, fixed-length)
• Truyền bởi tham chiếu, ủộ dài thay ủổi (pass by reference, variable- length)
Kiểu by-value chỉ cú ủộ dài là 1, 2 hoặc 4 byte (hoặc cú thể là 8 nếu sizeof(Datum) là 8). Cần chỳ ý ủến kiểu long vỡ nú cú ủộ lớn 4 bytes trong một số mỏy và 8 bytes trong mỏy khỏc, trong khi ủú, kiểu int là 4 bytes trong hầu hết cỏc mỏy cài ủặt hệ ủiều hành Unix. Một khai bỏo chấp nhận ủược với kiểu int4 trong một mỏy Unix cú thể ủược thực hiện như sau:
/* 4-byte integer, passed by value */
typedef int int4;
Kiểu cú ủộ dài cố ủịnh (fixed-length) cũng cú thể ủược truyền bởi tham chiếu như ủịnh nghĩa kiểu Point trong PostgreSQL như sau:
/* 16-byte structure, passed by reference */
typedef struct {
double x, y;
} Point;
Chỉ cú cỏc con trỏ tới kiểu dữ liệu này ủược sử dụng khi truyền tham số cho hàm trong PostgreSQL. ðể trả về một giá trị với kiểu dữ liệu này, người ta phải cấp phỏt một vựng nhớ phự hợp bằng cõu lệnh palloc, ghi vào vựng nhớ ủược chỉ ủịnh và gửi trả về một con trỏ tới vựng nhớ ủú.
Cỏc kiểu cú ủộ dài thay ủổi (variable-length) phải ủược truyền bởi tham chiếu và phải ủược bắt ủầu bởi một trường ủộ dài 4 bytes. Dữ liệu ủược lưu trong kiểu này phải ủược phõn vựng trong bộ nhớ ngay sau trường ủộ dài. Trường ủộ dài
mang giỏ trị là ủộ lớn của cấu trỳc dữ liệu, bao gồm cả ủộ lớn của ban thõn nú (4 bytes).
Chỳng ta cú thể ủịnh nghĩa kiểu text như sau:
typedef struct { int4 length;
char data[1];
} text;
Trong vớ dụ này, trường data ủược khai bỏo khụng ủủ lớn nếu muốn chứa cỏc chuỗi cú ủộ dài lớn hơn. Trong thực tế, chỳng ta khụng thể khai bỏo một cấu trỳc cú kớch thước thay ủổi trong C nờn người ta dựa vào việc trỡnh biờn dịch C khụng kiểm tra cỏc chỉ số mảng tại thời ủiểm khai bỏo ủể cấp phỏt dung lượng bộ nhớ phự hợp khi cần sử dụng và truy cập ủến mảng như thể nú ủó ủược khai bỏo ủỳng.
Khi sử dụng cỏc kiểu dữ liệu cú ủộ dài thay ủổi, chỳng ta phải cõn nhắc ủể cấp phỏt dung lượng bộ nhớ phự hợp và thiết lập giỏ trị chớnh xỏc cho trường ủộ dài. Vớ dụ, nếu muốn lưu trữ 40 bytes trong cấu trỳc text, người ta sử dụng ủoạn mã như sau:
#include "postgres.h"
...
char buffer[40]; /* our source data */
...
text *destination = (text *) palloc(VARHDRSZ + 40);
destination->length = VARHDRSZ + 40;
memcpy(destination->data, buffer, 40);
...
VARHDRSZ cũng giống nhưsizeof(int4), tuy nhiờn, ủõy ủược xem là phương phỏp tốt nhất khi sử dụng marco này ủịnh vị chớnh xỏc cỏc kiểu dữ liệu cú ủộ dài thay ủổi.
Bảng 2.1 miêu tả các kiểu dữ liệu trong C và kiểu dữ liệu trong SQL tương ứng khi viết các hàm C sử dụng kiểu dữ liệu có sẵn trong PostgreSQL. Cột “ðược ủịnh nghĩa tại” ủưa ra tờn file tiờu ủề (header file) cần thiết ủể sử dụng kiểu ủược ủịnh nghĩa. Cần lưu ý rằng, chỳng ta luụn luụn phải ủặt thư viện postgres.h trước tiên trong mọi file chương trình bởi vì nó mô tả rất nhiều cấu trúc cần thiết.
Kiểu dữ liệu SQL Kiểu dữ liệu C ðược ủịnh nghĩa tại
Abstime AbsoluteTime utils/nabstime.h
Boolean bool postgres.h (maybe compiler built-in)
box BOX* utils/geo_decls.h
bytea bytea* postgres.h
"char" char (compiler built-in)
character BpChar* postgres.h
cid CommandId postgres.h
date DateADT utils/date.h
smallint (int2) int2 or int16 postgres.h int2vector int2vector* postgres.h integer (int4) int4 or int32 postgres.h real (float4) float4* postgres.h
double precision (float8)
float8* postgres.h
interval Interval* utils/timestamp.h
lseg LSEG* utils/geo_decls.h
name Name postgres.h
oid Oid postgres.h
oidvector oidvector* postgres.h
path PATH* utils/geo_decls.h
point POINT* utils/geo_decls.h
regproc regproc postgres.h
reltime RelativeTime utils/nabstime.h
text text* postgres.h
tid ItemPointer storage/itemptr.h
time TimeADT utils/date.h
time with time zone TimeTzADT utils/date.h timestamp Timestamp* utils/timestamp.h tinterval TimeInterval utils/nabstime.h
varchar VarChar* postgres.h
xid TransactionId postgres.h
Bảng 2. 1Cỏc kiểu dữ liệu trong C và cỏc kiểu ủược ủịnh nghĩa tương ứng trong SQL