BÁO CÁO BỔ SUNG HÀM MỞ RỘNG VIẾT BẰNG C VÀO HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU POSTGRESQL

11 336 0
BÁO CÁO BỔ SUNG HÀM MỞ RỘNG VIẾT BẰNG C VÀO HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU POSTGRESQL

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

ĐẠI HỌC QUỐC GIA HÀ NỘI ĐẠI HỌC CÔNG NGHỆ BÁO CÁO BỔ SUNG HÀM MỞ RỘNG VIẾT BẰNG C VÀO HỆ QUẢN TRỊ CƠ SỞ DỮ LIỆU POSTGRESQL Học viên: Bùi Hoàng Khánh Lớp K16T3 Hà Nội, 03/2010 MỤC LỤC MỤC LỤC Tính mở rộng PostgreSQL .3 Hàm viết ngôn ngữ C Kết luận 10 TÀI LIỆU THAM KHẢO 11 Tính mở rộng PostgreSQL I.1 Tính mở rộng PosgreSQL PostgreSQL giống với hệ sở liệu quan chuẩn hệ khác, lưu trữ thông tin sở liệu, bảng, cột… gọi danh mục hệ thống (system catalogs) (còn gọi thư viện liệu) Các danh mục giống bảng người dùng Một điểm khác biệt PostgreSQL với hệ sở liệu quan hệ chuẩn PostgreSQL lưu nhiều thông tin danh mục: thông tin bảng cột, mà thông tin kiểu liệu, hàm, phương thức truy cập… Những bảng người dùng thay đổi PostgreSQL hoạt động dựa này, nên người dùng mở rộng I.2 Hàm người dùng định nghĩa PostgreSQL cung cấp loại hàm người dùng định nghĩa, gồm: - Các hàm ngôn ngữ truy vấn (được viết SQL) Các hàm ngôn ngữ thủ tục (được viết PL/pgSQL PL/Tcl) Các nội hàm Các hàm ngôn ngữ C Các loại hàm sử dụng kiểu liệu bản, phức hợp kết hợp hai loại làm tham số vào Các hàm định nghĩa để trả loại liệu khác nhau: sơ, phức hợp, kết hợp Nhiều loại nhận trả kiểu liệu giả (pseudotypes), kiểu đa hình Hàm viết ngôn ngữ C Hàm người dùng định nghĩa viết ngôn ngữ C ngôn ngữ tương thích với C C++ Những hàm biên dịch thành đối tượng tải động (dinamically loadable objects) (còn gọi thư viện chia sẻ) tải vào máy chủ cần Tính tải động phân biệt hàm ngôn ngữ C với hàm bên – thực tế quy định lập trình giống Có cách để gọi hàm viết C: - Cách thứ viết macro PG_FUNCTION_INFO_V1() cho hàm, gọi version Cách thứ hai không sử dụng macro trên, gọi version Cách khó linh hoạt thiếu số chức Tuy nhiên, phát triển khả tương thích Cả hai cách phải xác định tên ngôn ngữ CREATE FUNCTION C I.3 Quá trình tải động Như trình bày, hàm ngôn ngữ C tải động server cần Lần hàm người dùng định nghĩa file đối tượng tải gọi phiên, tải động file đối tượng vào nhớ Như vậy, CREATE FUNCTION phải xác định thông tin hàm là: tên file đối tượng, tên C hàm file đối tượng Nếu tên C không xác định lấy tên giống với tên hàm SQL Thuật toán để xác định vị trí file đối tượng dựa vào tên đưa CREATE FUNCTION sau: Nếu tên đường dẫn tuyệt đối file tải Nếu tên bắt đầu $libdir, phần thay tên đường dẫn thư viện PostgreSQL, xác định lúc build Nếu tên không chứa thành phần thư mục, file tìm đường dẫn xác định tham số cấu hình dymamic_library_path Ngược lại (file không tìm thấy đường dẫn, chứa đường dẫn không tuyệt đối), tải động thử để lấy tên đưa Nếu bước không làm việc phần mở rộng thư viện chia (thường so) thêm vào cuối tên file thực lại bước Một ý nên lưu đối tượng thư mục thư viện động $libdir, xác định lệnh pg_config –-pkglibdir Sau lần sử dụng đầu tiên, đối tượng tải động lưu nhớ Những lần gọi phiên đến hàm file cần tìm bảng đối tượng Nếu cần tải lại đối tượng sử dụng lệnh LOAD bắt đầu phiên I.4 Các kiểu liệu hàm ngôn ngữ C Để viết hàm ngôn ngữ C, cần biết cách PostgreSQL biểu diễn kiểu liệu cách chúng truyền vào trả Các hàm tự định nghĩa cần lưu ý phải dựa vào quy tắc định nghĩa PostgreSQL, để chạy hàm tự bạn xây dựng Như vậy, PostgreSQL lưu trữ lấy liệu từ ổ đĩa sử dụng hàm tự định nghĩa để nhập, xử lý, đưa liệu Dữ liệu PostgreSQL ba dạng sau: - Dạng 1: Truyền giá trị, có độ dài cố định Độ dài 1, 2, bytes (cũng bytes).Có thể xác định độ dài sizeof() Ví dụ sử dụng kiểu int máy Unix: Typedef int int4; - Dạng 2: Truyền tham chiếu, có độ dài cố định Khi truyền liệu vào khỏi hàm PostgreSQL phải sử dụng trỏ Để trả lại giá trị biến, phải cấp vùng nhớ thông qua palloc, để trỏ trỏ tới Ví dụ: typedef struct { double x, y; } Point; - Dạng 3: Truyền tham chiếu, có độ dài thay đổi Loại này, tất liệu phải bắt đầu trường có độ dài bytes, lưu trữ vùng nhớ kiểu liệu, độ dài Kích thước liệu bao gồm tổng độ dài cấu trúc (bao gồm kích thước nó) Ví dụ: typedef struct { int4 length; char data[1]; } text; text *destination; Các kiểu liệu tương ứng SQL C xây dựng sẵn PostgreSQL tham khảo Table 31-1 Equivalent C Types for Built-In SQL Types tài liệu PostgreSQL 8.0.0 Documentation I.5 Gọi hàm viết ngôn ngữ C I.5.1 Version - Không sử dụng macro PG_FUNCTION_INFO_V1() Như trình bày trên, cách không thích hợp, dễ điều khiển khởi tạo Các tham số vào kết hàm C khai báo dạng C bình thường, phải cẩn thận việc sử dụng C để biểu diễn kiểu liệu SQL Mặc dù sử dụng đơn giản, không khả chuyển Có số vấn đề việc truyền kiểu liệu có kích thước nhỏ kiểu int số kiến trúc Và không đơn giản trả kết null nhận tham số null Dưới ví dụ thực thêm hàm mở rộng C vào PostgreSQL theo cách này: funcs.c #include "postgres.h" #include /* by value */ int add_one(int arg) { return arg + 1; } /* by reference, fixed length */ float8 * add_one_float8(float8 *arg) { float8 *result = (float8 *) palloc(sizeof(float8)); *result = *arg + 1.0; return result; } /* by reference, variable length */ text * copytext(text *t) { /* * VARSIZE is the total size of the struct in bytes */ text *new_t = (text *) palloc(VARSIZE(t)); VARATT_SIZEP(new_t) = VARSIZE(t); memcpy((void *) VARDATA(new_t), (void *) VARDATA(t), VARSIZE(t)-VARHDRSZ); return new_t; } Bảng 1: Chương trình viết C File Funcs.c biên dịch thành đối tượng chia với tên funcs.so, sau đưa vào PostgreSQL sau: CREATE FUNCTION add_one(integer) RETURNS integer AS ’DIRECTORY/funcs’, ’add_one’ LANGUAGE C STRICT; CREATE FUNCTION add_one(double precision) RETURNS double precision AS ’DIRECTORY/funcs’, ’add_one_float8’ LANGUAGE C STRICT; CREATE FUNCTION copytext(text) RETURNS text AS ’DIRECTORY/funcs’, ’copytext’ LANGUAGE C STRICT; Bảng 2: Lệnh SQL tạo extender Ở DIRECTORY tên đường dẫn đến thư mục dùng chung Có thể bỏ phần mở rộng so Chú ý phải xác định hàm STRICT, có nghĩa hệ thống giả định kết null cách tự động giá trị đầu vào null Bằng cách này, không cần phải kiểm tra giá trị đầu vào null chương trình; ngược lại, phải kiểm tra với đối số truyền tham chiếu (với đối số truyền giá trị cách kiểm tra cả) I.5.2 Version - Sử dụng macro PG_FUNCTION_INFO_V1() Cách sử dụng macro để hạn chế phức tạp việc truyền đối số trả kết Chương trình C cách cấu trúc file mã nguồn sau: PG_FUNCTION_INFO_V1(func_name); Datum func_name(PG_FUNCTION_ARGS) { } Hai lệnh phải xuất file mã nguồn PG_FUNCTION_INFO_V1() quy ước viết trước hàm Macro không cần thiết cho hàm hàm bên trong, PostgreSQL thừa nhận tất hàm sử dụng quy ước phiên Tuy nhiên, cần cho hàm nạp tải động (dynamically-loaded functions) Trong phiên này, đối số truyền vào cách sử dụng macro PG_GETARG_xxx(), kết trả cách sử dụng macro PG_RETURN_xxx() PG_GETARG_xxx() có đối số số đối số hàm truyền vào, 0; ví dụ PG_RETURN_INT32(0) trả đối số với kiểu int32 PG_RETURN_xxx() có đối số giá trị thực để trả về; ví dụ PG_RETURN_FLOAT4(0.5)trả số thực có giá trị 0.5 Dưới ví dụ thực thêm hàm mở rộng C vào PostgreSQL theo cách dùng macro: Functs.c #include "postgres.h" #include #include "fmgr.h" /* by value */ PG_FUNCTION_INFO_V1(add_one); Datum add_one(PG_FUNCTION_ARGS) { int32 arg = PG_GETARG_INT32(0); PG_RETURN_INT32(arg + 1); } /* b reference, fixed length */ PG_FUNCTION_INFO_V1(add_one_float8); Datum add_one_float8(PG_FUNCTION_ARGS) { float8 arg = PG_GETARG_FLOAT8(0); PG_RETURN_FLOAT8(arg + 1.0); } /* by reference, variable length */ PG_FUNCTION_INFO_V1(copytext); Datum copytext(PG_FUNCTION_ARGS) { text *t = PG_GETARG_TEXT_P(0); text *new_t = (text *) palloc(VARSIZE(t)); VARATT_SIZEP(new_t) = VARSIZE(t); memcpy((void *) VARDATA(new_t), void *) VARDATA(t), VARSIZE(t)-VARHDRSZ); PG_RETURN_TEXT_P(new_t); } Lệnh CREATE FUNCTION tương tự version Cách có số cải tiến so với version 0, như: - Với ví dụ trên, thấy mã nguồn sử dụng macro để lấy đối số, trả liệu trả về… Việc sử dụng macro có lợi macro ẩn chi tiết không cần thiết Ví dụ như, hàm add_one_float8 trên, ta không cần quan tâm float8 loại truyền tham chiếu - Kiểm soát giá trị vào null Macro PG_ARGISNULL(n) cho phép kiểm tra giá trị vào null hay không Để trả giá trị null, ta dùng PG_RETURN_NULL(); macro làm việc chế độ strick không strick - Có hai giao diện khác macro PG_GETARG_xxx(): Đầu tiên PG_GETARG_xxx_COPY(), macro đảm bảo để trả đối số mà bị hạn chế việc ghi đè liệu Các macro bình thường trả trỏ tham chiếu đến giá trị lưu bảng, mà giá trị không ghi đè Thứ hai macro PG_GETARG_xxx_SLICE() với đối số đầu vào, số đối số hàm (giống với PG_GETARG_xxx()), offset (được tính từ 0) độ dài đoạn trả Với cải tiến này, cách dùng cho phép tính di động cao hơn, không phá vỡ giới hạn giao thức gọi hàm C chuẩn; cho phép trả kiểu liệu phức tạp, tập hợp; thực thi trigger điều khiển gọi ngôn ngữ thủ tục (procedural-language call handler) I.6 Quy tắc lập trình biên dịch hàm viết ngôn ngữ C I.6.1 Quy tắc lập trình Dưới số quy tắc lập trình cho việc viết biên dich hàm C: - Sử dụng pg_config includedir-server để tìm thư mục chứa file header (.h) PostgreSQL cài vào máy - Sử dung palloc pfree cho việc cấp phát giải phóng nhớ thay sử dụng hàm tương ứng thư viện C malloc free - Luôn xóa trắng struct cách sử dụng memset - Phải include file postgres.h (chứa hầu hết kiểu liệu) fmgr.h (chứa giao diện quản lý hàm) Tốt đặt postgres.h trước file header khác - Tên symbol định nghĩa file đối tượng không trùng với symbol khác symbol định nghĩa PostgreSQL - Việc biên dịch liên kết mã nguồn để tải động vào PostgreSQL cần cờ đặc biệt, -shared, -fpic - Để chắn không tải file tải động vào server không tương thích, cần phải thêm ‘magic block’, cần thêm đoạn mã sau vào file mã nguồn: #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif Cái giúp server phát lý không tương thích, ví dụ như, mã biên dịch cho phiên PostgreSQL khác với phiên server… I.6.2 Biên dịch Trước đưa hàm mở rộng viết C vào PostgreSQL, cần phải biên dịch liên kết để tạo file tải động server Chính xác thư viên chia sẻ cần tạo ra: đầu tiên, file mã nguồn biên dịch thành file đối tượng, sau đó, file đối tượng liên kết với Các file đối tượng cần tạo với mã độc lập vị trí (position-independent code - PIC), có nghĩa chúng đặt ví trý tùy ý nhớ chúng tải vào Để biên dịch hàm C, ta cần biên dịch C, gcc cc Các cờ biên dịch phần mở rộng đối tượng chia khác nhau, phụ thuộc vào hệ điều hành dùng; ví dụ so với hệ điều hành Linux, dll với hệ điều hành Window Dưới số bước biên dịch số hệ điều hành, giả thiết file mã nguồn foo.c, file đối tượng tạo foo.o: - BSD/OS gcc -fpic -c foo.c ld -shared -o foo.so foo.o - FreeBSD gcc -fpic -c foo.c gcc -shared -o foo.so foo.o - Linux cc -fpic -c foo.c cc -shared -o foo.so foo.o - Solaris gcc -fpic -c foo.c gcc -G -o foo.so foo.o - Window với biên dịch C CygWin gcc –c foo.c gcc –shared foo.dll foo.o Kết luận Với tính mở rộng PostgreSQL, người dùng đưa vào hàm người dùng định nghĩa nhiều cách khác Báo cáo sâu vào trình bày việc sử dụng hàm ngôn ngữ C, trinh bày cách, quy tắc để thực thi mở rộng hàm vào hệ quản trị CSDL PostgreSQL Từ đặc điểm hai cách đưa hàm ngôn mở rộng ngôn ngữ C, thấy, cách dùng thứ (dùng macro) cung cấp nhiều cải tiến cho người dùng Cách có tính linh động cao, mà không phá vỡ quy tắc ngôn ngữ C chuẩn; cho phép trả kiểu liệu phức tạp; thực thi trigger Báo cáo không trình bày chi tiết việc truyển vào đối số trả liệu phức tạp, phức hợp, tập hợp, đa hình… Chi tiết phần tham khảo tài liệu PostgreSQL 8.0.0 Documentation 10 TÀI LIỆU THAM KHẢO PostgreSQL 8.0.0 Documentation http://www.postgresql.org/docs/8.4/static/xfunc-c.html http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/ 11 [...]...TÀI LIỆU THAM KHẢO 1 PostgreSQL 8.0.0 Documentation 2 http://www .postgresql. org/docs/8.4/static/xfunc -c. html 3 http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/ 11 ... BSD/OS gcc -fpic -c foo .c ld -shared -o foo.so foo.o - FreeBSD gcc -fpic -c foo .c gcc -shared -o foo.so foo.o - Linux cc -fpic -c foo .c cc -shared -o foo.so foo.o - Solaris gcc -fpic -c foo .c gcc -G... ngữ C, trinh bày c ch, quy t c để th c thi mở rộng hàm vào hệ quản trị CSDL PostgreSQL Từ đ c điểm hai c ch đưa hàm ngôn mở rộng ngôn ngữ C, thấy, c ch dùng thứ (dùng macro) cung c p nhiều c i... tượng c n tạo với mã đ c lập vị trí (position-independent code - PIC), c nghĩa chúng đặt ví trý tùy ý nhớ chúng tải vào Để biên dịch hàm C, ta c n biên dịch C, gcc cc C c cờ biên dịch phần mở rộng

Ngày đăng: 16/03/2016, 22:50

Mục lục

    I.1. Tính mở rộng của PosgreSQL

    I.2. Hàm người dùng định nghĩa

    I.3. Quá trình tải động

    I.4. Các kiểu dữ liệu cơ bản trong hàm ngôn ngữ C

    I.5. Gọi hàm viết bằng ngôn ngữ C

    I.5.1. Version 0 - Không sử dụng macro PG_FUNCTION_INFO_V1()

    I.5.2. Version 1 - Sử dụng macro PG_FUNCTION_INFO_V1()

    I.6. Quy tắc lập trình và biên dịch hàm viết bằng ngôn ngữ C

    I.6.1. Quy tắc lập trình

Tài liệu cùng người dùng

Tài liệu liên quan