Re: RETURNS TABLE function: ERROR: column reference "word" is ambiguous - Mailing list pgsql-general
From | Pavel Stehule |
---|---|
Subject | Re: RETURNS TABLE function: ERROR: column reference "word" is ambiguous |
Date | |
Msg-id | CAFj8pRCyadFsUTJwD8vWAzrBVwAtOSd1mEixvrkC=8XoxHzBbw@mail.gmail.com Whole thread Raw |
In response to | Re: RETURNS TABLE function: ERROR: column reference "word" is ambiguous ("Charles Clavadetscher" <clavadetscher@swisspug.org>) |
List | pgsql-general |
2016-08-10 15:18 GMT+02:00 Charles Clavadetscher <clavadetscher@swisspug.org>:
HelloYou can use
> -----Original Message-----
> From: pgsql-general-owner@postgresql.org [mailto:pgsql-general-owner@ postgresql.org] On Behalf Of Alexander Farber
> Sent: Mittwoch, 10. August 2016 14:54
> To: pgsql-general <pgsql-general@postgresql.org>
> Subject: [GENERAL] RETURNS TABLE function: ERROR: column reference "word" is ambiguous
>
> Good afternoon,
>
>
> In PostgreSQL 9.5.3 I have created a function (full source code at the bottom), which goes through an 15 x 15
> varchar array and collects words played horizontally and vertically.
>
>
> I have declared the function as:
>
>
> CREATE OR REPLACE FUNCTION words_check_words(
> IN in_uid integer,
> IN in_gid integer,
> IN in_tiles jsonb)
> RETURNS TABLE(word varchar, score integer) AS $func$ ................
> CREATE TEMPORARY TABLE _words (word varchar, score integer) ON COMMIT DROP; ...............
> SELECT word, max(score) as score FROM _words GROUP BY word; END $func$ LANGUAGE plpgsql;
>
>
> And when I call it as:
>
>
> select * from words_check_words(2, 1,
> '[{"col":11,"letter":"A","row":8,"value":1},{"col":11," letter":"B","row":7,"value":3} ]'::jsonb);
>
>
> then it fails with:
>
>
> ERROR: column reference "word" is ambiguous LINE 1: SELECT word, max(score) as score FROM _words GROUP BY word
> ^
> DETAIL: It could refer to either a PL/pgSQL variable or a table column.
>
>
> As I understand the "word" is used both by the RETURN TYPE and my TEMP TABLE.
>
>
> How to resolve this "naming conflict" best or maybe there is some better way like using some "internal" table
> implicitly created by the type declaration?
>
>
> Thank you
>
> Alex
>
>
> P.S. Below is my full source code and the full log output -
>
>
#variable_conflict [use_column|use_variable] before BEGIN:
- http://dba.stackexchange.com/questions/105831/naming- conflict-between-function- parameter-and-result-of-join- with-using-clause
- https://www.postgresql.org/docs/current/static/plpgsql- implementation.html
I am sorry, but disabling this check is not good.This is pretty big trap.
correct and usual solution is using qualified names
_words.word
Regards
Pavel
Hope this helps.
Regards
Charles--
> CREATE OR REPLACE FUNCTION words_check_words(
> IN in_uid integer,
> IN in_gid integer,
> IN in_tiles jsonb)
> RETURNS TABLE(word varchar, score integer) AS $func$ DECLARE
> _tile jsonb;
> _letter varchar;
> _letter2 varchar;
> _value integer;
> _value2 integer;
> _col integer;
> _col2 integer;
> _row integer;
> _row2 integer;
> _letters varchar[][];
> _values integer[][];
> _mult varchar[][];
> _factor integer;
> _score integer;
> _word varchar;
> BEGIN
> SELECT
> g.letters,
> g.values,
> b.mult
> INTO
> _letters,
> _values,
> _mult
> FROM words_games g, words_boards b WHERE
> g.gid = in_gid AND
> g.bid = b.bid AND
> g.player1 = in_uid AND
> -- and it is first player's turn
> (g.played1 IS NULL OR g.played1 < g.played2);
>
> IF NOT FOUND THEN
> SELECT
> g.letters,
> g.values,
> b.mult
> INTO
> _letters,
> _values,
> _mult
> FROM words_games g, words_boards b WHERE
> g.gid = in_gid AND
> g.bid = b.bid AND
> g.player2 = in_uid AND
> -- and it is first player's turn
> (g.played2 IS NULL OR g.played2 < g.played1);
> END IF;
>
> IF NOT FOUND THEN
> RAISE EXCEPTION 'Game % not found for user %', in_gid, in_uid;
> END IF;
>
> CREATE TEMPORARY TABLE _words (word varchar, score integer) ON COMMIT DROP;
>
> FOR _tile IN SELECT * FROM JSONB_ARRAY_ELEMENTS(in_tiles)
> LOOP
> _letter := _tile->>'letter';
> _value := (_tile->>'value')::int;
> _col := (_tile->>'col')::int + 1;
> _row := (_tile->>'row')::int + 1;
>
> _letters[_col][_row] := _letter;
> -- multiply the new letter value with premium
> _values[_col][_row] := _value * words_letter_mult(_mult[_col][_row]);
>
> _word := _letter;
> _score := _values[_col][_row];
> _factor := words_word_mult(_mult[_col][_row]);
>
> -- go left and prepend letters
> FOR _col2 IN REVERSE (_col - 1)..1 LOOP
> _letter2 := _letters[_col2][_row];
> EXIT WHEN _letter2 IS NULL;
> _value2 := _values[_col2][_row];
> _word := _letter2 || _word;
> _score := _score + _value2;
> _factor := _factor * words_word_mult(_mult[_col2][_row]);
> END LOOP;
>
> -- go right and append letters
> FOR _col2 IN (_col + 1)..15 LOOP
> _letter2 := _letters[_col2][_row];
> EXIT WHEN _letter2 IS NULL;
> _value2 := _values[_col2][_row];
> _word := _word || _letter2;
> _score := _score + _value2;
> _factor := _factor * words_word_mult(_mult[_col2][_row]);
> END LOOP;
>
> IF LENGTH(_word) > 1 /* AND EXISTS SELECT 1 FROM words_nouns */ THEN
> INSERT INTO _words(word, score)
> VALUES (upper(_word), _score);
> END IF;
>
> _word := _letter;
> _score := _values[_col][_row];
> _factor := words_word_mult(_mult[_col][_row]);
>
> -- go up and prepend letters
> FOR _row2 IN REVERSE (_row - 1)..1 LOOP
> _letter2 := _letters[_col][_row2];
> EXIT WHEN _letter2 IS NULL;
> _value2 := _values[_col][_row2];
> _word := _letter2 || _word;
> _score := _score + _value2;
> _factor := _factor * words_word_mult(_mult[_col][_row2]);
> END LOOP;
>
> -- go down and append letters
> FOR _row2 IN (_row + 1)..15 LOOP
> _letter2 := _letters[_col][_row2];
> EXIT WHEN _letter2 IS NULL;
> _value2 := _values[_col][_row2];
> _word := _word || _letter2;
> _score := _score + _value2;
> _factor := _factor * words_word_mult(_mult[_col][_row2]);
> END LOOP;
>
> IF LENGTH(_word) > 1 /* AND EXISTS SELECT 1 FROM words_nouns */ THEN
> INSERT INTO _words(word, score)
> VALUES (upper(_word), _score);
> END IF;
> END LOOP;
>
> RAISE NOTICE 'letters = %', _letters;
> RAISE NOTICE 'values = %', _values;
> RAISE NOTICE 'mult = %', _mult;
>
> SELECT word, max(score) as score FROM _words GROUP BY word; END $func$ LANGUAGE plpgsql;
>
>
> -----------------
>
>
> -- apologies for non-english letters here
>
>
> LOG: statement: select * from words_check_words(2, 1,
> '[{"col":11,"letter":"?","row":8,"value":1},{"col":11," letter":"?","row":7,"value":3} ]'::jsonb);
> NOTICE: letters =
> {{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL},{NULL, NULL,NULL,NULL,NULL,NULL,NULL, NU
> LL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL
> ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL},{NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL, NUL
> L,NULL,NULL,NULL,NULL,NULL,NULL},{NULL,NULL,NULL,NULL, NULL,NULL,
> NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL
> ,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,М, NULL,NULL
> ,NULL,NULL,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,Э,Р, О,Е,NULL,NULL,NULL,NULL},{ NULL,NULL,NULL,NULL,NULL,NULL, NUL
> L,NULL,NULL,Х,NULL,NULL,NULL,NULL,NULL},{NULL,NULL,NULL, NULL,NUL
> L,NULL,NULL,NULL,NULL,И,NULL,NULL,NULL,NULL,NULL},{NULL, NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,В,NULL,NULL,NULL,NUL
> L,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,?,?,Ы,NULL, NULL,NULL
> ,NULL,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL} ,{NULL,NULL,NULL,NULL,NULL,N
> ULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL, NULL,NUL
> L,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL}}
> NOTICE: values =
> {{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL},{NULL, NULL,NULL,NULL,NULL,NULL,NULL, NU
> LL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL
> ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL},{NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL, NUL
> L,NULL,NULL,NULL,NULL,NULL,NULL},{NULL,NULL,NULL,NULL, NULL,NULL,
> NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL
> ,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,2, NULL,NULL
> ,NULL,NULL,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,10,2, 1,1,NULL,NULL,NULL,NULL},{ NULL,NULL,NULL,NULL,NULL,NULL, NU
> LL,NULL,NULL,5,NULL,NULL,NULL,NULL,NULL},{NULL,NULL,NULL, NULL,NU
> LL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL},{NULL, NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,2,NULL,NULL,NULL,NU
> LL,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,6,1,5,NULL, NULL,NUL
> L,NULL,NULL},{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL} ,{NULL,NULL,NULL,NULL,NULL,
> NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL, NULL,NU
> LL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL}}
> NOTICE: mult =
> {{TW,NULL,NULL,DL,NULL,NULL,NULL,TW,NULL,NULL,NULL,DL, NULL,NULL,TW},{NULL,TL,NULL, NULL,NULL,DW,NULL,NULL,NULL, DW,NUL
> L,NULL,NULL,TL,NULL},{NULL,NULL,TL,NULL,NULL
> ,NULL,DL,NULL,DL,NULL,NULL,NULL,TL,NULL,NULL},{DL,NULL, NULL,TL,NULL,NULL,NULL,DL, NULL,NULL,NULL,TL,NULL,NULL, DL},{NU
> LL,NULL,NULL,NULL,TL,NULL,NULL,NULL,NULL,NULL,TL,NULL, NULL,NULL,
> NULL},{NULL,DW,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,DW,NULL},{NULL,NULL, DL,NULL,NULL,NULL,DL,NULL,
> DL,NULL,NULL,NULL,DL,NULL,NULL},{TW,NULL,NULL,DL,NULL, NULL,NULL,
> NULL,NULL,NULL,NULL,DL,NULL,NULL,TW},{NULL,NULL,DL,NULL, NULL,NULL,DL,NULL,DL,NULL, NULL,NULL,DL,NULL,NULL},{NULL, DW,N
> ULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,DW, NULL},{
> NULL,NULL,NULL,NULL,TL,NULL,NULL,NULL,NULL,NULL,TL,NULL, NULL,NULL,NULL},{DL,NULL,NULL, TL,NULL,NULL,NULL,DL,NULL,NULL
> ,NULL,TL,NULL,NULL,DL},{NULL,NULL,TL,NULL,NULL,NULL,DL, NULL,DL,N
> ULL,NULL,NULL,TL,NULL,NULL},{NULL,TL,NULL,NULL,NULL,DW, NULL,NULL,NULL,DW,NULL,NULL, NULL,TL,NULL},{TW,NULL,NULL, DL,NU
> LL,NULL,NULL,TW,NULL,NULL,NULL,DL,NULL,NULL,TW}}
> ERROR: column reference "word" is ambiguous at character 8
> DETAIL: It could refer to either a PL/pgSQL variable or a table column.
> QUERY: SELECT word, max(score) as score FROM _words GROUP BY word
> CONTEXT: PL/pgSQL function words_check_words(integer,integer,jsonb) line 131 at SQL statement
> STATEMENT: select * from words_check_words(2, 1,
> '[{"col":11,"letter":"?","row":8,"value":1},{"col":11," letter":"?","row":7,"value":3} ]'::jsonb);
>
>
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general
pgsql-general by date: