为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】: --03134284194-20240812-238838-20108 Pack9
【操作系统】:win10
【CPU】: X86
【问题描述】*:
今天清理历史记录,看到之前学习 “在达梦中如何创建一个聚集函数,实现PG中bit_or聚集函数的功能” 这个帖子内容时创建的 bit_or 聚合函数。
参考该函数结构,试写了 bit_and 和 bit_xor 两个聚合函数,测试时发现,单独查询结果是正确的,但把几个函数一并使用时,查询结果都等于第一个函数的值。
这块我有点拿不准是函数实现上有问题,还是数据库本身如此,还请专家帮忙分析下,多谢。
测试过程如下:
DROP FUNCTION IF EXISTS BIT_OR;
CREATE OR REPLACE TYPE BIT_OR_AGG_TYPE AS OBJECT (
BIT_OR_RESULT NUMBER(38),
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT BIT_OR_AGG_TYPE) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT BIT_OR_AGG_TYPE, VALUE IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN BIT_OR_AGG_TYPE, RETURNVALUE OUT NUMBER, FLAGS IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT BIT_OR_AGG_TYPE, CTX2 IN BIT_OR_AGG_TYPE) RETURN NUMBER
);
CREATE OR REPLACE TYPE BODY BIT_OR_AGG_TYPE IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT BIT_OR_AGG_TYPE) RETURN NUMBER IS
BEGIN
SCTX := BIT_OR_AGG_TYPE(0);
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT BIT_OR_AGG_TYPE, VALUE IN NUMBER) RETURN NUMBER IS
BEGIN
SELF.BIT_OR_RESULT := COALESCE(SELF.BIT_OR_RESULT, 0) | VALUE;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN BIT_OR_AGG_TYPE, RETURNVALUE OUT NUMBER, FLAGS IN NUMBER) RETURN NUMBER IS
BEGIN
RETURNVALUE := SELF.BIT_OR_RESULT;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT BIT_OR_AGG_TYPE, CTX2 IN BIT_OR_AGG_TYPE) RETURN NUMBER IS
BEGIN
SELF.BIT_OR_RESULT := COALESCE(SELF.BIT_OR_RESULT, 0) | COALESCE(CTX2.BIT_OR_RESULT, 0);
RETURN ODCICONST.SUCCESS;
END;
END;
CREATE OR REPLACE FUNCTION BIT_OR(INPUT NUMBER) RETURN NUMBER
PARALLEL_ENABLE AGGREGATE USING BIT_OR_AGG_TYPE;
1.2 BIT_AND
DROP FUNCTION IF EXISTS BIT_AND;
CREATE OR REPLACE TYPE BIT_AND_AGG_TYPE AS OBJECT (
BIT_AND_RESULT NUMBER(38),
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT BIT_AND_AGG_TYPE) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT BIT_AND_AGG_TYPE, VALUE IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN BIT_AND_AGG_TYPE, RETURNVALUE OUT NUMBER, FLAGS IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT BIT_AND_AGG_TYPE, CTX2 IN BIT_AND_AGG_TYPE) RETURN NUMBER
);
CREATE OR REPLACE TYPE BODY BIT_AND_AGG_TYPE IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT BIT_AND_AGG_TYPE) RETURN NUMBER IS
BEGIN
SCTX := BIT_AND_AGG_TYPE(0XFFFFFFFF);
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT BIT_AND_AGG_TYPE, VALUE IN NUMBER) RETURN NUMBER IS
BEGIN
SELF.BIT_AND_RESULT := COALESCE(SELF.BIT_AND_RESULT, 0) & VALUE;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN BIT_AND_AGG_TYPE, RETURNVALUE OUT NUMBER, FLAGS IN NUMBER) RETURN NUMBER IS
BEGIN
RETURNVALUE := SELF.BIT_AND_RESULT;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT BIT_AND_AGG_TYPE, CTX2 IN BIT_AND_AGG_TYPE) RETURN NUMBER IS
BEGIN
SELF.BIT_AND_RESULT := COALESCE(SELF.BIT_AND_RESULT, 0) & COALESCE(CTX2.BIT_AND_RESULT, 0);
RETURN ODCICONST.SUCCESS;
END;
END;
CREATE OR REPLACE FUNCTION BIT_AND(INPUT NUMBER) RETURN NUMBER
PARALLEL_ENABLE AGGREGATE USING BIT_AND_AGG_TYPE;
1.3 BIT_XOR
DROP FUNCTION IF EXISTS BIT_XOR;
CREATE OR REPLACE TYPE BIT_XOR_AGG_TYPE AS OBJECT (
BIT_XOR_RESULT NUMBER(38),
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT BIT_XOR_AGG_TYPE) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT BIT_XOR_AGG_TYPE, VALUE IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN BIT_XOR_AGG_TYPE, RETURNVALUE OUT NUMBER, FLAGS IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT BIT_XOR_AGG_TYPE, CTX2 IN BIT_XOR_AGG_TYPE) RETURN NUMBER
);
CREATE OR REPLACE TYPE BODY BIT_XOR_AGG_TYPE IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT BIT_XOR_AGG_TYPE) RETURN NUMBER IS
BEGIN
SCTX := BIT_XOR_AGG_TYPE(NULL);
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT BIT_XOR_AGG_TYPE, VALUE IN NUMBER) RETURN NUMBER IS
BEGIN
SELF.BIT_XOR_RESULT := COALESCE(SELF.BIT_XOR_RESULT, 0) ^ VALUE;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN BIT_XOR_AGG_TYPE, RETURNVALUE OUT NUMBER, FLAGS IN NUMBER) RETURN NUMBER IS
BEGIN
RETURNVALUE := SELF.BIT_XOR_RESULT;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT BIT_XOR_AGG_TYPE, CTX2 IN BIT_XOR_AGG_TYPE) RETURN NUMBER IS
BEGIN
SELF.BIT_XOR_RESULT := COALESCE(SELF.BIT_XOR_RESULT, 0) ^ COALESCE(CTX2.BIT_XOR_RESULT, 0);
RETURN ODCICONST.SUCCESS;
END;
END;
CREATE OR REPLACE FUNCTION BIT_XOR(INPUT NUMBER) RETURN NUMBER
PARALLEL_ENABLE AGGREGATE USING BIT_XOR_AGG_TYPE;
CREATE TABLE BITS(
ID INT PRIMARY KEY AUTO_INCREMENT,
BIN_VALUE VARBINARY(8)
);
INSERT INTO BITS(BIN_VALUE) VALUES(0X05),(0X06);
COMMIT;
SELECT BIT_OR(BIN_VALUE) FROM BITS; --返回7
SELECT BIT_AND(BIN_VALUE) FROM BITS; --返回4
SELECT BIT_XOR(BIN_VALUE) FROM BITS; --返回3
--三个聚合函数一并使用,返回:7 7 7
SELECT BIT_OR(BIN_VALUE)
,BIT_AND(BIN_VALUE)
,BIT_XOR(BIN_VALUE)
FROM BITS;
--调整三个聚合函数顺序,返回 4 4 4
SELECT BIT_AND(BIN_VALUE)
,BIT_OR(BIN_VALUE)
,BIT_XOR(BIN_VALUE)
FROM BITS;
金仓和edb是基于Postgresql的,默认有 bit_or 和 bit_and 函数,我未实现 bit_xor,用两个现有函数的查询结果也都正常
--03134284172-20240321-222308-20093 版本中也存在该问题