Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get full length of DDL for a table or any object in redshift / postgresql

Team, I am working on redshift ( 8.0.2 ). I would like to have DDL command in place for any object type ( table / view...) in redshift.

I have below one. but it is not giving the full text.

select s.userid,u.usename,s.starttime, s.type, rtrim(s.text) from svl_statementtext s, pg_user u
 where u.usesysid = s.userid
 and s.type = 'DDL' 
 and s.text like '%table11%' 
 order by s.starttime asc;

 userid |                                                             usename                                                              |         starttime          | type |                                                                                                   text
--------+----------------------------------------------------------------------------------------------------------------------------------+----------------------------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    143 | user11                                                                                                                           | 2014-04-16 23:42:06.227296 | DDL  | CREATE TABLE table11 ( log_time date, user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time
    143 | user11                                                                                                                           | 2014-04-16 23:42:06.234987 | DDL  | CREATE TABLE table11 ( log_time date, user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time
(2 rows)

in Oracle we have DDL_METADATA.GET_DDL pkg. it will give the full text. I would like to have the same. I tried with STL_DDLTEXT. text is much trimmed.

select xid, starttime, sequence, substring(text,1,40) as text
from stl_ddltext where  userid = 100 and text like '%table11%'  order by xid desc, sequence;
  xid   |         starttime          | sequence |                   text
--------+----------------------------+----------+------------------------------------------
 135475 | 2014-04-16 23:42:06.234987 |        0 | CREATE TABLE table11 ( log_time dat
 135475 | 2014-04-16 23:42:06.227296 |        0 | CREATE TABLE table11 ( log_time dat
(2 rows)

I have few more doubts on the first query output. the column lenght of "usename" is too high. how to trim that. If i query pg_user, it is trimmed internally. IN oracle we can have for e.g.

" col <col_name> for a80  " 

second doubt: i am getting 2 rows. actually i created only one table. Any reason for 2 rows in the output ?

for e.g. in physical postgre db, if we want to generate any ddl for one function, we can use below.

in the below, function name is "add"

SELECT pg_catalog.pg_get_functiondef('add'::regproc);

like this, do we have any pkg in Redshift for table/views ?

Thanks

like image 848
user3258784 Avatar asked Apr 16 '14 23:04

user3258784


People also ask

How do you get DDL of a table in Redshift?

STEP 1: Create view "v_generate_schema_ddl" You can recreate the table/schema DDL by running scripts called v_generate_tbl_ddl. sql and v_generate_schema_ddl. sql. The scripts can be downloaded from amazon-redshift-utils, which is part of the Amazon Web Services - Labs git hub repository.

How do you get DDL of a table in Postgres?

Using psql command \d You can get the DDL just by running \d. This works only for table-like objects.

How do you get the size of a table in Redshift?

Getting Table Sizes. The simplest method for listing the size of your database tables is to use a handy and official script provided by Amazon Redshift Utilities, table_info. sql .


2 Answers

I have not found a single function in Redshift that provides this functionality. You can get the full definition of views by using the pg_get_viewdef function:

SELECT 'create view '|| nc.nspname::information_schema.sql_identifier ||'.'|| c.relname::information_schema.sql_identifier ||' as '||
 pg_get_viewdef(c.oid)::information_schema.character_data AS view_definition
FROM pg_namespace nc, pg_class c, pg_user u
WHERE c.relnamespace = nc.oid AND u.usesysid = c.relowner AND c.relkind = 'v'::"char" 
AND nc.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema');

For table definitions I've put together a query, but it still needs a little work to fill in some details as noted in the commented lines:

select tm.schemaname||'.'||tm.tablename, 'create table '||tm.schemaname||'.'||tm.tablename
||' ('
||cp.coldef
-- primary key
-- diststyle
-- dist key
||d.distkey
--sort key 
|| (select 
' sortkey(' ||substr(array_to_string(
                 array( select ','||cast(column_name as varchar(100))  as str from
                       (select column_name from information_schema.columns col where  col.table_schema= tm.schemaname and col.table_name=tm.tablename) c2
                        join 
                        (-- gives sort cols
                          select attrelid as tableid, attname as colname, attsortkeyord as sort_col_order from pg_attribute pa where 
                          pa.attnum > 0  AND NOT pa.attisdropped AND pa.attsortkeyord > 0
                        ) st on tm.tableid=st.tableid and c2.column_name=st.colname   order by sort_col_order
                      )
                ,'')
              ,2,10000) || ')'
)
||';'
from 
-- t  master table list
(
SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid 
FROM pg_namespace n, pg_class c
WHERE n.oid = c.relnamespace 
AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
AND c.relname <> 'temp_staging_tables_1'
-- and c.relname in ('f_recipient_registration','ht_base_document','ht_folder','ht_logical_file','ht_transaction_addresses','ht_ysi_batch','ht_ysi_batch_messages','ht_ysi_files') 
) tm 
-- cp  creates the col params for the create string
join
(select 
substr(str,(charindex('QQQ',str)+3),(charindex('ZZZ',str))-(charindex('QQQ',str)+3)) as tableid
,substr(replace(replace(str,'ZZZ',''),'QQQ'||substr(str,(charindex('QQQ',str)+3),(charindex('ZZZ',str))-(charindex('QQQ',str)+3)),''),2,10000) as coldef
from
( select array_to_string(array(
SELECT  'QQQ'||cast(t.tableid as varchar(10))||'ZZZ'|| ','||column_name||' '|| decode(udt_name,'bpchar','char',udt_name) || decode(character_maximum_length,null,'', '('||cast(character_maximum_length as varchar(9))||')'   )
-- default
|| decode(substr(column_default,2,8),'identity','',null,'',' default '||column_default||' ')
-- nullable
|| decode(is_nullable,'YES',' NULL ','NO',' NOT NULL ') 
-- identity 
|| decode(substr(column_default,2,8),'identity',' identity('||substr(column_default,(charindex('''',column_default)+1), (length(column_default)-charindex('''',reverse(column_default))-charindex('''',column_default)   ) )  ||') ', '') as str 
from  
-- ci  all the col info
(
select cast(t.tableid as int), cast(table_schema as varchar(100)), cast(table_name as varchar(100)), cast(column_name as varchar(100)), 
cast(ordinal_position as int), cast(column_default as varchar(100)), cast(is_nullable as varchar(20)) , cast(udt_name as varchar(50))  ,cast(character_maximum_length as int),
sort_col_order  , decode(d.colname,null,0,1) dist_key 
from (select * from information_schema.columns c where  c.table_schema= t.schemaname and c.table_name=t.tablename) c
left join 
(-- gives sort cols
select attrelid as tableid, attname as colname, attsortkeyord as sort_col_order from  pg_attribute a where 
 a.attnum > 0  AND NOT a.attisdropped AND a.attsortkeyord > 0
) s on t.tableid=s.tableid and c.column_name=s.colname
left join 
-- gives dist col
(select attrelid as tableid, attname as colname from pg_attribute a where
  a.attnum > 0 AND NOT a.attisdropped  AND a.attisdistkey = 't'
) d on t.tableid=d.tableid and c.column_name=d.colname
order by ordinal_position
) ci 
-- for the working array funct
), '') as str
from 
(-- need tableid
SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid 
FROM pg_namespace n, pg_class c
WHERE n.oid = c.relnamespace 
AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
) t 
-- for the agg functions that dont exist
-- ) group by table_schema, table_name 
)) cp on tm.tableid=cp.tableid
-- add in primary key query here
-- dist key
left join
(  select 
-- close off the col defs after the primary key 
')' ||
' distkey('|| cast(column_name as varchar(100)) ||')'  as distkey, t.tableid
from information_schema.columns c
join 
(-- need tableid
  SELECT substring(n.nspname,1,100) as schemaname, substring(c.relname,1,100) as tablename, c.oid as tableid 
  FROM pg_namespace n, pg_class c
  WHERE n.oid = c.relnamespace 
  AND nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
) t on c.table_schema= t.schemaname and c.table_name=t.tablename
join 
-- gives dist col
(select attrelid as tableid, attname as colname from pg_attribute a where
  a.attnum > 0 AND NOT a.attisdropped  AND a.attisdistkey = 't'
  ) d on t.tableid=d.tableid and c.column_name=d.colname    
) d on tm.tableid=d.tableid 
like image 110
mike_pdb Avatar answered Oct 16 '22 23:10

mike_pdb


For DDL:

  • First create the admin view here: https://github.com/awslabs/amazon-redshift-utils/blob/master/src/AdminViews/v_generate_tbl_ddl.sql

  • Next write a query like this:

    select ddl
    from admin.v_generate_tbl_ddl
    where schemaname = 'some_schema' and tablename='some_table'
    order by seq asc
    
like image 41
jasonS Avatar answered Oct 16 '22 23:10

jasonS