Listagg Redshift DDL - sql

I am trying to retrieve the DDL for a table in Redshift. I found this view where I can easily select the definition for any table. However I need this information in one line, and I know that there is this Listagg function, but if I try to do this:
select listagg(ddl, ' ')
from admin.v_generate_tbl_ddl
where schemaname = 'schema'
and tablename = 'orders'
It's giving me this error:
Query execution failed
Reason: SQL Error [XX000]: ERROR: One or more of the used functions
must be applied on at least one user created tables. Examples of user
table only functions are LISTAGG, MEDIAN, PERCENTILE_CONT, etc
Can You please help me on how can I achieve this?

listagg function is a compute-node only function.
But the query you run to get the table ddl runs only on leader because it only specifies pg_* tables.
According to AWS documentation
A query that references only catalog tables (tables with a PG prefix, such as PG_TABLE_DEF) or that does not reference any tables, runs exclusively on the leader node.
If a query that uses a compute-node function doesn't reference a user-defined table or Amazon Redshift system table returns the following error.
[Amazon] (500310) Invalid operation: One or more of the used functions must be applied on at least one user created table.
https://docs.aws.amazon.com/redshift/latest/dg/c_SQL_functions_compute_node_only.html
To sum up, since your query does not reference any user created table, you can not use listagg

Related

Get query used to create a table

We use snowflake at work to store data, and for one of the tables, I dont have the SQL query used to create the table. Is there a way to see the query used to make that table?
I tried using the following
get_ddl('table', 'db.table', true)
but this gives me an output like-
This doesnt give me any information about the sql query that was used. How do I get that in snowflake?
If get_ddl() is not enough you may use INFORMATION_SCHEMA.
To get more information you have 2 options:
Use the QUERY_HISTORY() table functions: https://docs.snowflake.com/en/sql-reference/functions/query_history.html
Use the QUERY_HISTORY() view: https://docs.snowflake.com/en/sql-reference/account-usage/query_history.html
If you use the funtions/view above and filter all the records by QUERY_TEXT, maybe you get more information about the exact SQL that was used to create your table.

How do I generate a table name that contains today's date?

It may seem a little strange, but there are already tables with names for each date.
In my project, I have tables for each date to make statistics easier to handle.
Of course, I don't think this is always the best way, but this is the table structure for my project.
(It's a common technique in Google BigQuery and Amazon Athena. This question is about Google BigQuery)
So to get the data, I want to generate today's date. If I use TODAY, I can get the data of the latest day without rewriting the code even if it is the next day.
I tried, but the code didn't work.
Not work 1:
CONCAT in FROM
SELECT
*
FROM
CONCAT('foo_', FORMAT_TIMESTAMP('%Y%m%d', CURRENT_TIMESTAMP(), 'Asia/Tokyo'))
Error:
Table-valued function not found: CONCAT at [4:3]
Not work 2:
create temporary function:
create temporary function getTableName() as (CONCAT('foo_', FORMAT_TIMESTAMP('%Y%m%d', CURRENT_TIMESTAMP(), 'Asia/Tokyo')));
Error:
CREATE TEMPORARY FUNCTION statements must be followed by an actual query.
Question
How do I generate a table name that contains TODAY's date?
In this case, I would recommend you to use Wild tables in BigQuery, which allows you to use some features in Standard SQL.
With Wild Tables you can use _TABLE_SUFFIX, it grants you the ability to filter/scan tables containing this parameter. The syntax would be as follows:
SELECT *
FROM `test-proj-261014.sample.test_*`
where _TABLE_SUFFIX = FORMAT_DATE('%Y%m%d', CURRENT_DATE)
I hope it helps.
Your first query should go like this:
select CONCAT('foo_', FORMAT_TIMESTAMP('%Y%m%d', CURRENT_TIMESTAMP(), 'Asia/Tokyo'))
For creating temporary function, use the below code:
create temp function getTableName() as
((select CONCAT('foo_', FORMAT_TIMESTAMP('%Y%m%d', CURRENT_TIMESTAMP(), 'Asia/Tokyo'))
));
select getTableName()
The error "CREATE TEMPORARY FUNCTION statements must be followed by an actual query." is because once the temporary functions are defined then you have to use the actual query to use that function and then the validity of function dies out. To define persistent UDFs and use them in multiple queries please go through the link to define permanent functions.You can reuse persistent UDFs across multiple queries, whereas you can only use temporary UDFs in a single query.

AWS Redshift Leader Node-Only Function with table reference

I have a requirement to pass the server address, server port, and the count from a table in one query in AWS Redshift. i.e.
select inet_server_addr(), inet_server_port(), count(*) from my_table;
ERROR: 0A000: Specified types or functions (one per INFO message) not
supported on Redshift tables.
I understand that this query does not work because I am trying to execute a Leader Node-Only Function in conjunction with a query which needs to access the compute nodes.
I am wondering, however, if there is a work around available to get the information that I need in one query execution.
Note: Editing the above query to use common table expressions (cte), sub-queries, views, scalar-functions etc results in the same error message.
Note 2: PostgreSQL System information functions like inet_server_addr() are currently unsupported in AWS Redshift, however, they work when called without a table reference.

SQLite given a statement it is possible to know what table will be touched [duplicate]

I am using sqlite in a C++ project and I would like to be able to get the table names involved in a query.
Ex:
SELECT * FROM Employee
should return Employee
Now I use successfully qlite3_column_table_name (doc) for this kind of queries but for aggregate queries, the function returns null as the result does not belong to a table directly.
ex:
SELECT SUM(salary) AS total FROM Employee
Surely, when sqlite compiles the statement, the "Employee" keyword is recognised as a table. Do you know aby way to have access to this?
I tried to step through the code of the parser without success...
An authorizer callback allows you to detect which tables are actually accessed by a query.

Bind variables in the from clause for Postgres

I'm attempting to write an extension for SQL Developer to better support Postgres. These are just XML configuration files with SQL snippets in them. To display the values for a postgres sequence, I need to run a simple query of the following form:
select * from schema.sequence
The trouble with this is that the Oracle SQL Developer environment provides the correct schema and node (sequence) name as bind variables. This would mean that I should format the query as:
select * from :SCHEMA.:NAME
The trouble with this is that bind variables are only valid in the select clause or the where clause (as far as I'm aware), and using this form of the query returns a "syntax error at or near "$1" error message.
Is there a way to return the values in the sequence object without directly selecting them from the sequence? Perhaps some obtuse joined statement from pg_catalog tables?
Try this:
select *
from information_schema.sequences
where sequence_name = :name
and sequence_schema = :schema;
It's not exactly the same thing as doing a select from the sequence, but the basic information is there.