diff --git a/db/pgConn.cpp b/db/pgConn.cpp index c766b9c..9d27caf 100644 --- a/db/pgConn.cpp +++ b/db/pgConn.cpp @@ -486,11 +486,13 @@ bool pgConn::BackendMinimumVersion(int major, int minor) if (!majorVersion) { wxString version = GetVersionString(); + minorVersion = 0; + patchVersion = 0; sscanf(version.ToAscii(), "%*s %d.%d.%d", &majorVersion, &minorVersion, &patchVersion); isEdb = version.Upper().Matches(wxT("ENTERPRISEDB*")); - if (version.Upper().Matches(wxT("*11BETA*"))) { - majorVersion=11; - minorVersion=0; + if (!majorVersion) { + wxString vers=ExecuteScalar(wxT("SELECT current_setting('server_version_num');")); + sscanf(vers.ToAscii(), "%2d%04d", &majorVersion, &minorVersion); } // EnterpriseDB 8.3 beta 1 & 2 and possibly later actually have PostgreSQL 8.2 style // catalogs. This is expected to change either before GA, but in the meantime we diff --git a/dlg/dlgLanguage.cpp b/dlg/dlgLanguage.cpp index 7c8c5bc..af62b1f 100644 --- a/dlg/dlgLanguage.cpp +++ b/dlg/dlgLanguage.cpp @@ -114,7 +114,7 @@ int dlgLanguage::Go(bool modal) else { // create mode - if (connection->BackendMinimumVersion(8, 1)) + if (connection->BackendMinimumVersion(8, 1)&&(!connection->BackendMinimumVersion(13, 0))) { pgSetIterator languages(connection, wxT("SELECT tmplname FROM pg_pltemplate\n") diff --git a/include/schema/pgPublication.h b/include/schema/pgPublication.h index e1ce300..4f6bf9b 100644 --- a/include/schema/pgPublication.h +++ b/include/schema/pgPublication.h @@ -81,6 +81,15 @@ public: { return del; } + bool GetIsViaRoot() const + { + return publish_via_partition_root; + } + void iSetIsViaRoot(const bool b) + { + publish_via_partition_root = b; + } + wxString GetStrOper() const { wxString s = wxT(""); @@ -115,7 +124,7 @@ public: private: wxString tables, version; - bool all,ins,upd,del; + bool all,ins,upd,del, publish_via_partition_root; }; class pgPublicationCollection : public pgDatabaseObjCollection diff --git a/schema/pgPartition.cpp b/schema/pgPartition.cpp index f94d0d5..3a6d881 100644 --- a/schema/pgPartition.cpp +++ b/schema/pgPartition.cpp @@ -254,7 +254,18 @@ pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser query += wxT(",case when lk.relation=rel.oid then 'AccessExclusiveLock' else pg_get_expr(rel.relpartbound, rel.oid) end \n AS partexp"); query += wxT(",(select count(*)from pg_inherits ii where ii.inhparent=rel.oid)>0 AS ispartitioned"); - + if (collection->GetDatabase()->BackendMinimumVersion(10, 0)) + { + //query += wxT(",\n pg_get_statisticsobjdef(stat_ext.oid) AS stat_stmt"); + //query += wxT(",\nCASE WHEN stat_ext.stxowner<>rel.relowner then 'ALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s\\(')||' OWNER TO '||stat_ext.stxowner::regrole else null end AS alter_stmt"); + query += ",(select string_agg(pg_get_statisticsobjdef(stat_ext.oid)||CASE WHEN stat_ext.stxowner<>rl.relowner then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' OWNER TO '||stat_ext.stxowner::regrole else '' end" + ; + if (collection->GetDatabase()->BackendMinimumVersion(13, 0)) { + query += "||CASE WHEN stat_ext.stxstattarget<>-1 then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' SET STATISTICS '||stat_ext.stxstattarget else '' end"; + } + query += ",E';\\n' order by stat_ext.stxrelid) stat_stmt from pg_class rl join pg_statistic_ext stat_ext on rl.oid=stat_ext.stxrelid where stat_ext.stxrelid=rel.oid) stat_stmt"; + } + query += wxT(" FROM pg_class rel\n") wxT(" JOIN pg_inherits i ON (rel.oid = i.inhrelid) \n") wxT(" LEFT JOIN pg_locks lk ON locktype='relation' and granted=true and mode='AccessExclusiveLock' and relation=rel.oid\n") @@ -386,6 +397,11 @@ pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser table->iSetPartKeyDef(tables->GetVal(wxT("partkeydef"))); table->iSetPartExp(tables->GetVal(wxT("partexp"))); table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + wxString st = tables->GetVal(wxT("stat_stmt")); + //wxString at = tables->GetVal(wxT("alter_stmt")); + if (!st.IsEmpty()) if ((st.Right(1) != ";")) st = st + wxT(";\n"); + table->iSetStatExt(st); + } if (collection->GetConnection()->GetIsGreenplum()) { diff --git a/schema/pgPublication.cpp b/schema/pgPublication.cpp index e9cbee7..e60e101 100644 --- a/schema/pgPublication.cpp +++ b/schema/pgPublication.cpp @@ -110,12 +110,21 @@ wxString pgPublication::GetSql(ctlTree *browser) if (!GetTablesStr().IsEmpty()) sql += wxT("") + GetTablesStr(); } - if (GetIsIns()&&GetIsUpd()&&GetIsDel()) + if (GetIsIns()&&GetIsUpd()&&GetIsDel()&&!GetIsViaRoot()) { - } else + } + else { - sql += wxT("\n WITH (publish = '") + GetStrOper() + wxT("')"); + sql += wxT("\n WITH ("); + wxString opts = wxEmptyString; + if (!(GetIsIns() && GetIsUpd() && GetIsDel())) opts =opts+ "publish = '" + GetStrOper() + wxT("'"); + if (GetIsViaRoot()) { + if (!opts.IsEmpty()) opts += ","; + opts += "publish_via_partition_root = on"; + } + if (!opts.IsEmpty()) opts += ")"; + sql += opts; } sql += wxT(";\n"); @@ -158,8 +167,13 @@ pgObject *pgPublicationFactory::CreateObjects(pgCollection *collection, ctlTree { wxString sql; pgPublication *publication = 0; + wxString pg13=""; + if (collection->GetDatabase()->BackendMinimumVersion(13, 0)) { + pg13 = ", pubviaroot"; + } sql = wxT("select x.oid,x.pubname, pg_get_userbyid(x.pubowner) AS owner, x.puballtables, x.pubinsert, x.pubupdate, x.pubdelete, obj_description(x.oid,'pg_publication') AS comment, t.t") + + pg13 + wxT("\n") wxT(" FROM pg_publication x\n") wxT(" LEFT JOIN LATERAL (select string_agg(schemaname||'.'||tablename,', ') t from pg_publication_tables where pubname=x.pubname) t on true \n") wxT(" ") @@ -183,6 +197,7 @@ pgObject *pgPublicationFactory::CreateObjects(pgCollection *collection, ctlTree publication->iSetIsDel(publications->GetBool(wxT("pubdelete"))); //publication->iSetVersion(publications->GetVal(wxT("extversion"))); publication->iSetComment(publications->GetVal(wxT("comment"))); + if (!pg13.IsEmpty()) publication->iSetIsViaRoot(publications->GetBool(wxT("pubviaroot"))); if (browser) { diff --git a/schema/pgTable.cpp b/schema/pgTable.cpp index 9931dae..7ebbcc4 100644 --- a/schema/pgTable.cpp +++ b/schema/pgTable.cpp @@ -618,7 +618,7 @@ wxString pgTable::GetSql(ctlTree *browser) } } } - wxRegEx reg("vacuum_index_cleanup=[a-z]+|vacuum_truncate=[a-z]+|parallel_workers=[0-9]+|toast_tuple_target=[0-9]+|log_autovacuum_min_duration=[0-9]+|user_catalog_table=[a-z]+"); + wxRegEx reg("autovacuum_vacuum_insert_scale_factor=[0-9.]+|autovacuum_vacuum_insert_threshold=[0-9]+|vacuum_index_cleanup=[a-z]+|vacuum_truncate=[a-z]+|parallel_workers=[0-9]+|toast_tuple_target=[0-9]+|log_autovacuum_min_duration=[0-9]+|user_catalog_table=[a-z]+"); wxString relopt=GetRelOptions(); wxString o; size_t start, len; @@ -726,7 +726,7 @@ wxString pgTable::GetSql(ctlTree *browser) else sql += GetGrant(wxT("arwdRxt")); wxString st=GetStatExt(); - if (!st.IsEmpty()) sql += st + wxT(";\n"); + if (!st.IsEmpty()) sql += st + wxT("\n"); sql += GetCommentSql(); if (GetConnection()->BackendMinimumVersion(9, 1)) @@ -1572,8 +1572,14 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows if (collection->GetDatabase()->BackendMinimumVersion(10, 0)) { - query += wxT(",\n pg_get_statisticsobjdef(stat_ext.oid) AS stat_stmt"); - query += wxT(",\nCASE WHEN stat_ext.stxowner<>rel.relowner then 'ALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s\\(')||' OWNER TO '||stat_ext.stxowner::regrole else null end AS alter_stmt"); + //query += wxT(",\n pg_get_statisticsobjdef(stat_ext.oid) AS stat_stmt"); + //query += wxT(",\nCASE WHEN stat_ext.stxowner<>rel.relowner then 'ALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s\\(')||' OWNER TO '||stat_ext.stxowner::regrole else null end AS alter_stmt"); + query += ",(select string_agg(pg_get_statisticsobjdef(stat_ext.oid)||CASE WHEN stat_ext.stxowner<>rl.relowner then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' OWNER TO '||stat_ext.stxowner::regrole else '' end" + ; + if (collection->GetDatabase()->BackendMinimumVersion(13, 0)) { + query += "||CASE WHEN stat_ext.stxstattarget<>-1 then E';\\nALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s')||' SET STATISTICS '||stat_ext.stxstattarget else '' end"; + } + query += ",E';\\n' order by stat_ext.stxrelid) stat_stmt from pg_class rl join pg_statistic_ext stat_ext on rl.oid=stat_ext.stxrelid where stat_ext.stxrelid=rel.oid) stat_stmt"; } query += wxT(" FROM pg_class rel\n") wxT(" LEFT JOIN pg_locks lk ON locktype='relation' and granted=true and mode='AccessExclusiveLock' and relation=rel.oid\n") @@ -1591,8 +1597,6 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows if (collection->GetConnection()->BackendMinimumVersion(9, 0)) query += wxT("LEFT JOIN pg_type typ ON rel.reloftype=typ.oid\n"); - if (collection->GetConnection()->BackendMinimumVersion(10, 0)) - query += wxT("LEFT JOIN pg_statistic_ext stat_ext ON rel.oid=stat_ext.stxrelid\n"); query += wxT(" WHERE ")+pg10+wxT(" rel.relkind IN ('r','s','t','p') AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); @@ -1733,8 +1737,8 @@ pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *brows table->iSetPartExp(tables->GetVal(wxT("partexp"))); table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); wxString st = tables->GetVal(wxT("stat_stmt")); - wxString at = tables->GetVal(wxT("alter_stmt")); - if (!st.IsEmpty()&&!at.IsEmpty()) st=st+wxT(";\n")+at; + //wxString at = tables->GetVal(wxT("alter_stmt")); + if (!st.IsEmpty()) if ((st.Right(1) != ";") ) st=st+wxT(";\n"); table->iSetStatExt(st); }