Files
openGauss-server/contrib/gms_stats/gms_stats.cpp

119 lines
3.7 KiB
C++

/*
* 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 = NULL;
List* tbl_relnames = NIL;
int len;
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) {
len = strlen(reltup->relname.data);
relname = (char *) palloc(len + 1);
errno_t rc = strcpy_s(relname, len + 1, reltup->relname.data);
securec_check(rc, "\0", "\0");
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);
pfree_ext(relnames);
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();
}