On 4/29/06, Andrew Dunstan <[EMAIL PROTECTED]> wrote:
Tom Lane wrote:
>"Jaime Casanova" <[EMAIL PROTECTED]> writes:
>
>
>>there is a chance to add a STEP clause to the FOR statement in plpgsql?
>>
>>
>
>This is not free: it'd require making STEP a reserved word (at least
>within plpgsql) which is contrary to spec. I think you need to make
>a pretty good case why the value of the feature outweighs breaking
>applications that have perfectly-legally used "step" as an identifier.
>
>
This isn't available in PL/SQL, is it? That doesn't mean we shouldn't do it, of
course, but it might lessen any perceived imperative.
Maybe using BY instad of STEP as the keyword would make it easier, since its
occurrence in SQL makes it less likely to be used as a variable.
cheers
andrew
Hi,
i make a little patch using BY instead of STEP per Tom's complaint and
Andrew's suggestion.
the patch is not ready yet because i can't figure out how to make the
BY optional and that is mandatory because backward compatibility...
the problem is how to manage it in gram.y
perhaps someone with more expertise in gram.y can make suggestions?
also, you can review the patch and say if it will be added if i can
solve the optional BY problem... then i can start working in fixing
the docs
--
regards,
Jaime Casanova
"What they (MySQL) lose in usability, they gain back in benchmarks, and that's
all that matters: getting the wrong answer really fast."
Randal L. Schwartz
diff -rciEb pgsql-8.2dev/src/pl/plpgsql/src/gram.y pgsql-8.2fori/src/pl/plpgsql/src/gram.y
*** pgsql-8.2dev/src/pl/plpgsql/src/gram.y 2006-04-30 09:45:12.000000000 -0500
--- pgsql-8.2fori/src/pl/plpgsql/src/gram.y 2006-04-30 09:49:05.000000000 -0500
***************
*** 143,148 ****
--- 143,149 ----
%token K_ALIAS
%token K_ASSIGN
%token K_BEGIN
+ %token K_BY
%token K_CLOSE
%token K_CONSTANT
%token K_CONTINUE
***************
*** 930,935 ****
--- 931,937 ----
{
/* Saw "..", so it must be an integer loop */
PLpgSQL_expr *expr2;
+ PLpgSQL_expr *expr_by;
PLpgSQL_var *fvar;
PLpgSQL_stmt_fori *new;
char *varname;
***************
*** 937,943 ****
/* First expression is well-formed */
check_sql_expr(expr1->query);
! expr2 = plpgsql_read_expression(K_LOOP, "LOOP");
/* should have had a single variable name */
plpgsql_error_lineno = $2.lineno;
--- 939,951 ----
/* First expression is well-formed */
check_sql_expr(expr1->query);
! expr2 = read_sql_construct(K_BY, K_LOOP,
! "BY|LOOP",
! "SELECT ", true,
! false, &tok);
!
! if (tok = K_BY)
! expr_by = plpgsql_read_expression(K_LOOP, "LOOP");
/* should have had a single variable name */
plpgsql_error_lineno = $2.lineno;
***************
*** 965,970 ****
--- 973,979 ----
new->reverse = reverse;
new->lower = expr1;
new->upper = expr2;
+ new->by = expr_by;
$$ = (PLpgSQL_stmt *) new;
}
diff -rciEb pgsql-8.2dev/src/pl/plpgsql/src/pl_exec.c pgsql-8.2fori/src/pl/plpgsql/src/pl_exec.c
*** pgsql-8.2dev/src/pl/plpgsql/src/pl_exec.c 2006-04-30 09:45:12.000000000 -0500
--- pgsql-8.2fori/src/pl/plpgsql/src/pl_exec.c 2006-04-30 09:49:54.000000000 -0500
***************
*** 1346,1352 ****
/* ----------
* exec_stmt_fori Iterate an integer variable
! * from a lower to an upper value.
* Loop can be left with exit.
* ----------
*/
--- 1346,1353 ----
/* ----------
* exec_stmt_fori Iterate an integer variable
! * from a lower to an upper value
! * incrementing or decrementing in BY value
* Loop can be left with exit.
* ----------
*/
***************
*** 1355,1360 ****
--- 1356,1362 ----
{
PLpgSQL_var *var;
Datum value;
+ Datum by_value;
Oid valtype;
bool isnull;
bool found = false;
***************
*** 1393,1398 ****
--- 1395,1414 ----
exec_eval_cleanup(estate);
/*
+ * Get the by value
+ */
+ by_value = exec_eval_expr(estate, stmt->by, &isnull, &valtype);
+ by_value = exec_cast_value(by_value, valtype, var->datatype->typoid,
+ &(var->datatype->typinput),
+ var->datatype->typioparam,
+ var->datatype->atttypmod, isnull);
+
+ /* If there is no BY, then we assume 1 */
+ if (isnull)
+ by_value = (Datum) 1;
+ exec_eval_cleanup(estate);
+
+ /*
* Now do the loop
*/
for (;;)
***************
*** 1468,1476 ****
* Increase/decrease loop var
*/
if (stmt->reverse)
! var->value--;
else
! var->value++;
}
/*
--- 1484,1492 ----
* Increase/decrease loop var
*/
if (stmt->reverse)
! var->value -= by_value;
else
! var->value += by_value;
}
/*
diff -rciEb pgsql-8.2dev/src/pl/plpgsql/src/plpgsql.h pgsql-8.2fori/src/pl/plpgsql/src/plpgsql.h
*** pgsql-8.2dev/src/pl/plpgsql/src/plpgsql.h 2006-04-30 09:45:12.000000000 -0500
--- pgsql-8.2fori/src/pl/plpgsql/src/plpgsql.h 2006-04-30 09:49:39.000000000 -0500
***************
*** 398,403 ****
--- 398,404 ----
PLpgSQL_var *var;
PLpgSQL_expr *lower;
PLpgSQL_expr *upper;
+ PLpgSQL_expr *by;
int reverse;
List *body; /* List of statements */
} PLpgSQL_stmt_fori;
Sólo en pgsql-8.2fori/src/pl/plpgsql/src: pl_scan.c
diff -rciEb pgsql-8.2dev/src/pl/plpgsql/src/scan.l pgsql-8.2fori/src/pl/plpgsql/src/scan.l
*** pgsql-8.2dev/src/pl/plpgsql/src/scan.l 2006-04-30 09:45:12.000000000 -0500
--- pgsql-8.2fori/src/pl/plpgsql/src/scan.l 2006-04-30 09:49:25.000000000 -0500
***************
*** 116,121 ****
--- 116,122 ----
\.\. { return K_DOTDOT; }
alias { return K_ALIAS; }
begin { return K_BEGIN; }
+ by { return K_BY; }
close { return K_CLOSE; }
constant { return K_CONSTANT; }
continue { return K_CONTINUE; }
drop function probando_for();
create or replace function probando_for() returns void as $$
declare
i integer;
begin
for i in 1..10 by 2 loop
-- for i in 1..10 loop
raise notice 'probando %', i;
end loop;
end;
$$ language 'plpgsql';
select probando_for();
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings