1 如果为已知数据类型,可使用 distinct type
CREATE DISTINCT TYPE birthday AS DATE;
2 未知数据类型 比如 现在想实现一个 描述 正方体体积的数据类型 volume(长,宽,高)
2.1 volume.h
typedef struct {
int x;
int y;
int z;
} volume_t;
volume_t *volume_add(volume_t *a, volume_t *b);
volume_t *volume_comp(volume_t *a, volume_t *b);
2.2 volume.c
#include <string.h>
#include "volume.h"
#include "mi.h"
volume_t *volume_add(volume_t *a, volume_t *b) {
volume_t *result = (volume_t *)mi_zalloc(sizeof(volume_t));
result->x = a->x + b->x;
result->y = a->y + b->y;
result->z = a->z + b->z;
return result;
}
mi_integer volume_comp(volume_t *a, volume_t *b) {
if(a->x * a->y * a->z == b->x * b->y * b->z){
return 1;
}else{
return 0;
}
}
volume_t *volume_in(mi_lvarchar *input,MI_FPARAM* param)
{
mi_lvarchar *result = NULL;
volume_t *c = (volume_t *)mi_zalloc(sizeof(volume_t));
mi_char* s = mi_lvarchar_to_string(input);
mi_fp_setreturnisnull(param, 0, MI_TRUE);
sscanf(s, "(%d,%d,%d)", &c->x, &c->y,&c->z);
if (c == NULL) {
char error_msg[] = "volume_input: volume_from_char failed!";
mi_db_error_raise(NULL,MI_EXCEPTION, error_msg);
return (mi_lvarchar *)NULL;
}
mi_fp_setreturnisnull(param, 0, MI_FALSE);
return c;
}
mi_lvarchar *volume_out(volume_t *output,MI_FPARAM* param) {
mi_lvarchar * var = NULL;
mi_fp_setreturnisnull(param, 0, MI_TRUE);
var = mi_new_var(sizeof(volume_t));
if (var == (mi_lvarchar *)NULL) {
char error_msg[] = "memory allocation failed";
mi_db_error_raise(NULL, MI_EXCEPTION, error_msg);
}
sprintf(var,"(%d,%d,%d)", output->x, output->y,output->z);
mi_fp_setreturnisnull(param, 0, MI_FALSE);
return var;
}
mi_lvarchar *volume_send(volume_t *output,MI_FPARAM* param) {
return volume_out(output,param);
}
volume_t *volume_rcv(mi_lvarchar *input,MI_FPARAM* param) {
return volume_in(input,param);
}
volume_t *volume_import_txt(mi_lvarchar *input,MI_FPARAM* param) {
return volume_in(input,param);
}
mi_lvarchar *volume_export_txt(volume_t *output,MI_FPARAM* param) {
return volume_out(output,param);
}
volume_t *volume_import_bin(mi_lvarchar *input,MI_FPARAM* param) {
return volume_in(input,param);
}
mi_lvarchar *volume_export_bin(volume_t *output,MI_FPARAM* param) {
return volume_out(output,param);
}
mi_integer volume_comp(volume_t *a, volume_t *b) {
if(a->x * a->y * a->z == b->x * b->y * b->z){
return 1;
}else{
return 0;
}
}
mi_integer volume_ncomp(volume_t *a, volume_t *b) {
if(a->x * a->y * a->z == b->x * b->y * b->z){
return 0;
}else{
return 1;
}
}
2.3 创建数据类型
CREATE OPAQUE TYPE volume (
INTERNALLENGTH = 12,
ALIGNMENT = 4,
CANNOTHASH
);
2.4 创建相关函数
create function volume_in(lvarchar)
returns volume
with (handlesnulls)
external name '$GBASEDBTDIR/lib/volume.so(volume_in)'
language c;
create function volume_out(volume)
returns lvarchar
with (handlesnulls)
external name '$GBASEDBTDIR/lib/volume.so(volume_out)'
language c;
create function volume_send(volume)
returns lvarchar
external name '$GBASEDBTDIR/lib/volume.so(volume_send)'
language c;
create function volume_rcv(lvarchar)
returns volume
external name '$GBASEDBTDIR/lib/volume.so(volume_rcv)'
language c;
create function volume_import_txt(lvarchar)
returns volume
external name '$GBASEDBTDIR/lib/volume.so(volume_import_txt)'
language c;
create function volume_export_txt(volume)
returns lvarchar
external name '$GBASEDBTDIR/lib/volume.so(volume_export_txt)'
language c;
create function volume_import_bin(lvarchar)
returns volume
external name '$GBASEDBTDIR/lib/volume.so(volume_import_bin)'
language c;
create function volume_export_bin(volume)
returns lvarchar
external name '$GBASEDBTDIR/lib/volume.so(volume_export_bin)'
language c;
create function volume_add(volume, volume)
returns volume
external name '$GBASEDBTDIR/lib/volume.so(volume_add)'
language c;
create function volume_comp(volume, volume)
returns int
external name '$GBASEDBTDIR/lib/volume.so(volume_comp)'
language c;
create function gbasedbt.compare(gbasedbt.volume, gbasedbt.volume)
returns integer
external name '$GBASEDBTDIR/lib/volume.so(volume_comp)' language c not variant;
create function gbasedbt.equal(gbasedbt.volume, gbasedbt.volume)
returns gbasedbt.boolean
external name '$GBASEDBTDIR/lib/volume.so(volume_comp)' language c not variant;
create function gbasedbt.notequal(gbasedbt.volume, gbasedbt.volume)
returns gbasedbt.boolean
external name '$GBASEDBTDIR/lib/volume.so(volume_ncomp)' language c not variant;
create function gbasedbt.volume_plus(gbasedbt.volume, gbasedbt.volume)
returns gbasedbt.volume with(not variant)
external name '$GBASEDBTDIR/lib/volume.so(volume_add)' language c ;
2.5 创建转换
create implicit cast(lvarchar as volume with gbasedbt.volume_in);
create implicit cast(volume as lvarchar with gbasedbt.volume_out);
create explicit cast(volume as sendrecv with gbasedbt.volume_send);
create implicit cast(sendrecv as volume with gbasedbt.volume_recv);
create implicit cast(impexp as volume with gbasedbt.volume_import_txt);
create explicit cast(volume as impexp with gbasedbt.volume_export_txt);
create implicit cast(impexpbin as volume with gbasedbt.volume_import_bin);
create explicit cast(volume as impexpbin with gbasedbt.volume_export_bin);
2.6 测试
create table t1(c1 volume);
insert into t1 values('(1,2,3)');
select volume_plus('(1,2,3)'::volume , '(1,2,3)'::volume) from dual;
create index idx_t1_c1 on t1(c1);
select * from t1;
Table created.
>
1 row(s) inserted.
>
(expression) (2,4,6)
1 row(s) retrieved.
>
Index created.
>
c1 (1,2,3)
1 row(s) retrieved.
2.7 规则
gbase8s 要求必须实现 创建转换等组函数,其中还需要实现流支持函数以及存储支持函数,部分函数反编译出来看不太明白,舍弃了
1476

被折叠的 条评论
为什么被折叠?



