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

Add option to configure newline after keywords #66

Open
bartlomieju opened this issue Nov 14, 2024 · 7 comments
Open

Add option to configure newline after keywords #66

bartlomieju opened this issue Nov 14, 2024 · 7 comments

Comments

@bartlomieju
Copy link

bartlomieju commented Nov 14, 2024

A query like this:

SELECT * FROM users WHERE id = 1;

gets formatted as:

SELECT
  *
FROM
  users
WHERE
  id = 1;

Would it be possible to configure the formatter to only add newline if there is more than one item following a keyword?

So in another example I'd like to be able to format this:

SELECT * FROM users WHERE id = 1;

SELECT id, name, email, created_at FROM users WHERE id = 1;

into this:

SELECT * FROM users WHERE id = 1;

SELECT
  id,
  name,
  email,
  created_at
FROM users WHERE id = 1;
-- or this
SELECT
  id,
  name,
  email,
  created_at
FROM users
WHERE id = 1;
@shssoichiro
Copy link
Owner

@lu-zero is this resolved by #74?

@lu-zero
Copy link
Contributor

lu-zero commented Jan 17, 2025

With #75 it should be possible to have the last layout specified, but it would need another bit of logic to inline the next top level keyword.

lu-zero added a commit to lu-zero/sqlformat-rs that referenced this issue Jan 20, 2025
lu-zero added a commit to lu-zero/sqlformat-rs that referenced this issue Jan 20, 2025
lu-zero added a commit to lu-zero/sqlformat-rs that referenced this issue Jan 21, 2025
lu-zero added a commit to lu-zero/sqlformat-rs that referenced this issue Jan 27, 2025
lu-zero added a commit to lu-zero/sqlformat-rs that referenced this issue Jan 27, 2025
@lu-zero
Copy link
Contributor

lu-zero commented Jan 31, 2025

Now we have a mean to have a fairly compact formatting:

    fn it_formats_blocks_inline_or_not() {
        let input = " UPDATE t SET o = ($5 + $6 + $7 + $8),a = CASE WHEN $2
            THEN NULL ELSE COALESCE($3, b) END, b = CASE WHEN $4 THEN NULL ELSE
            COALESCE($5, b) END, s = (SELECT true FROM bar WHERE bar.foo = $99),
            c = CASE WHEN $6 THEN NULL ELSE COALESCE($7, c) END,
            d = CASE WHEN $8 THEN NULL ELSE COALESCE($9, d) END,
            e = (SELECT true FROM bar) WHERE id = $1";
        let options = FormatOptions {
            max_inline_arguments: Some(50),
            max_inline_block: 100,
            max_inline_top_level: Some(10),
            ..Default::default()
        };
        let expected = indoc!(
            "
          UPDATE t
          SET
            o = ($5 + $6 + $7 + $8),
            a = CASE WHEN $2 THEN NULL ELSE COALESCE($3, b) END,
            b = CASE WHEN $4 THEN NULL ELSE COALESCE($5, b) END,
            s = (SELECT true FROM bar WHERE bar.foo = $99),
            c = CASE WHEN $6 THEN NULL ELSE COALESCE($7, c) END,
            d = CASE WHEN $8 THEN NULL ELSE COALESCE($9, d) END,
            e = (SELECT true FROM bar)
          WHERE id = $1"
        );

        assert_eq!(format(input, &QueryParams::None, &options), expected);
    }

I'm only unsure if max_inline_block and max_inline_top_level should be collapsed as it is done.

@bartlomieju
Copy link
Author

Oh that's sweet! We're about to release Deno 2.2 next week, so it would be lovely if we could include that setting.

@lu-zero
Copy link
Contributor

lu-zero commented Jan 31, 2025

It needs more tweaking and fixes, it doesn't yet return in the columnar mode correctly when limits are hit.

@lu-zero
Copy link
Contributor

lu-zero commented Feb 1, 2025

The hack from last night was abusing the different rules pretty much twisting them to the opposite of what they should, if somebody wants to help we need to:

  • compute the span between commas within either a block or a top level span and decide if we want to stay inline or columnar over a variable
  • store more information on the indent and inlineblock level so the rules for nested top levels always work
  • write more tests to make sure all the rules combination are behaving right.

@lu-zero
Copy link
Contributor

lu-zero commented Feb 3, 2025

    #[test]
    fn it_formats_blocks_inline_or_not() {
        let input: &str = " UPDATE t SET o = ($5 + $6 + $7 + $8),a = CASE WHEN $2
            THEN NULL ELSE COALESCE($3, b) END, b = CASE WHEN $4 THEN NULL ELSE
            COALESCE($5, b) END, s = (SELECT true FROM bar WHERE bar.foo = $99 AND bar.foo > $100),
            c = CASE WHEN $6 THEN NULL ELSE COALESCE($7, c) END,
            d = CASE WHEN $8 THEN NULL ELSE COALESCE($9, dddddddd) + bbbbb END,
            e = (SELECT true FROM bar) WHERE id = $1";
        let options: FormatOptions<'_> = FormatOptions {
            max_inline_arguments: Some(60),
            max_inline_block: 60,
            max_inline_top_level: Some(60),
            ..Default::default()
        };
        let expected: &str = indoc!(
            "
          UPDATE t
          SET
            o = ($5 + $6 + $7 + $8),
            a = CASE WHEN $2 THEN NULL ELSE COALESCE($3, b) END,
            b = CASE WHEN $4 THEN NULL ELSE COALESCE($5, b) END,
            s = (
              SELECT true
              FROM bar
              WHERE bar.foo = $99
              AND bar.foo > $100
            ),
            c = CASE WHEN $6 THEN NULL ELSE COALESCE($7, c) END,
            d = CASE
              WHEN $8 THEN NULL
              ELSE COALESCE($9, dddddddd) + bbbbb
            END,
            e = (SELECT true FROM bar)
          WHERE id = $1"
        );

        assert_eq!(format(input, &QueryParams::None, &options), expected);
    }

Now we are getting closer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants