Attribute notation for function call gives error

前端 未结 1 982
予麋鹿
予麋鹿 2021-01-22 01:35

Attribute notation function call gives error when current schema is different from one of function.

I have created a function

CREATE FU         


        
相关标签:
1条回答
  • 2021-01-22 01:59

    You found the root of the problem yourself. To be precise: the schema of the function pub has to be listed anywhere in the current search_path, does not have to be the "default" or "current" schema (the first one in the list). Related:

    • How does the search_path influence identifier resolution and the "current schema"

    So Postgres did not find the function. Postgres 11 isn't different from Postgres 10 in this regard. There are some noteworthy, related developments, though. You mentioned:

    Database has been migrated from PostgreSQL 10 with backup/restore.

    Consider this subtle change pointed out in the release notes for Postgres 11:

    • Consider syntactic form when disambiguating function versus column references (Tom Lane)

      When x is a table name or composite column, PostgreSQL has traditionally considered the syntactic forms f(x) and x.f to be equivalent, allowing tricks such as writing a function and then using it as though it were a computed-on-demand column. However, if both interpretations are feasible, the column interpretation was always chosen, leading to surprising results if the user intended the function interpretation. Now, if there is ambiguity, the interpretation that matches the syntactic form is chosen.

    So, if there was a column fullname in table reps and also the function pub.fullname(pub.reps) you display, Postgres 10, even with functional notation, would still chose the column:

    SELECT fullname(r) FROM reps r;  -- resolves to column if it exists, ignoring function
    

    db<>fiddle here for Postgres 10

    Postgres 11 (more reasonably) choses the function:

    db<>fiddle here for Postgres 11

    Postgres 12 (currently beta) eventually implements true generated columns. The release notes:

    • Add support for generated columns (Peter Eisentraut)

    The content of generated columns are computed from expressions (including references to other columns in the same table) rather than being specified by INSERT or UPDATE commands.

    Only STORED generated columns made it into this release, though. The (more interesting IMO) VIRTUAL variant was postponed for a later release. (Not in Postgres 13, yet.)

    Your table could look like this:

    CREATE TABLE pub.reps (
      reps_id  int GENERATED ALWAYS AS IDENTITY PRIMARY KEY 
    , fname    text NOT NULL
    , lname    text NOT NULL
    , fullname text GENERATED ALWAYS AS (fname || ' ' || lname) STORED
    );
    

    db<>fiddle here

    I declared fname and lname columns NOT NULL. Else, your simple concatenation (fname || ' ' || lname) is a trap. See:

    • How to concatenate columns in a Postgres SELECT?
    • Combine two columns and add into one new column
    0 讨论(0)
提交回复
热议问题