简体   繁体   English

Postgres 截断 CASE 语句列

[英]Postgres truncates CASE statement column

I'm writing some functions for mapping a Postgres database.我正在编写一些用于映射 Postgres 数据库的函数。 The functions are used to create dynamic queries for a javascript API.这些函数用于为 javascript API 创建动态查询。

I've come across a particular query that truncates the output of a column and I cannot determine why.我遇到了一个截断列的 output 的特定查询,我无法确定原因。

The width of the column in the following query seems to be truncated to 63 characters:以下查询中的列宽似乎被截断为 63 个字符:

SELECT
  CASE
    WHEN t.column_name ~ '_[uid]*$' AND t.has_fn THEN
      format(
        'format(''%s/%%s'', %s) AS %s',
        array_to_string(ARRAY['',t.fk_schema,t.fk_name],'/'),
        t.column_name,
        regexp_replace(t.column_name, '_[uid]*$', '_link')
      )
    ELSE t.column_name
  END AS column
FROM core.map_type() t; -- core.map_type() is a set returning function

This query is used to create a select list for another query, but the string produced by format() is truncated to 63 characters.此查询用于为另一个查询创建 select 列表,但format()生成的字符串被截断为 63 个字符。

However, if I add || ''但是,如果我添加|| '' || '' to the ELSE branch of the CASE statement, the problem goes away: || ''CASE语句的ELSE分支,问题就消失了:

SELECT
  CASE
    WHEN t.column_name ~ '_[uid]*$' AND t.has_fn THEN
      format(
        'format(''%s/%%s'', %s) AS %s',
        array_to_string(ARRAY['',t.fk_schema,t.fk_name],'/'),
        t.column_name,
        regexp_replace(t.column_name, '_[uid]*$', '_link')
      )
    ELSE t.column_name || '' -- add empty string here
  END AS column
FROM core.map_type() t; -- core.map_type() is a set returning function

Having a column truncated like this is a worrisome problem.像这样截断一列是一个令人担忧的问题。 The fix here is a total hack and does not feel like a real solution.这里的修复完全是 hack,感觉不像是真正的解决方案。

Why is this happening?为什么会这样? How can it be fixed?如何修复?

In this case, the value of t.column_name in the ELSE branch of the CASE statement is of type name .在这种情况下, CASE语句的ELSE分支中的t.column_name的值是name类型。 name is a type used internally by Postgres for naming things. name是 Postgres 内部用于命名事物的类型。 It has a fixed length of 64 bytes.它具有 64 字节的固定长度。

The column is truncated to suit the length of the ELSE branch.该列被截断以适应ELSE分支的长度。

Casting t.column_name to text will fix the problem:t.column_nametext将解决问题:

SELECT
  CASE
    WHEN t.column_name ~ '_[uid]*$' AND t.has_fn THEN
      format(
        'format(''%s/%%s'', %s) AS %s',
        array_to_string(ARRAY['',t.fk_schema,t.fk_name],'/'),
        t.column_name,
        regexp_replace(t.column_name, '_[uid]*$', '_link')
      )
    ELSE t.column_name::text
  END AS column
FROM core.map_type() t;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM