vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Pavel Stehule wrote: > Hello > > I found some bugs when I used base_lexer, so I returned back own > lexer. It's only little bit longer, but simpler. Hmm. I don't like having to lex the expressions again. It just doesn't feel right. How about taking a completely different strategy, and implement the CASE-WHEN construct fully natively in plpgsql, instead of trying to convert it to a single SQL CASE-WHEN expression? It's not a very good match anyway; you have to do tricks to convert the comma-separated lists of WHEN expressions to WHEN-THEN clauses, and you can't use the THEN-clauses as is, but you have to replace them with offsets into the array. I think implementing the logic in pl_exec.c would lead to cleaner code. FWIW, the current approach gives pretty cryptic CONTEXT information in error messages as well. For example, this pretty simple case-when example: postgres=# create or replace FUNCTION case_test(int) returns text as $$ begin case $1 when 1 then return 'one'; when 'invalid' then return 'two'; when 3,4,5 then return 'three, four or five'; end case; end; $$ language plpgsql immutable; CREATE FUNCTION gives this pretty hard-to-understand error message: postgres=# SELECT case_test(1); ERROR: invalid input syntax for integer: "invalid" CONTEXT: SQL statement "SELECT CASE $1 WHEN 1 THEN 1 WHEN 'invalid' THEN 2 WHEN 3 THEN 3 WHEN 4 THEN 3 WHEN 5 THEN 3 END " PL/pgSQL function "case_test" line 2 at unknown BTW, what does PL/SQL or PSM say about the type-compatibility of the CASE and the WHENs? We're very lenient in assignments, how should this behave? -- Heikki Linnakangas EnterpriseDB http://www.enterprisedb.com -- Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches |
| |||
| Hello 2008/5/2 Heikki Linnakangas <heikki@enterprisedb.com>: > Pavel Stehule wrote: >> >> Hello >> >> I found some bugs when I used base_lexer, so I returned back own >> lexer. It's only little bit longer, but simpler. > > Hmm. I don't like having to lex the expressions again. It just doesn't feel > right. me too. But when I tested to use base_lexer routines, I had to write similar number of lines and add new separate file http://archives.postgresql.org/pgsql...4/msg00131.php - main problems of this version is enhanced strings, because base_lexer don't forward this information. > > How about taking a completely different strategy, and implement the > CASE-WHEN construct fully natively in plpgsql, instead of trying to convert > it to a single SQL CASE-WHEN expression? It's not a very good match anyway; > you have to do tricks to convert the comma-separated lists of WHEN > expressions to WHEN-THEN clauses, and you can't use the THEN-clauses as is, > but you have to replace them with offsets into the array. I think > implementing the logic in pl_exec.c would lead to cleaner code. > It was first variant. It's simpler for parsing and slower for execution simple case value casting and comparation. > FWIW, the current approach gives pretty cryptic CONTEXT information in error > messages as well. For example, this pretty simple case-when example: > > postgres=# create or replace FUNCTION case_test(int) > returns text as $$ > begin > case $1 > when 1 then > return 'one'; > when 'invalid' then > return 'two'; > when 3,4,5 then > return 'three, four or five'; > end case; > end; > $$ language plpgsql immutable; > CREATE FUNCTION > > gives this pretty hard-to-understand error message: > > postgres=# SELECT case_test(1); > ERROR: invalid input syntax for integer: "invalid" > CONTEXT: SQL statement "SELECT CASE $1 WHEN 1 THEN 1 WHEN 'invalid' > THEN 2 WHEN 3 THEN 3 WHEN 4 THEN 3 WHEN 5 THEN 3 END " > PL/pgSQL function "case_test" line 2 at unknown > > BTW, what does PL/SQL or PSM say about the type-compatibility of the CASE > and the WHENs? We're very lenient in assignments, how should this behave? > what I know, it have to be compareable case $1 when 1 then return 'one'; when 'invalid' then return 'two'; is same as if expr1 = 1 then\ return 'one' elsif expr1 = 'invalid' then .... I have to agree, so this message is ugly, but on second hand I can check this error in compile time. When I move it to pl_exec I can detect this bug much later, so current solution is safe. So, when I read error message I see correct message - only CONTEXT is crazy (but it is strange not only in this case)/ I haven't idea how I can solve it - maybe notice in documentation. We can add hint to this message. Other way (mix read_sql_construct and add_expr) has other problem with nested case statements. Maybe safe to somewhere positions of placeholders. But It will not be simple too, because width of placeholders can be different. Regards Pavel Stehule > -- > Heikki Linnakangas > EnterpriseDB http://www.enterprisedb.com > -- Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches |
| |||
| "Pavel Stehule" <pavel.stehule@gmail.com> writes: > 2008/5/2 Heikki Linnakangas <heikki@enterprisedb.com>: >> How about taking a completely different strategy, and implement the >> CASE-WHEN construct fully natively in plpgsql, instead of trying to convert >> it to a single SQL CASE-WHEN expression? It's not a very good match anyway; > It was first variant. It's simpler for parsing and slower for > execution > simple case value casting and comparation. I agree with Heikki: this patch is seriously ugly, and "slower for execution" isn't a good enough reason for saddling us with having to maintain such a kluge in the parser. I don't really see why you should need to have multiple expression evaluations, anyhow. Can't you evaluate the test expression once and inject its value into the comparisons using CaseTestExpr, the same way the core CASE-expression code works? regards, tom lane -- Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches |
| ||||
| Hello 2008/5/3 Tom Lane <tgl@sss.pgh.pa.us>: > "Pavel Stehule" <pavel.stehule@gmail.com> writes: >> 2008/5/2 Heikki Linnakangas <heikki@enterprisedb.com>: >>> How about taking a completely different strategy, and implement the >>> CASE-WHEN construct fully natively in plpgsql, instead of trying to convert >>> it to a single SQL CASE-WHEN expression? It's not a very good match anyway; > >> It was first variant. It's simpler for parsing and slower for >> execution >> simple case value casting and comparation. > > I agree with Heikki: this patch is seriously ugly, and "slower for > execution" isn't a good enough reason for saddling us with having > to maintain such a kluge in the parser. > > I don't really see why you should need to have multiple expression > evaluations, anyhow. Can't you evaluate the test expression once > and inject its value into the comparisons using CaseTestExpr, > the same way the core CASE-expression code works? > > I have to look on this way. Regards Pavel Stehule regards, tom lane > -- Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-patches |