You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Informix 14.10.FC10视图创建报错:SELECT投影列表不允许行内聚合

Informix 14.10.FC7到FC10迁移中视图创建报错问题分析

我正在将数据库从Informix Dynamic Server 14.10.FC7W1AEE迁移至14.10.FC10AEE(均部署在RHEL 8系统的不同机器上),同时PortMaster从7升级到10。目前除某视图创建命令外,其余操作均正常执行。

该视图创建命令如下:

create view "dbo".dirdoc1 (
    typv,predpona,eecyear,eecnum,popivaz
) as select
    x0.typv ,
    min(row(x1.eecyear ,
    x1.eecnum ,
    x1.predpona )::eec ).predpona ,
    min(row(x1.eecyear ,
    x1.eecnum ,
    x1.predpona )::eec ).eecyear ,
    min(row(x1.eecyear ,
    x1.eecnum ,
    x1.predpona )::eec ).eecnum ,
    max(x0.popivaz ) 
from
    "dbo".typv x0 ,
outer("dbo".dirdoc x1 ) where
    (
        x0.typv = x1.typv 
    ) 
group by
    x0.typv ;

执行后收到报错:

Aggregate within a ROW in a SELECT projection list is not allowed

现象说明

当仅保留一个聚合项(比如只保留min(row(x1.eecyear,x1.eecnum,x1.predpona)::eec).eecnum)时,命令可正常执行;但使用2个及以上min()列时,就会触发上述报错。该命令(或仅SELECT部分)在FC7环境中完全正常,在FC10中则报错。我已经核对了FC8、FC9、FC10的版本发布说明、onconfig文件及环境变量(两台机器配置尽可能保持一致),想了解FC7到FC10之间的哪些变更可能导致此问题?


问题复现步骤(FC7W1可行,FC10不可行)

1. 创建基础表dbo.typv

CREATE TABLE dbo.typv (
    typv char(8) NOT NULL,
    popivaz varchar(254) NOT NULL,
    poznvaz varchar,
    nazevc varchar,
    snp smallint DEFAULT 0 NOT NULL,
    peca smallint DEFAULT 0 NOT NULL, 
    uveu smallint,
    PRIMARY KEY (typv) CONSTRAINT typv_pk
);

2. 创建表dbo.dirdoc

create table dbo.dirdoc
  (
    typv char(8) not null ,
    eecyear datetime year to year not null ,
    eecnum integer not null ,
    oj char(14),
    predpona varchar(7)
        default 'EEC' not null ,
    celex char(10),

    check (((((oj MATCHES 'OJ [0-9][0-9]/[CL] [1-9][0-9/ ][0-9/ ][0-9/ ][0-9/ ][0-9/ ]'
              ) AND ((oj MATCHES '*[0-9]/[0-9][0-9]*' ) OR (oj MATCHES '????????[1-9][0-9 ][0-9 ]   '
              ) ) ) AND (oj NOT MATCHES '*/*/*/*' ) ) AND (oj NOT MATCHES '*[0-9] [0-9]*'
              ) ) AND (oj NOT MATCHES '*/[0-9][0-9][0-9]*' ) ) constraint dbo.oj_dirdoc
  ) extent size 16 next size 16 lock mode page;

3. 创建行类型informix.eec

create row type informix.eec
    (
    eecyear datetime year to year,
    eecnum integer,
    predpona varchar(7)
    );

4. 创建自定义比较函数informix.lessthanorequal

CREATE FUNCTION informix.lessthanorequal(eec1 eec, eec2 eec) RETURNING BOOLEAN WITH(NOT VARIANT,NEGATOR=greaterthan);
IF eec1.eecyear IS NULL OR eec2.eecyear IS NULL THEN RETURN NULL::BOOLEAN;
ELIF eec1.eecyear < eec2.eecyear THEN RETURN 't';
ELIF eec1.eecyear > eec2.eecyear THEN RETURN 'f';
END IF
IF eec1.eecnum IS NULL OR eec2.eecnum IS NULL THEN RETURN NULL::BOOLEAN;
ELIF eec1.eecnum < eec2.eecnum THEN RETURN 't';
ELIF eec1.eecnum > eec2.eecnum THEN RETURN 'f';
END IF
IF eec1.predpona IS NULL AND eec2.predpona IS NULL THEN RETURN 't';
ELIF eec1.predpona < eec2.predpona THEN RETURN 't';
ELIF eec1.predpona > eec2.predpona THEN RETURN 'f';
ELIF eec2.predpona IS NULL THEN RETURN 't';
ELIF eec1.predpona IS NULL THEN RETURN 'f';
ELSE RETURN 't';
END IF
END FUNCTION;

5. 创建报错的视图dbo.dirdoc1

create view dbo.dirdoc1 (typv,predpona,eecyear,eecnum,popivaz) as 
   select
        x0.typv,
        min(row(x1.eecyear,x1.eecnum,x1.predpona)::eec).predpona,
        min(row(x1.eecyear,x1.eecnum,x1.predpona)::eec).eecyear,
        min(row(x1.eecyear,x1.eecnum,x1.predpona)::eec).eecnum,
        max(x0.popivaz) 
    from
        dbo.typv x0,
    outer(dbo.dirdoc x1) where
        (x0.typv = x1.typv) 
    group by
        x0.typv;

可能的版本变更原因分析

从FC7到FC10的版本迭代中,Informix对SQL语法的合规性检查进行了强化,尤其是针对聚合函数与行类型结合的场景:

  • SQL语法解析器严格性提升:FC7版本的解析器可能存在漏洞,允许在SELECT投影列表中多次对行类型执行聚合函数并提取字段的操作;而FC8/FC9/FC10中修复了该漏洞,严格执行官方规范——不允许在投影列表中同时存在多个“聚合函数嵌套行类型操作”的表达式。
  • UDT聚合交互逻辑调整:针对自定义行类型(如eec)的聚合操作,FC10调整了执行计划生成逻辑。当多个min(row(...))::eec.xxx表达式共存时,解析器会判定为“聚合内部嵌套行类型操作”的违规场景,单个表达式则因执行路径简单未触发检查。
  • PortMaster升级的间接影响:PortMaster从7升级到10同步更新了SQL语法校验规则,部分之前被允许的非标准语法在新版本中被限制。

内容的提问来源于stack exchange,提问作者Ondřej Žižka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:47:45