/* ********** * http://sourceforge.jp/projects/pgshowcreatetbl/ = show create table for PostgreSQL = * This SQL function returns a CREATE TABLE statement for the table assigned. * PostgreSQL ã«ã¦ CREATE TABLE 文をå–å¾—ã™ã‚‹ãŸã‚ã® SQL 関数ã§ã™ã€‚ PostgreSQL ã§ã¯ pg_dump --schema-only コマンド㧠CREATE TABLE 文をå–å¾—ã§ãã¾ã™ãŒã€ DB 接続や psql コンソールãªã©ã‹ã‚‰å–å¾—ã™ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“。 本 SQL ã¯ã€ãれを実ç¾ã™ã‚‹ãŸã‚ã®ã‚‚ã®ã§ã™ã€‚ = Features = * ã“ã®ãƒ•ァンクションã¯ã€SQLæ–‡1ã¤ã‹ã‚‰æ§‹æˆã•れã¾ã™ã®ã§ã€ * PostgreSQL ã®è¨å®šå¤‰æ›´ãªã—ã«åˆ©ç”¨ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ * '''PHP, Java, Ruby ç‰ã€ãŠå¥½ããªè¨€èªžã«çµ„ã¿è¾¼ã‚€ã“ã¨ãŒã§ãã¾ã™ã€‚''' * 例:1) $1, $2 を言語ã”ã¨ã®å¤‰æ•°ã«ã™ã‚‹ã€2) ダブルクオーテーションをエスケープã™ã‚‹ (" -> \") * This function is written in SQL. This brings the features that: * You do not need to re-configure your PostgreSQL settings. * '''You can embed this function in your preferred languages: PHP, Java, Ruby, etc...''' * example: 1) replace $1 and $2 into variables of the language you are going to use, 2) escape the double-quotations (" -> \") = Usage = {{{ code sql SELECT show_create_table('table_name', 'schema_name'); or SELECT show_create_table('table_name', null); }}} * schema_name ã‚’ null ã«ã™ã‚‹ã¨ã€å…¨ã‚¹ã‚ãƒ¼ãƒžãŒæ¤œç´¢ã®å¯¾è±¡ã«ãªã‚Šã¾ã™ã€‚ * If schema_name = null, all of the schema will be searched. = Install = * psql シェルã§ã‚³ãƒ”ー&ペーストã™ã‚‹ãªã©ã—ã¦ãã ã•ã„。 * copy & paste in psql shell. = Available versions = * v8.3.8 * v8.3.x (probably...) * v8.x (maybe...) * 動作ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã”å ±å‘Šã‚’é ‚ã‘ã‚‹ã¨æœ‰ã‚Šé›£ã„ã§ã™ã€‚ * If this function successfully runs on your PostgreSQL, please tell me your version! * http://sourceforge.jp/forum/forum.php?forum_id=23996 = known bugs = * see http://sourceforge.jp/projects/pgshowcreatetbl/ticket/?type[]=19647&type_mode[]=eq&status[]=1&view=type * ********** */ CREATE OR REPLACE FUNCTION show_create_table(varchar /*table*/, varchar /*schema*/) returns text as $$ /* * show create table for PostgreSQL v0.6 * 2010.9.3 Tadashi Murakami * * Bug reports are welcome: * http://sourceforge.jp/projects/pgshowcreatetbl/ * * Licensed under the Apache License, Version 2.0. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 */ SELECT CASE WHEN tb.relkind = 'r' THEN (/*0*/ SELECT 'CREATE TABLE ' || $1 || ' (' || chr(10) || array_to_string (/*1,2*/ARRAY( SELECT ' "'||"Column" ||'" '|| "Type" || "Modifiers" || "Index" FROM (/*3*/ SELECT at.attnum, ns.nspname as schema, tb.relname as table, at.attname as "Column", /* Type */ CASE WHEN at.attinhcount<>0 OR at.attisdropped THEN null ELSE CASE WHEN tp.typname = 'int2' THEN 'smallint' WHEN tp.typname = 'int4' THEN 'integer' WHEN tp.typname = 'int8' THEN 'bigint' WHEN tp.typname = 'float4' THEN 'real' WHEN tp.typname = 'float8' THEN 'double precision' WHEN tp.typname = 'bpchar' THEN 'char' ELSE tp.typname END || CASE WHEN at.attlen >= 0 THEN '' WHEN at.atttypmod < 4 THEN '' WHEN tp.typname<>'numeric' THEN '('|| at.atttypmod-4 ||')' WHEN (at.atttypmod & 65535) = 4 THEN '('|| (at.atttypmod >> 16) ||')' ELSE '('|| (at.atttypmod >> 16) ||','|| (at.atttypmod & 65535)-4 ||')' END END as "Type", /* Modifiers */ CASE WHEN at.attnotnull THEN ' not null' ELSE '' END || CASE WHEN ad.adbin IS NULL THEN '' ELSE ' default ' || pg_get_expr(ad.adbin, tb.oid) END as "Modifiers", /* one-column Index */ CASE WHEN ix.indexrelid IS NULL THEN '' ELSE CASE WHEN ix.indisprimary THEN ' PRIMARY KEY' WHEN ix.indisunique THEN ' UNIQUE' ELSE ' /* index */' END || CASE WHEN am.amname <> 'btree' THEN ' /*'||am.amname||'*/' ELSE '' END || ' /* '|| ic.relname ||' */' END as "Index" -- , tb.*, at.*, tp.* FROM pg_attribute at -- -- for Type, Modifiers -- INNER JOIN pg_type tp ON at.atttypid = tp.oid LEFT OUTER JOIN pg_attrdef ad ON ad.adrelid = tb.oid AND ad.adnum = at.attnum -- -- for one-column Index -- LEFT OUTER JOIN pg_index ix ON ix.indrelid = tb.oid AND ix.indnatts = 1 AND at.attnum = ix.indkey[0] LEFT OUTER JOIN pg_class ic ON ix.indexrelid = ic.oid LEFT OUTER JOIN pg_am am ON ic.relam = am.oid -- WHERE tb.oid = at.attrelid AND at.attnum >= 1 )/*3*/ as columns ORDER BY attnum ), ','||chr(10))/*2,1*/ -- -- -- multi-columns Index -- -- ||(/*1*/ SELECT CASE WHEN count(*) = 0 THEN '' ELSE ','||chr(10)||' '|| array_to_string (/*2,3*/ARRAY( SELECT CASE WHEN indisprimary THEN 'PRIMARY KEY ' ELSE 'UNIQUE ' END || substr(indexdef, strpos(indexdef, '('), strpos(indexdef, ')') - strpos(indexdef, '(') + 1) || ' /* '||index||' */' FROM (/*4*/ SELECT ic.relname as index, ns.nspname as schema, tb.relname as table -- , ia.attname, ia.attnum , ix.indnatts, ix.indisunique, ix.indisprimary, am.amname , ix.indkey , pg_get_indexdef(ic.oid) as indexdef -- , pg_get_expr(ix.indexprs, ix.indrelid), pg_get_expr(ix.indpred, ix.indrelid) FROM pg_index ix INNER JOIN pg_class ic ON ix.indexrelid = ic.oid INNER JOIN pg_am am ON ic.relam = am.oid -- LEFT OUTER JOIN pg_attribute ia ON ia.attnum = any(ix.indkey) AND ia.attrelid = tb.oid WHERE ix.indrelid = tb.oid AND ix.indnatts > 1 AND (ix.indisprimary OR ix.indisunique) )/*4*/ as def ORDER BY indisprimary desc, index), ','||chr(10) )/*3,2*/ END -- copy from the above conditions FROM pg_index ix WHERE ix.indrelid = tb.oid AND ix.indnatts > 1 AND (ix.indisprimary OR ix.indisunique) )/*1*/ || chr(10) || ')' )/*0*/ WHEN tb.relkind = 'v' THEN 'CREATE VIEW ' || $1 || ' AS (' || chr(10) || trim(trailing ';' from pg_get_viewdef(tb.oid)) || chr(10) || ')' ELSE '/* pg_class.relkind='''||tb.relkind||''' */' END as show_create_table FROM pg_class tb INNER JOIN pg_namespace ns ON tb.relnamespace = ns.oid WHERE tb.relname = $1 AND (/*0*/ ($2 IS NOT NULL AND ns.nspname = $2) OR (/*1,2*/$2 IS NULL AND ns.nspname = ( SELECT ns.nspname -- FROM pg_class tb, pg_namespace ns -- WHERE tb.relname = $1 -- AND tb.relnamespace = ns.oid WHERE strpos(replace(current_setting('search_path'), '"$user"', current_user), ns.nspname) = (/*3*/ SELECT MIN(strpos(replace(current_setting('search_path'), '"$user"', current_user), ns2.nspname)) FROM pg_class tb2, pg_namespace ns2 WHERE tb2.relname = $1 AND tb2.relnamespace = ns2.oid )/*3*/ ))/*2,1*/ )/*0*/ $$ language sql;