문제

I have an application which works fine on Postgres 9.0, but after upgrade to 9.3 a huge sql statements stopped working. My assumption is that pg behavior changed from case-insensitive to case-sensitive. Here is the statement which works on pg 9.0, but throws an error on 9.3:

> ERROR:  column tmplrole.name does not exist at character 35

The query:

select cftCE.f_resource as ceId, tmplRole.name as tRole, mdtk.meta_type_key as metaKey, md1.metadatum_value as metaValue, grp1.id as groupId 
from account acc1 
left outer join account_role accRole on acc1.f_principal=accRole.f_account  
left outer join roles r1 on accRole.f_role=r1.f_principal 
left outer join template_role tmplRole on r1.f_template_role=tmplRole.id 
left outer join groups grp1 on r1.f_group=grp1.id left outer join content_entry cftCE on grp1.f_content_entry=cftCE.f_resource 
left outer join metadatum md1 on cftCE.f_resource=md1.f_content_entry  
left outer join meta_type mdtk on md1.f_meta_type=mdtk.id  
inner join ( select f_content_entry as permCe from groups grp 
inner join ( select f_group as groupId from operation opr     
inner join ( select ppr.f_resource as cftce from PRINCIPAL_PERMISSION_RESOURCE ppr      
inner join ( select roles.f_principal  as userrole from roles, account_role, account      
where roles.f_principal=account_role.F_role and account_role.f_account=account.f_principal and account.f_principal=$1 )
AS roles_alias on ppr.f_principal = userrole      
inner join (select operation.f_resource  as viewCftOperation from Operation where Operation.F_TEMPLATE_OPERATION=$2 ) 
AS operation_alias on ppr.f_resource = viewCftOperation ) AS ppr_alias on opr.F_resource = cftce )
AS group_alias  on grp.ID = groupid ) 
AS content_entry_alias on cftCE.f_resource = permCe where acc1.f_principal=$3
and (mdtk.meta_type_key=$4 or mdtk.meta_type_key=$5 or mdtk.meta_type_key=$6) order by cftCE.date_created desc;
도움이 되었습니까?

해결책

Case sensitivity rules haven't changed but the handling of tablename.type has changed in PostgreSQL 9.1. The catch is that name is a postgres built-in type, used for the catalog.

Here's the relevant entry in the 9.1 release notes:

E.14.2.2. Casting
Disallow function-style and attribute-style data type casts for composite types (Tom Lane)

For example, disallow composite_value.text and text(composite_value). Unintentional uses of this syntax have frequently resulted in bug reports; although it was not a bug, it seems better to go back to rejecting such expressions. The CAST and :: syntaxes are still available for use when a cast of an entire composite value is actually intended.

My guess would be that your table template_role doesn't have a name column in 9.0, and that having tmplRole.name being interpreted as tmplRole::name was a bug was went unnoticed in your query.

Also see the related Is name a special keyword in PostgreSQL?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top