Skip to content
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

User-defined functions and table-valued functions have an extra space #444

Open
Prinzhorn opened this issue Sep 17, 2022 · 9 comments
Open
Labels

Comments

@Prinzhorn
Copy link
Contributor

Prinzhorn commented Sep 17, 2022

It appears there is an internal list of known SQLite functions and virtual tables used to format. I rely heavily on user-defined functions and table-valued functions. These custom functions have an extra space before the opening parenthesis.

Input data

SELECT
  foo('unknown'),
  substr('known'),
  bar('unknown')
FROM
  foo_bar(foo('unknown')),
  json_each()

Expected Output

SELECT
  foo('unknown'),
  substr('known'),
  bar('unknown')
FROM
  foo_bar(foo('unknown')),
  json_each()

Actual Output

SELECT
  foo ('unknown'), -- Extra space
  substr('known'),
  bar ('unknown') -- Extra space
FROM
  foo_bar (foo ('unknown')), -- Two extra spaces
  json_each()

Usage

=> https://sql-formatter-org.github.io/sql-formatter/ with SQLite language

I don't think any of the other formatting options matter in this case. The formatter should not need to keep a list of SQLite functions/tables but infer the formatting from the token (I have no idea how this library is actually implemented).

@Prinzhorn Prinzhorn added the bug label Sep 17, 2022
@nene
Copy link
Collaborator

nene commented Sep 17, 2022

Yes, this is a known issue. We're planning to address this, but it's not a simple fix to make. Hard to say how long it will take.

The formatter relies on various heuristics to do it's work. We're slowly evolving towards properly parsing the SQL language, but we're still far from that.

@Prinzhorn
Copy link
Contributor Author

Prinzhorn commented Sep 17, 2022

Thanks for the quick reply. I'm sure this is a tricky problem and you likely don't want to ship like 58MB of grammars (and if so, allow tree shaking and only importing the grammar I need) https://www.npmjs.com/package/antlr4ts-sql

image

For my use case I wonder if I could interface to the SQLite C API to tokenize the SQL, but it looks there is no high level API available.

@ourpower
Copy link

ourpower commented May 4, 2023

Hey,

Maybe any update on this one behavior? Or maybe can you suggest any workarounds?

@nene
Copy link
Collaborator

nene commented May 4, 2023

For SQLite I can suggest a new SQL formatting library that I've been developing: prettier-plugin-sql-cst

@karlhorky
Copy link
Contributor

karlhorky commented Oct 31, 2023

Edit: The problem I described below is resolved in sql-formatter@14.0.0 and later with the postgresql language/dialect as mentioned by @nwalters512


Yeah this is also happening with PostgreSQL, the now() function has an extra space between the function name and the parentheses:

Input:

SELECT
  users.id,
  users.username
FROM
  users
  INNER JOIN sessions ON (
    sessions.token = 'abc123'
    AND users.id = sessions.user_id
    AND sessions.expiry_timestamp > now()
  )

Expected Output (no change):

SELECT
  users.id,
  users.username
FROM
  users
  INNER JOIN sessions ON (
    sessions.token = 'abc123'
    AND users.id = sessions.user_id
    AND sessions.expiry_timestamp > now()
  )

Actual Output (extra space between now and ()):

SELECT
  users.id,
  users.username
FROM
  users
  INNER JOIN sessions ON (
    sessions.token = 'abc123'
    AND users.id = sessions.user_id
    AND sessions.expiry_timestamp > now ()
  )

@nwalters512
Copy link
Contributor

@karlhorky did you set language: 'postgresql' in your config? NOW might not necessary be recognized as a function if you haven't specified the language. For reference, the NOW function is handled here:

@karlhorky
Copy link
Contributor

@pjxxcc
Copy link

pjxxcc commented Nov 6, 2023

Encountering the same issue, can we consider exhaustively listing scenarios where spaces are needed before parentheses for handling? In all other cases, remove spaces in front of parentheses.
For example, keywords like:

where 
when 
and 
join 
as 
+ 
- 
* 
/ 
(

@Brookke
Copy link

Brookke commented Dec 19, 2023

Also seeing the same issue with postgresql:

Input

create or replace function find_array_element(el anyelement, arr anyarray) returns integer as $$ declare i int;
begin
    for i in 1..array_upper( arr, 1 ) loop
        if( el = arr[i] ) then
            return i;
        end if;
    end loop;
    return 0;
end;
$$ language plpgsql;

output

create
or replace function find_array_element (el anyelement, arr anyarray) returns integer as $$
declare
    i int;
begin
    for i in 1..array_upper( arr, 1 ) loop
        if( el = arr[i] ) then
            return i;
        end if;
    end loop;

    return 0;
end;
$$ language plpgsql;

expected

create
or replace function find_array_element(el anyelement, arr anyarray) returns integer as $$
declare
    i int;
begin
    for i in 1..array_upper( arr, 1 ) loop
        if( el = arr[i] ) then
            return i;
        end if;
    end loop;

    return 0;
end;
$$ language plpgsql;

prettier config:

{
    "trailingComma": "es5",
    "proseWrap": "always",
    "plugins": [
      "prettier-plugin-sql"
    ],
    "language": "postgresql",
    "paramTypes": "{'named':[':']}"
}

@nene nene changed the title [FORMATTING] SQLite: user-defined functions and table-valued functions have an extra space User-defined functions and table-valued functions have an extra space May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants