支持gms_stats包
This commit is contained in:
@ -99,6 +99,7 @@ install:
|
||||
@if test -d contrib/dolphin; then $(MAKE) -C contrib/dolphin $@; fi
|
||||
@if test -d contrib/age; then $(MAKE) -C contrib/age $@; fi
|
||||
@if test -d contrib/datavec; then $(MAKE) -C contrib/datavec $@; fi
|
||||
@if test -d contrib/gms_stats; then $(MAKE) -C contrib/gms_stats $@; fi
|
||||
@if test -d contrib/gms_profiler; then $(MAKE) -C contrib/gms_profiler $@; fi
|
||||
+@echo "openGauss installation complete."
|
||||
endif
|
||||
|
||||
@ -112,6 +112,8 @@
|
||||
./share/postgresql/extension/dblink--1.0.sql
|
||||
./share/postgresql/extension/dblink--unpackaged--1.0.sql
|
||||
./share/postgresql/extension/dblink.control
|
||||
./share/postgresql/extension/gms_stats--1.0.sql
|
||||
./share/postgresql/extension/gms_stats.control
|
||||
./share/postgresql/extension/gms_profiler--1.0.sql
|
||||
./share/postgresql/extension/gms_profiler.control
|
||||
./share/postgresql/timezone/GB-Eire
|
||||
@ -808,6 +810,7 @@
|
||||
./lib/postgresql/dblink.so
|
||||
./lib/postgresql/pgoutput.so
|
||||
./lib/postgresql/assessment.so
|
||||
./lib/postgresql/gms_stats.so
|
||||
./lib/postgresql/gms_profiler.so
|
||||
./lib/libpljava.so
|
||||
./lib/libpq.a
|
||||
|
||||
@ -101,6 +101,8 @@
|
||||
./share/postgresql/extension/dblink--1.0.sql
|
||||
./share/postgresql/extension/dblink--unpackaged--1.0.sql
|
||||
./share/postgresql/extension/dblink.control
|
||||
./share/postgresql/extension/gms_stats--1.0.sql
|
||||
./share/postgresql/extension/gms_stats.control
|
||||
./share/postgresql/extension/gms_profiler--1.0.sql
|
||||
./share/postgresql/extension/gms_profiler.control
|
||||
./share/postgresql/timezone/GB-Eire
|
||||
@ -779,6 +781,7 @@
|
||||
./lib/postgresql/java/pljava.jar
|
||||
./lib/postgresql/postgres_fdw.so
|
||||
./lib/postgresql/dblink.so
|
||||
./lib/postgresql/gms_stats.so
|
||||
./lib/postgresql/gms_profiler.so
|
||||
./lib/libpljava.so
|
||||
./lib/libpq.a
|
||||
|
||||
@ -112,6 +112,8 @@
|
||||
./share/postgresql/extension/dblink--1.0.sql
|
||||
./share/postgresql/extension/dblink--unpackaged--1.0.sql
|
||||
./share/postgresql/extension/dblink.control
|
||||
./share/postgresql/extension/gms_stats--1.0.sql
|
||||
./share/postgresql/extension/gms_stats.control
|
||||
./share/postgresql/extension/gms_profiler--1.0.sql
|
||||
./share/postgresql/extension/gms_profiler.control
|
||||
./share/postgresql/timezone/GB-Eire
|
||||
@ -806,6 +808,7 @@
|
||||
./lib/postgresql/java/pljava.jar
|
||||
./lib/postgresql/postgres_fdw.so
|
||||
./lib/postgresql/dblink.so
|
||||
./lib/postgresql/gms_stats.so
|
||||
./lib/postgresql/pgoutput.so
|
||||
./lib/postgresql/assessment.so
|
||||
./lib/postgresql/gms_profiler.so
|
||||
|
||||
@ -24,6 +24,7 @@ set(CMAKE_MODULE_PATH
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gc_fdw
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ndpplugin
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/spq_plugin
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gms_stats
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/gms_profiler
|
||||
)
|
||||
|
||||
@ -42,6 +43,7 @@ add_subdirectory(pagehack)
|
||||
add_subdirectory(pg_xlogdump)
|
||||
add_subdirectory(file_fdw)
|
||||
add_subdirectory(log_fdw)
|
||||
add_subdirectory(gms_stats)
|
||||
if("${ENABLE_MULTIPLE_NODES}" STREQUAL "OFF")
|
||||
add_subdirectory(gc_fdw)
|
||||
endif()
|
||||
|
||||
21
contrib/gms_stats/CMakeLists.txt
Normal file
21
contrib/gms_stats/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
#This is the main CMAKE for build all gms_stats.
|
||||
# gms_stats
|
||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TGT_gms_stats_SRC)
|
||||
set(TGT_gms_stats_INC
|
||||
${PROJECT_OPENGS_DIR}/contrib/gms_stats
|
||||
${PROJECT_OPENGS_DIR}/contrib
|
||||
)
|
||||
|
||||
set(gms_stats_DEF_OPTIONS ${MACRO_OPTIONS})
|
||||
set(gms_stats_COMPILE_OPTIONS ${OPTIMIZE_OPTIONS} ${OS_OPTIONS} ${PROTECT_OPTIONS} ${WARNING_OPTIONS} ${LIB_SECURE_OPTIONS} ${CHECK_OPTIONS})
|
||||
set(gms_stats_LINK_OPTIONS ${LIB_LINK_OPTIONS})
|
||||
add_shared_libtarget(gms_stats TGT_gms_stats_SRC TGT_gms_stats_INC "${gms_stats_DEF_OPTIONS}" "${gms_stats_COMPILE_OPTIONS}" "${gms_stats_LINK_OPTIONS}")
|
||||
set_target_properties(gms_stats PROPERTIES PREFIX "")
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gms_stats.control
|
||||
DESTINATION share/postgresql/extension/
|
||||
)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gms_stats--1.0.sql
|
||||
DESTINATION share/postgresql/extension/
|
||||
)
|
||||
install(TARGETS gms_stats DESTINATION lib/postgresql)
|
||||
25
contrib/gms_stats/Makefile
Normal file
25
contrib/gms_stats/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
# contrib/gms_stats/Makefile
|
||||
MODULE_big = gms_stats
|
||||
OBJS = gms_stats.o
|
||||
|
||||
EXTENSION = gms_stats
|
||||
DATA = gms_stats--1.0.sql
|
||||
|
||||
REGRESS = gms_stats
|
||||
|
||||
ifdef USE_PGXS
|
||||
PG_CONFIG = pg_config
|
||||
PGXS := $(shell $(PG_CONFIG) --pgxs)
|
||||
include $(PGXS)
|
||||
else
|
||||
subdir = contrib/gms_stats
|
||||
top_builddir = ../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
regress_home = $(top_builddir)/src/test/regress
|
||||
REGRESS_OPTS = -c 0 -d 1 -r 1 -p 25632 --single_node -w --keep_last_data=false \
|
||||
--regconf=$(regress_home)/regress.conf \
|
||||
--temp-config=$(regress_home)/make_fastcheck_postgresql.conf
|
||||
include $(top_srcdir)/contrib/contrib-global.mk
|
||||
endif
|
||||
|
||||
gms_stats.o: gms_stats.cpp
|
||||
1
contrib/gms_stats/data/dummy.txt
Normal file
1
contrib/gms_stats/data/dummy.txt
Normal file
@ -0,0 +1 @@
|
||||
The openGauss regression needs this file to run.
|
||||
57
contrib/gms_stats/expected/gms_stats.out
Normal file
57
contrib/gms_stats/expected/gms_stats.out
Normal file
@ -0,0 +1,57 @@
|
||||
create extension gms_stats;
|
||||
create schema gms_stats_test;
|
||||
set search_path=gms_stats_test;
|
||||
create table normal_table(a int, b char(10));
|
||||
insert into normal_table select generate_series(1,500), 'abc';
|
||||
create table partition_table(a int) partition by range(a) (partition p1 values less than(100),partition p2 values less than(maxvalue));
|
||||
insert into partition_table select generate_series(1,600);
|
||||
create materialized view mv_tb as select * from normal_table;
|
||||
select schemaname, tablename, attname, avg_width, most_common_vals, most_common_freqs from pg_stats where schemaname='gms_stats_test' order by tablename, attname;
|
||||
schemaname | tablename | attname | avg_width | most_common_vals | most_common_freqs
|
||||
------------+-----------+---------+-----------+------------------+-------------------
|
||||
(0 rows)
|
||||
|
||||
begin
|
||||
gms_stats.gather_schema_stats('gms_stats_test');
|
||||
end;
|
||||
/
|
||||
NOTICE: PL/SQL procedure successfully completed.
|
||||
CONTEXT: SQL statement "CALL gms_stats.gather_schema_stats('gms_stats_test')"
|
||||
PL/pgSQL function inline_code_block line 3 at PERFORM
|
||||
select schemaname, tablename, attname, avg_width, most_common_vals, most_common_freqs from pg_stats where schemaname='gms_stats_test' order by tablename, attname;
|
||||
schemaname | tablename | attname | avg_width | most_common_vals | most_common_freqs
|
||||
----------------+-----------------+---------+-----------+------------------+-------------------
|
||||
gms_stats_test | mv_tb | a | 4 | |
|
||||
gms_stats_test | mv_tb | b | 11 | {"abc "} | {1}
|
||||
gms_stats_test | normal_table | a | 4 | |
|
||||
gms_stats_test | normal_table | b | 11 | {"abc "} | {1}
|
||||
gms_stats_test | partition_table | a | 4 | |
|
||||
(5 rows)
|
||||
|
||||
create table normal_table2(a int, b char(10));
|
||||
insert into normal_table2 select generate_series(1,700), 'abc';
|
||||
call gms_stats.gather_schema_stats('gms_stats_test');
|
||||
NOTICE: PL/SQL procedure successfully completed.
|
||||
gather_schema_stats
|
||||
---------------------
|
||||
|
||||
(1 row)
|
||||
|
||||
select schemaname, tablename, attname, avg_width, most_common_vals, most_common_freqs from pg_stats where schemaname='gms_stats_test' order by tablename, attname;
|
||||
schemaname | tablename | attname | avg_width | most_common_vals | most_common_freqs
|
||||
----------------+-----------------+---------+-----------+------------------+-------------------
|
||||
gms_stats_test | mv_tb | a | 4 | |
|
||||
gms_stats_test | mv_tb | b | 11 | {"abc "} | {1}
|
||||
gms_stats_test | normal_table | a | 4 | |
|
||||
gms_stats_test | normal_table | b | 11 | {"abc "} | {1}
|
||||
gms_stats_test | normal_table2 | a | 4 | |
|
||||
gms_stats_test | normal_table2 | b | 11 | {"abc "} | {1}
|
||||
gms_stats_test | partition_table | a | 4 | |
|
||||
(7 rows)
|
||||
|
||||
drop schema gms_stats_test cascade;
|
||||
NOTICE: drop cascades to 4 other objects
|
||||
DETAIL: drop cascades to table normal_table
|
||||
drop cascades to table partition_table
|
||||
drop cascades to materialized view mv_tb
|
||||
drop cascades to table normal_table2
|
||||
42
contrib/gms_stats/gms_stats--1.0.sql
Normal file
42
contrib/gms_stats/gms_stats--1.0.sql
Normal file
@ -0,0 +1,42 @@
|
||||
/* contrib/gms_stats/gms_stats--1.0.sql */
|
||||
|
||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
|
||||
\echo Use "CREATE EXTENSION gms_stats" to load this file. \quit
|
||||
|
||||
-- gms_stats package begin
|
||||
CREATE SCHEMA gms_stats;
|
||||
GRANT USAGE ON SCHEMA gms_stats TO PUBLIC;
|
||||
CREATE TYPE objecttab AS (
|
||||
ownname varchar2(30),
|
||||
objtype varchar2(6),
|
||||
objname varchar2(30),
|
||||
partname varchar2(30),
|
||||
subpartname varchar2(30));
|
||||
|
||||
CREATE FUNCTION gms_stats.gs_analyze_schema_tables(schemaname varchar2)
|
||||
RETURNS void
|
||||
AS 'MODULE_PATHNAME','gs_analyze_schema_tables'
|
||||
LANGUAGE C VOLATILE NOT FENCED;
|
||||
|
||||
CREATE OR REPLACE PROCEDURE gms_stats.gather_schema_stats(
|
||||
ownname varchar2,
|
||||
estimate_percent number default 100,
|
||||
block_sample boolean default false,
|
||||
method_opt varchar2 default 'FOR ALL COLUMNS SIZE AUTO',
|
||||
degree number default null,
|
||||
granularity varchar2 default 'GLOBAL',
|
||||
cascade boolean default false,
|
||||
stattab varchar2 default null,
|
||||
statid varchar2 default null,
|
||||
options varchar2 default 'GATHER',
|
||||
objlist ObjectTab default null,
|
||||
statown varchar2 default null,
|
||||
no_invalidate boolean default false,
|
||||
force boolean default false,
|
||||
obj_filter_list objecttab default null) IS
|
||||
BEGIN
|
||||
perform gms_stats.gs_analyze_schema_tables(ownname);
|
||||
raise notice 'PL/SQL procedure successfully completed.';
|
||||
END;
|
||||
|
||||
-- gms_stats package end
|
||||
5
contrib/gms_stats/gms_stats.control
Normal file
5
contrib/gms_stats/gms_stats.control
Normal file
@ -0,0 +1,5 @@
|
||||
# gms_stats extension
|
||||
comment = 'collection of stats data for PL/SQL applications'
|
||||
default_version = '1.0'
|
||||
module_pathname = '$libdir/gms_stats'
|
||||
relocatable = true
|
||||
113
contrib/gms_stats/gms_stats.cpp
Normal file
113
contrib/gms_stats/gms_stats.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Technologies Co.,Ltd.
|
||||
*
|
||||
* openGauss is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
*
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
* --------------------------------------------------------------------------------------
|
||||
*
|
||||
* gms_stats.cpp
|
||||
* gms_stats can effectively estimate statistical data.
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* contrib/gms_stats/gms_stats.cpp
|
||||
*
|
||||
* --------------------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
#include "funcapi.h"
|
||||
#include "fmgr.h"
|
||||
|
||||
#include "access/skey.h"
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "commands/sqladvisor.h"
|
||||
#include "commands/vacuum.h"
|
||||
#include "executor/spi.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "gms_stats.h"
|
||||
|
||||
PG_MODULE_MAGIC;
|
||||
|
||||
PG_FUNCTION_INFO_V1(gs_analyze_schema_tables);
|
||||
|
||||
static List* GetRelationsInSchema(char *namespc)
|
||||
{
|
||||
Relation pg_class_rel = NULL;
|
||||
ScanKeyData skey[1];
|
||||
SysScanDesc sysscan;
|
||||
HeapTuple tuple;
|
||||
char* relname;
|
||||
List* tbl_relnames = NIL;
|
||||
Oid nspid;
|
||||
|
||||
nspid = get_namespace_oid(namespc, true);
|
||||
if (!OidIsValid(nspid))
|
||||
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("schema \"%s\" does not exists", namespc)));
|
||||
|
||||
ScanKeyInit(&skey[0], Anum_pg_class_relnamespace, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(nspid));
|
||||
pg_class_rel = heap_open(RelationRelationId, AccessShareLock);
|
||||
sysscan = systable_beginscan(pg_class_rel, ClassNameNspIndexId, true, SnapshotNow, 1, skey);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(sysscan))) {
|
||||
Form_pg_class reltup = (Form_pg_class)GETSTRUCT(tuple);
|
||||
if (reltup->relkind == RELKIND_RELATION || reltup->relkind == RELKIND_MATVIEW) {
|
||||
relname = reltup->relname.data;
|
||||
tbl_relnames = lappend(tbl_relnames, relname);
|
||||
}
|
||||
}
|
||||
systable_endscan(sysscan);
|
||||
heap_close(pg_class_rel, AccessShareLock);
|
||||
return tbl_relnames;
|
||||
}
|
||||
|
||||
static void analyze_tables(char *namespc, List *relnames_list)
|
||||
{
|
||||
StringInfo execute_sql;
|
||||
ListCell* lc;
|
||||
VacuumStmt* stmt;
|
||||
execute_sql = makeStringInfo();
|
||||
foreach(lc, relnames_list)
|
||||
{
|
||||
char* relnames = (char*)lfirst(lc);
|
||||
appendStringInfo(execute_sql, "ANALYZE %s.%s;", quote_identifier(namespc), quote_identifier(relnames));
|
||||
|
||||
List* parsetree_list = NULL;
|
||||
ListCell* parsetree_item = NULL;
|
||||
parsetree_list = raw_parser(execute_sql->data, NULL);
|
||||
foreach (parsetree_item, parsetree_list) {
|
||||
Node* parsetree = (Node*)lfirst(parsetree_item);
|
||||
stmt = (VacuumStmt*)parsetree;
|
||||
}
|
||||
vacuum(stmt, InvalidOid, true, NULL, true);
|
||||
list_free(parsetree_list);
|
||||
resetStringInfo(execute_sql);
|
||||
}
|
||||
DestroyStringInfo(execute_sql);
|
||||
}
|
||||
|
||||
Datum
|
||||
gs_analyze_schema_tables(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *schema_name = text_to_cstring(PG_GETARG_TEXT_P(0));
|
||||
List* relnames_list;
|
||||
|
||||
relnames_list = GetRelationsInSchema(schema_name);
|
||||
analyze_tables(schema_name, relnames_list);
|
||||
|
||||
pfree_ext(schema_name);
|
||||
list_free(relnames_list);
|
||||
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
15
contrib/gms_stats/gms_stats.h
Normal file
15
contrib/gms_stats/gms_stats.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*---------------------------------------------------------------------------------------*
|
||||
* gms_stats.h
|
||||
*
|
||||
* Definition about gms_stats package.
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* contrib/gms_stats/gms_stats.h
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef GMS_STATS_H
|
||||
#define GMS_STATS_H
|
||||
|
||||
extern "C" Datum gs_analyze_schema_tables(PG_FUNCTION_ARGS);
|
||||
#endif
|
||||
26
contrib/gms_stats/sql/gms_stats.sql
Normal file
26
contrib/gms_stats/sql/gms_stats.sql
Normal file
@ -0,0 +1,26 @@
|
||||
create extension gms_stats;
|
||||
create schema gms_stats_test;
|
||||
set search_path=gms_stats_test;
|
||||
create table normal_table(a int, b char(10));
|
||||
insert into normal_table select generate_series(1,500), 'abc';
|
||||
|
||||
create table partition_table(a int) partition by range(a) (partition p1 values less than(100),partition p2 values less than(maxvalue));
|
||||
insert into partition_table select generate_series(1,600);
|
||||
|
||||
create materialized view mv_tb as select * from normal_table;
|
||||
|
||||
select schemaname, tablename, attname, avg_width, most_common_vals, most_common_freqs from pg_stats where schemaname='gms_stats_test' order by tablename, attname;
|
||||
|
||||
begin
|
||||
gms_stats.gather_schema_stats('gms_stats_test');
|
||||
end;
|
||||
/
|
||||
select schemaname, tablename, attname, avg_width, most_common_vals, most_common_freqs from pg_stats where schemaname='gms_stats_test' order by tablename, attname;
|
||||
|
||||
create table normal_table2(a int, b char(10));
|
||||
insert into normal_table2 select generate_series(1,700), 'abc';
|
||||
call gms_stats.gather_schema_stats('gms_stats_test');
|
||||
|
||||
select schemaname, tablename, attname, avg_width, most_common_vals, most_common_freqs from pg_stats where schemaname='gms_stats_test' order by tablename, attname;
|
||||
|
||||
drop schema gms_stats_test cascade;
|
||||
Reference in New Issue
Block a user