-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bad indentation for DECLARE in PostgreSQL #92
Comments
In PostgresSQL, the DECLARE keyword might begin a block of declarations, or declare a single cursor. Updated the syntax scanning code to only consider DECLARE a block start when it is part of a program block. This change will alter how PostgresSQL blocks are indented, hopefully for the better. Added tests for the relevant cases, and updated existing test cases which also incorrectly detected DECLARE statements.
First, thank you for working on this so quickly. However, it looks like there are two corner cases that aren’t covered. The first is when a -- Current behaviour
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
DECLARE local_a text := a;
DECLARE local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
$$ LANGUAGE plpgsql;
-- Expected behaviour
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
DECLARE local_a text := a;
DECLARE local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
$$ LANGUAGE plpgsql; The second happens with nesting inside another -- Current behaviour
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
BEGIN
DECLARE
local_a text := a;
local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
END;
$$ LANGUAGE plpgsql;
-- Expected behaviour
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
BEGIN
DECLARE
local_a text := a;
local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
END;
$$ LANGUAGE plpgsql; This might require a new -- Current behaviour
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
BEGIN
IF a IS NULL THEN
RETURN FALSE;
ELSE
DECLARE
local_a text := a;
local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
END IF;
END;
$$ LANGUAGE plpgsql;
-- Expected behaviour
CREATE FUNCTION less_than(a text, b text) RETURNS boolean AS $$
BEGIN
IF a IS NULL or b IS NULL THEN
RETURN FALSE;
ELSE
DECLARE
local_a text := a;
local_b text := b;
BEGIN
RETURN local_a < local_b;
END;
END IF;
END;
$$ LANGUAGE plpgsql; |
* sql-indent.el (sqlind-maybe-declare-statement): recognize declare statements in begin blocks, then and else blocks. (sqlind-refine-syntax): don't nest declare statements
Thanks for preparing the test cases, I don't use Postgresql and I rely on these to improve sql-indent. I have pushed a fix for the test cases you prepared. Can you please have a look? Thanks, Alex. |
I appreciate the effort to support Postgres! Sadly, I have found a corner case that results from only examining the previous token: e7795c7#r37366259 |
The current `sql-indent` implementation is unable to recognize DECLARE blocks in all situations. Documented this limitation, for now.
The current `sql-indent` implementation is unable to recognize DECLARE blocks in all situations. Documented this limitation, for now.
Unlike an SQL parser,
I just want to be clear that I think your report is valid, but unfortunately I don't know how to fix it and have no more time to look into it. |
The
DECLARE
statement in PL/pgSQL is similar to the one in PL/SQL and is used to declare variables: https://www.postgresql.org/docs/current/plpgsql-declarations.htmlTest case in PostgreSQL:
However, there is also a
DECLARE
statement that creates a cursor: https://www.postgresql.org/docs/12/sql-declare.htmlI think
sqlind-beginning-of-block
probably needs to handle the PostgreSQL case:emacs-sql-indent/sql-indent.el
Lines 956 to 957 in 56be397
However, for the cursor use-case, I think that
sqlind-maybe-declare-statement
needs to understand if it’sin-begin-block
and do something special, especially in order to recognize and indent the embeddedSELECT
orVALUES
statement.The text was updated successfully, but these errors were encountered: