Column reference “id” is ambiguous - It could refer to either a PL/pgSQL variable or a table column











up vote
0
down vote

favorite












I have this simple test function in Postgres (in my test schema).



CREATE OR REPLACE FUNCTION test.func_001
(
par_id int
)
RETURNS TABLE
(
id int
)

AS
$BODY$
DECLARE

var_id int;

BEGIN

update test.item --- this is a table
set
id = 4
WHERE
id = 44;

return query
select 1000 as id;

END;
$BODY$
LANGUAGE plpgsql;


The test.item table has a single id column.



I get the error below while trying to run the function.



Query execution failed

Reason:
SQL Error [42702]: ERROR: column reference "id" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table column.
Where: PL/pgSQL function test.func_001(integer) line 8 at SQL statement


This error seems weird, does it mean that Postgres is finding a conflict/clash between the test.item.id column and the id column from the returned table?!
How come? This doesn't make any sense.



I cannot believe this but I see no other id usages here.



Note that if I comment out just this part.



-- WHERE
-- id = 44;


then suddenly the function works fine.



So it seems Postgres is confusing the id in the where
clause with something else that's named id?!



With what?



This is totally illogical and counter-intuitive.



Could someone please explain?










share|improve this question
























  • I guess you get the error, because you have a return value named id and a column in your table with the same name
    – Jens
    Nov 8 at 9:32










  • Well, OK... I don't quite have a return value id. I am returning a table (from this function) and that returned table has an id column. Also, I have a physical table (test.item) which has an id column. I am amazed why it is finding a clash between the two. Makes no sense to me. Note that I have read the full manual about PL/pgSQL, its syntax, etc. There is nothing there documenting this weird behavior.
    – peter.petrov
    Nov 8 at 9:35

















up vote
0
down vote

favorite












I have this simple test function in Postgres (in my test schema).



CREATE OR REPLACE FUNCTION test.func_001
(
par_id int
)
RETURNS TABLE
(
id int
)

AS
$BODY$
DECLARE

var_id int;

BEGIN

update test.item --- this is a table
set
id = 4
WHERE
id = 44;

return query
select 1000 as id;

END;
$BODY$
LANGUAGE plpgsql;


The test.item table has a single id column.



I get the error below while trying to run the function.



Query execution failed

Reason:
SQL Error [42702]: ERROR: column reference "id" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table column.
Where: PL/pgSQL function test.func_001(integer) line 8 at SQL statement


This error seems weird, does it mean that Postgres is finding a conflict/clash between the test.item.id column and the id column from the returned table?!
How come? This doesn't make any sense.



I cannot believe this but I see no other id usages here.



Note that if I comment out just this part.



-- WHERE
-- id = 44;


then suddenly the function works fine.



So it seems Postgres is confusing the id in the where
clause with something else that's named id?!



With what?



This is totally illogical and counter-intuitive.



Could someone please explain?










share|improve this question
























  • I guess you get the error, because you have a return value named id and a column in your table with the same name
    – Jens
    Nov 8 at 9:32










  • Well, OK... I don't quite have a return value id. I am returning a table (from this function) and that returned table has an id column. Also, I have a physical table (test.item) which has an id column. I am amazed why it is finding a clash between the two. Makes no sense to me. Note that I have read the full manual about PL/pgSQL, its syntax, etc. There is nothing there documenting this weird behavior.
    – peter.petrov
    Nov 8 at 9:35















up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have this simple test function in Postgres (in my test schema).



CREATE OR REPLACE FUNCTION test.func_001
(
par_id int
)
RETURNS TABLE
(
id int
)

AS
$BODY$
DECLARE

var_id int;

BEGIN

update test.item --- this is a table
set
id = 4
WHERE
id = 44;

return query
select 1000 as id;

END;
$BODY$
LANGUAGE plpgsql;


The test.item table has a single id column.



I get the error below while trying to run the function.



Query execution failed

Reason:
SQL Error [42702]: ERROR: column reference "id" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table column.
Where: PL/pgSQL function test.func_001(integer) line 8 at SQL statement


This error seems weird, does it mean that Postgres is finding a conflict/clash between the test.item.id column and the id column from the returned table?!
How come? This doesn't make any sense.



I cannot believe this but I see no other id usages here.



Note that if I comment out just this part.



-- WHERE
-- id = 44;


then suddenly the function works fine.



So it seems Postgres is confusing the id in the where
clause with something else that's named id?!



With what?



This is totally illogical and counter-intuitive.



Could someone please explain?










share|improve this question















I have this simple test function in Postgres (in my test schema).



CREATE OR REPLACE FUNCTION test.func_001
(
par_id int
)
RETURNS TABLE
(
id int
)

AS
$BODY$
DECLARE

var_id int;

BEGIN

update test.item --- this is a table
set
id = 4
WHERE
id = 44;

return query
select 1000 as id;

END;
$BODY$
LANGUAGE plpgsql;


The test.item table has a single id column.



I get the error below while trying to run the function.



Query execution failed

Reason:
SQL Error [42702]: ERROR: column reference "id" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table column.
Where: PL/pgSQL function test.func_001(integer) line 8 at SQL statement


This error seems weird, does it mean that Postgres is finding a conflict/clash between the test.item.id column and the id column from the returned table?!
How come? This doesn't make any sense.



I cannot believe this but I see no other id usages here.



Note that if I comment out just this part.



-- WHERE
-- id = 44;


then suddenly the function works fine.



So it seems Postgres is confusing the id in the where
clause with something else that's named id?!



With what?



This is totally illogical and counter-intuitive.



Could someone please explain?







postgresql plpgsql






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 9:45









Laurenz Albe

40.9k92745




40.9k92745










asked Nov 8 at 9:29









peter.petrov

27k74881




27k74881












  • I guess you get the error, because you have a return value named id and a column in your table with the same name
    – Jens
    Nov 8 at 9:32










  • Well, OK... I don't quite have a return value id. I am returning a table (from this function) and that returned table has an id column. Also, I have a physical table (test.item) which has an id column. I am amazed why it is finding a clash between the two. Makes no sense to me. Note that I have read the full manual about PL/pgSQL, its syntax, etc. There is nothing there documenting this weird behavior.
    – peter.petrov
    Nov 8 at 9:35




















  • I guess you get the error, because you have a return value named id and a column in your table with the same name
    – Jens
    Nov 8 at 9:32










  • Well, OK... I don't quite have a return value id. I am returning a table (from this function) and that returned table has an id column. Also, I have a physical table (test.item) which has an id column. I am amazed why it is finding a clash between the two. Makes no sense to me. Note that I have read the full manual about PL/pgSQL, its syntax, etc. There is nothing there documenting this weird behavior.
    – peter.petrov
    Nov 8 at 9:35


















I guess you get the error, because you have a return value named id and a column in your table with the same name
– Jens
Nov 8 at 9:32




I guess you get the error, because you have a return value named id and a column in your table with the same name
– Jens
Nov 8 at 9:32












Well, OK... I don't quite have a return value id. I am returning a table (from this function) and that returned table has an id column. Also, I have a physical table (test.item) which has an id column. I am amazed why it is finding a clash between the two. Makes no sense to me. Note that I have read the full manual about PL/pgSQL, its syntax, etc. There is nothing there documenting this weird behavior.
– peter.petrov
Nov 8 at 9:35






Well, OK... I don't quite have a return value id. I am returning a table (from this function) and that returned table has an id column. Also, I have a physical table (test.item) which has an id column. I am amazed why it is finding a clash between the two. Makes no sense to me. Note that I have read the full manual about PL/pgSQL, its syntax, etc. There is nothing there documenting this weird behavior.
– peter.petrov
Nov 8 at 9:35














2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










The clause FUNCTION fx() RETURNS TABLE(x int, y int, ...) is same like FUNCTION(OUT x int, OUT y int) RETURNS SETOF record. So in your case, there is implicit variable id, although you don't use it explicitly.



PostgreSQL design allows to produce rows without SQL.



CREATE OR REPLACE FUNCTION foo(a int)
RETURNS TABLE(b int, c int) AS $$
BEGIN
FOR i IN 1..a
LOOP
b := i; c := i * 10;
RETURN NEXT;
END LOOP;
END;
$$ LANGUAGE plpgsql;


See following document, please.




There is another way to declare a function as returning a set, which is to use the syntax RETURNS TABLE(columns). This is equivalent to using one or more OUT parameters plus marking the function as returning SETOF record (or SETOF a single output parameter's type, as appropriate). This notation is specified in recent versions of the SQL standard, and thus may be more portable than using SETOF.







share|improve this answer




























    up vote
    2
    down vote













    There is a name conflict between the variable id that is defined by the RETURNS TABLE clause and the column of the same name.



    Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you rather than doing something that may not be what you intended.



    Qualify the column reference like this to remove the ambiguity:



    WHERE test.item.id = 44





    share|improve this answer























    • Well, if I had a local (function level) variable, I would understand this error but not in this case... So you're saying that the id in RETURNS TABLE(id int) under the hood is just implemented as a variable? And that's why Postgres is saying that I have an ambiguity?
      – peter.petrov
      Nov 8 at 10:02












    • "Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you..." That's kind of exaggerated btw.
      – peter.petrov
      Nov 8 at 10:03










    • I don't think id in the column list of the return table should clash with variables and column names of other tables. That doesn't sound normal, not for 2018. But anyway, thanks, I will qualify my column names as you suggest.
      – peter.petrov
      Nov 8 at 10:07










    • It is less exaggerated than what you originally had in your question. And I think it is true.
      – Laurenz Albe
      Nov 8 at 10:07










    • Your way of boldly stating that everything you don't understand is backwards gives me the impression that you don't have a lot of programming experience.
      – Laurenz Albe
      Nov 8 at 10:09











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204855%2fcolumn-reference-id-is-ambiguous-it-could-refer-to-either-a-pl-pgsql-variabl%23new-answer', 'question_page');
    }
    );

    Post as a guest
































    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    The clause FUNCTION fx() RETURNS TABLE(x int, y int, ...) is same like FUNCTION(OUT x int, OUT y int) RETURNS SETOF record. So in your case, there is implicit variable id, although you don't use it explicitly.



    PostgreSQL design allows to produce rows without SQL.



    CREATE OR REPLACE FUNCTION foo(a int)
    RETURNS TABLE(b int, c int) AS $$
    BEGIN
    FOR i IN 1..a
    LOOP
    b := i; c := i * 10;
    RETURN NEXT;
    END LOOP;
    END;
    $$ LANGUAGE plpgsql;


    See following document, please.




    There is another way to declare a function as returning a set, which is to use the syntax RETURNS TABLE(columns). This is equivalent to using one or more OUT parameters plus marking the function as returning SETOF record (or SETOF a single output parameter's type, as appropriate). This notation is specified in recent versions of the SQL standard, and thus may be more portable than using SETOF.







    share|improve this answer

























      up vote
      3
      down vote



      accepted










      The clause FUNCTION fx() RETURNS TABLE(x int, y int, ...) is same like FUNCTION(OUT x int, OUT y int) RETURNS SETOF record. So in your case, there is implicit variable id, although you don't use it explicitly.



      PostgreSQL design allows to produce rows without SQL.



      CREATE OR REPLACE FUNCTION foo(a int)
      RETURNS TABLE(b int, c int) AS $$
      BEGIN
      FOR i IN 1..a
      LOOP
      b := i; c := i * 10;
      RETURN NEXT;
      END LOOP;
      END;
      $$ LANGUAGE plpgsql;


      See following document, please.




      There is another way to declare a function as returning a set, which is to use the syntax RETURNS TABLE(columns). This is equivalent to using one or more OUT parameters plus marking the function as returning SETOF record (or SETOF a single output parameter's type, as appropriate). This notation is specified in recent versions of the SQL standard, and thus may be more portable than using SETOF.







      share|improve this answer























        up vote
        3
        down vote



        accepted







        up vote
        3
        down vote



        accepted






        The clause FUNCTION fx() RETURNS TABLE(x int, y int, ...) is same like FUNCTION(OUT x int, OUT y int) RETURNS SETOF record. So in your case, there is implicit variable id, although you don't use it explicitly.



        PostgreSQL design allows to produce rows without SQL.



        CREATE OR REPLACE FUNCTION foo(a int)
        RETURNS TABLE(b int, c int) AS $$
        BEGIN
        FOR i IN 1..a
        LOOP
        b := i; c := i * 10;
        RETURN NEXT;
        END LOOP;
        END;
        $$ LANGUAGE plpgsql;


        See following document, please.




        There is another way to declare a function as returning a set, which is to use the syntax RETURNS TABLE(columns). This is equivalent to using one or more OUT parameters plus marking the function as returning SETOF record (or SETOF a single output parameter's type, as appropriate). This notation is specified in recent versions of the SQL standard, and thus may be more portable than using SETOF.







        share|improve this answer












        The clause FUNCTION fx() RETURNS TABLE(x int, y int, ...) is same like FUNCTION(OUT x int, OUT y int) RETURNS SETOF record. So in your case, there is implicit variable id, although you don't use it explicitly.



        PostgreSQL design allows to produce rows without SQL.



        CREATE OR REPLACE FUNCTION foo(a int)
        RETURNS TABLE(b int, c int) AS $$
        BEGIN
        FOR i IN 1..a
        LOOP
        b := i; c := i * 10;
        RETURN NEXT;
        END LOOP;
        END;
        $$ LANGUAGE plpgsql;


        See following document, please.




        There is another way to declare a function as returning a set, which is to use the syntax RETURNS TABLE(columns). This is equivalent to using one or more OUT parameters plus marking the function as returning SETOF record (or SETOF a single output parameter's type, as appropriate). This notation is specified in recent versions of the SQL standard, and thus may be more portable than using SETOF.








        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 8 at 10:22









        Pavel Stehule

        21.8k34855




        21.8k34855
























            up vote
            2
            down vote













            There is a name conflict between the variable id that is defined by the RETURNS TABLE clause and the column of the same name.



            Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you rather than doing something that may not be what you intended.



            Qualify the column reference like this to remove the ambiguity:



            WHERE test.item.id = 44





            share|improve this answer























            • Well, if I had a local (function level) variable, I would understand this error but not in this case... So you're saying that the id in RETURNS TABLE(id int) under the hood is just implemented as a variable? And that's why Postgres is saying that I have an ambiguity?
              – peter.petrov
              Nov 8 at 10:02












            • "Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you..." That's kind of exaggerated btw.
              – peter.petrov
              Nov 8 at 10:03










            • I don't think id in the column list of the return table should clash with variables and column names of other tables. That doesn't sound normal, not for 2018. But anyway, thanks, I will qualify my column names as you suggest.
              – peter.petrov
              Nov 8 at 10:07










            • It is less exaggerated than what you originally had in your question. And I think it is true.
              – Laurenz Albe
              Nov 8 at 10:07










            • Your way of boldly stating that everything you don't understand is backwards gives me the impression that you don't have a lot of programming experience.
              – Laurenz Albe
              Nov 8 at 10:09















            up vote
            2
            down vote













            There is a name conflict between the variable id that is defined by the RETURNS TABLE clause and the column of the same name.



            Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you rather than doing something that may not be what you intended.



            Qualify the column reference like this to remove the ambiguity:



            WHERE test.item.id = 44





            share|improve this answer























            • Well, if I had a local (function level) variable, I would understand this error but not in this case... So you're saying that the id in RETURNS TABLE(id int) under the hood is just implemented as a variable? And that's why Postgres is saying that I have an ambiguity?
              – peter.petrov
              Nov 8 at 10:02












            • "Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you..." That's kind of exaggerated btw.
              – peter.petrov
              Nov 8 at 10:03










            • I don't think id in the column list of the return table should clash with variables and column names of other tables. That doesn't sound normal, not for 2018. But anyway, thanks, I will qualify my column names as you suggest.
              – peter.petrov
              Nov 8 at 10:07










            • It is less exaggerated than what you originally had in your question. And I think it is true.
              – Laurenz Albe
              Nov 8 at 10:07










            • Your way of boldly stating that everything you don't understand is backwards gives me the impression that you don't have a lot of programming experience.
              – Laurenz Albe
              Nov 8 at 10:09













            up vote
            2
            down vote










            up vote
            2
            down vote









            There is a name conflict between the variable id that is defined by the RETURNS TABLE clause and the column of the same name.



            Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you rather than doing something that may not be what you intended.



            Qualify the column reference like this to remove the ambiguity:



            WHERE test.item.id = 44





            share|improve this answer














            There is a name conflict between the variable id that is defined by the RETURNS TABLE clause and the column of the same name.



            Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you rather than doing something that may not be what you intended.



            Qualify the column reference like this to remove the ambiguity:



            WHERE test.item.id = 44






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 8 at 9:57

























            answered Nov 8 at 9:43









            Laurenz Albe

            40.9k92745




            40.9k92745












            • Well, if I had a local (function level) variable, I would understand this error but not in this case... So you're saying that the id in RETURNS TABLE(id int) under the hood is just implemented as a variable? And that's why Postgres is saying that I have an ambiguity?
              – peter.petrov
              Nov 8 at 10:02












            • "Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you..." That's kind of exaggerated btw.
              – peter.petrov
              Nov 8 at 10:03










            • I don't think id in the column list of the return table should clash with variables and column names of other tables. That doesn't sound normal, not for 2018. But anyway, thanks, I will qualify my column names as you suggest.
              – peter.petrov
              Nov 8 at 10:07










            • It is less exaggerated than what you originally had in your question. And I think it is true.
              – Laurenz Albe
              Nov 8 at 10:07










            • Your way of boldly stating that everything you don't understand is backwards gives me the impression that you don't have a lot of programming experience.
              – Laurenz Albe
              Nov 8 at 10:09


















            • Well, if I had a local (function level) variable, I would understand this error but not in this case... So you're saying that the id in RETURNS TABLE(id int) under the hood is just implemented as a variable? And that's why Postgres is saying that I have an ambiguity?
              – peter.petrov
              Nov 8 at 10:02












            • "Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you..." That's kind of exaggerated btw.
              – peter.petrov
              Nov 8 at 10:03










            • I don't think id in the column list of the return table should clash with variables and column names of other tables. That doesn't sound normal, not for 2018. But anyway, thanks, I will qualify my column names as you suggest.
              – peter.petrov
              Nov 8 at 10:07










            • It is less exaggerated than what you originally had in your question. And I think it is true.
              – Laurenz Albe
              Nov 8 at 10:07










            • Your way of boldly stating that everything you don't understand is backwards gives me the impression that you don't have a lot of programming experience.
              – Laurenz Albe
              Nov 8 at 10:09
















            Well, if I had a local (function level) variable, I would understand this error but not in this case... So you're saying that the id in RETURNS TABLE(id int) under the hood is just implemented as a variable? And that's why Postgres is saying that I have an ambiguity?
            – peter.petrov
            Nov 8 at 10:02






            Well, if I had a local (function level) variable, I would understand this error but not in this case... So you're saying that the id in RETURNS TABLE(id int) under the hood is just implemented as a variable? And that's why Postgres is saying that I have an ambiguity?
            – peter.petrov
            Nov 8 at 10:02














            "Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you..." That's kind of exaggerated btw.
            – peter.petrov
            Nov 8 at 10:03




            "Things like that cause problems in all programming languages, only PostgreSQL is nice enough to alert you..." That's kind of exaggerated btw.
            – peter.petrov
            Nov 8 at 10:03












            I don't think id in the column list of the return table should clash with variables and column names of other tables. That doesn't sound normal, not for 2018. But anyway, thanks, I will qualify my column names as you suggest.
            – peter.petrov
            Nov 8 at 10:07




            I don't think id in the column list of the return table should clash with variables and column names of other tables. That doesn't sound normal, not for 2018. But anyway, thanks, I will qualify my column names as you suggest.
            – peter.petrov
            Nov 8 at 10:07












            It is less exaggerated than what you originally had in your question. And I think it is true.
            – Laurenz Albe
            Nov 8 at 10:07




            It is less exaggerated than what you originally had in your question. And I think it is true.
            – Laurenz Albe
            Nov 8 at 10:07












            Your way of boldly stating that everything you don't understand is backwards gives me the impression that you don't have a lot of programming experience.
            – Laurenz Albe
            Nov 8 at 10:09




            Your way of boldly stating that everything you don't understand is backwards gives me the impression that you don't have a lot of programming experience.
            – Laurenz Albe
            Nov 8 at 10:09


















             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204855%2fcolumn-reference-id-is-ambiguous-it-could-refer-to-either-a-pl-pgsql-variabl%23new-answer', 'question_page');
            }
            );

            Post as a guest




















































































            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)