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

tracking: support for Grafana #10134

Closed
5 tasks done
neverchanje opened this issue Jun 2, 2023 · 8 comments
Closed
5 tasks done

tracking: support for Grafana #10134

neverchanje opened this issue Jun 2, 2023 · 8 comments

Comments

@neverchanje
Copy link
Contributor

neverchanje commented Jun 2, 2023

Is your feature request related to a problem? Please describe.

The remaining works:

The original queries:

SELECT quote_ident(table_name) FROM information_schema.tables WHERE
quote_ident(table_schema) IN (
  SELECT
    CASE WHEN trim(s[i]) = '"$user"' THEN user ELSE trim(s[i]) END
  FROM
    generate_series(
      array_lower(string_to_array(current_setting('search_path'),','),1),
      array_upper(string_to_array(current_setting('search_path'),','),1)
    ) as i,
    string_to_array(current_setting('search_path'),',') s
) ORDER BY table_name limit 100;

Describe the solution you'd like

No response

Describe alternatives you've considered

No response

Additional context

No response

@github-actions github-actions bot added this to the release-0.20 milestone Jun 2, 2023
@neverchanje
Copy link
Contributor Author

Another query:

SELECT
        quote_ident(table_name) as table_name,
        ( SELECT
            quote_ident(column_name) as column_name
          FROM information_schema.columns c
    WHERE
      c.table_schema = t.table_schema AND
      c.table_name = t.table_name AND
      udt_name IN ('timestamptz','timestamp')
    ORDER BY ordinal_position LIMIT 1
  ) AS time_column,
  ( SELECT
      quote_ident(column_name) AS column_name
    FROM information_schema.columns c
    WHERE
      c.table_schema = t.table_schema AND
      c.table_name = t.table_name AND
      udt_name='float8'
    ORDER BY ordinal_position LIMIT 1
  ) AS value_column
FROM information_schema.tables t
WHERE
quote_ident(table_schema) IN (
  SELECT
    CASE WHEN trim(s[i]) = '"$user"' THEN user ELSE trim(s[i]) END
  FROM
    generate_series(
      array_lower(string_to_array(current_setting('search_path'),','),1),
      array_upper(string_to_array(current_setting('search_path'),','),1)
    ) as i,
    string_to_array(current_setting('search_path'),',') s
) AND
  EXISTS
  ( SELECT 1
    FROM information_schema.columns c
    WHERE
      c.table_schema = t.table_schema AND
      c.table_name = t.table_name AND
      udt_name IN ('timestamptz','timestamp')
  ) AND
  EXISTS
  ( SELECT 1
    FROM information_schema.columns c
    WHERE
      c.table_schema = t.table_schema AND
      c.table_name = t.table_name AND
      udt_name='float8'
  )
LIMIT 1
;

@yezizp2012
Copy link
Member

SELECT quote_ident(table_name) FROM information_schema.tables WHERE
quote_ident(table_schema) IN (
  SELECT
    CASE WHEN trim(s[i]) = '"$user"' THEN user ELSE trim(s[i]) END
  FROM
    generate_series(
      array_lower(string_to_array(current_setting('search_path'),','),1),
      array_upper(string_to_array(current_setting('search_path'),','),1)
    ) as i,
    string_to_array(current_setting('search_path'),',') s
) ORDER BY table_name limit 100;

In this SQL, we can see that PostgreSQL can bind string_to_array as a table with a single value under column s. And actually PostgreSQL will bind the alias in two different ways if provided, take generate_series as example:

postgres=# select a from generate_series(1, 5) a; // a will bind to column.
 a
---
 1
 2
 3
 4
 5
(5 rows)

postgres=# select a.a from generate_series(1, 5) a; // a will bind to a table a with column a.
 a
---
 1
 2
 3
 4
 5
(5 rows)

But in rw, we don't allow to bind scalar function in from section, and the infer column name will always be the function name. To achieve that, two major changes are needed in the frontend:

  1. be able to bind scalar function as table function, it will return a table with one row and one column named after the alias (if provided) or the function name.
  2. dynamically bind the column names of the query, bind to the alias if provided.

Cc @xxchan , Could you help with this if you have time? Since you are more familiar with the table function piece. 🙏

@xxchan

This comment was marked as resolved.

@xxchan

This comment was marked as resolved.

@xxchan

This comment was marked as resolved.

@xiangjinwu
Copy link
Contributor

xiangjinwu commented Jun 12, 2023

  SELECT
    CASE WHEN trim(s[i]) = '"$user"' THEN user ELSE trim(s[i]) END
  FROM
    generate_series(
      array_lower(string_to_array(current_setting('search_path'),','),1),
      array_upper(string_to_array(current_setting('search_path'),','),1)
    ) as i,
    string_to_array(current_setting('search_path'),',') s

Just FYI this subquery has a simpler form for PostgreSQL >= 14, thanks to the introduction of string_to_table function. However grafana would not use this even when the server version is newer.

SELECT
    CASE WHEN trim(s) = '"$user"' THEN user ELSE trim(s) END
FROM
    string_to_table(current_setting('search_path'),',') s;

@neverchanje
Copy link
Contributor Author

neverchanje commented Jun 16, 2023

Another issue found: cc @yezizp2012

@neverchanje
Copy link
Contributor Author

Close this issue together with #9097. I've tested the Grafana integration and I didn't experience any errors and the ComputeNode as well as Frontend didn't output errors.

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

No branches or pull requests

4 participants