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

Reply via email to