!6575 gms_utility高级包功能实现(PART)

Merge pull request !6575 from zhubin79/gms-utility
This commit is contained in:
opengauss_bot
2024-11-12 11:51:38 +00:00
committed by Gitee
24 changed files with 8504 additions and 6 deletions

View File

@ -105,6 +105,7 @@ install:
@if test -d contrib/datavec; then $(MAKE) -C contrib/datavec clean; fi
@if test -d contrib/datavec; then $(MAKE) -C contrib/datavec $@; fi
@if test -d contrib/gms_compress; then $(MAKE) -C contrib/gms_compress $@; fi
@if test -d contrib/gms_utility; then $(MAKE) -C contrib/gms_utility $@; fi
@if test -d contrib/gms_stats; then $(MAKE) -C contrib/gms_stats $@; fi
@if test -d contrib/gms_tcp; then $(MAKE) -C contrib/gms_tcp $@; fi
@if test -d contrib/gms_profiler; then $(MAKE) -C contrib/gms_profiler $@; fi

View File

@ -63,6 +63,8 @@
./share/postgresql/extension/hstore--1.0--1.1.sql
./share/postgresql/extension/log_fdw--1.0.sql
./share/postgresql/extension/log_fdw.control
./share/postgresql/extension/gms_utility--1.0.sql
./share/postgresql/extension/gms_utility.control
./share/postgresql/extension/gms_output--1.0.sql
./share/postgresql/extension/gms_output.control
./share/postgresql/extension/gms_stats--1.0.sql
@ -766,6 +768,7 @@
./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so
./lib/postgresql/pgoutput.so
./lib/postgresql/gms_utility.so
./lib/postgresql/gms_output.so
./lib/postgresql/gms_stats.so
./lib/postgresql/gms_profiler.so

View File

@ -123,6 +123,8 @@
./share/postgresql/extension/dblink.control
./share/postgresql/extension/gms_compress--1.0.sql
./share/postgresql/extension/gms_compress.control
./share/postgresql/extension/gms_utility--1.0.sql
./share/postgresql/extension/gms_utility.control
./share/postgresql/extension/gms_output--1.0.sql
./share/postgresql/extension/gms_output.control
./share/postgresql/extension/gms_inaddr--1.0.sql
@ -838,6 +840,7 @@
./lib/postgresql/java/pljava.jar
./lib/postgresql/postgres_fdw.so
./lib/postgresql/dblink.so
./lib/postgresql/gms_utility.so
./lib/postgresql/pgoutput.so
./lib/postgresql/assessment.so
./lib/postgresql/gms_compress.so

View File

@ -68,6 +68,8 @@
./share/postgresql/extension/gms_sql.control
./share/postgresql/extension/gms_i18n--1.0.sql
./share/postgresql/extension/gms_i18n.control
./share/postgresql/extension/gms_utility--1.0.sql
./share/postgresql/extension/gms_utility.control
./share/postgresql/timezone/GB-Eire
./share/postgresql/timezone/Turkey
./share/postgresql/timezone/Kwajalein
@ -762,6 +764,7 @@
./lib/postgresql/gms_lob.so
./lib/postgresql/gms_sql.so
./lib/postgresql/gms_i18n.so
./lib/postgresql/gms_utility.so
./include/postgresql/server/postgres_ext.h
./include/postgresql/server/pg_config_os.h
./include/postgresql/server/pgtime.h

View File

@ -98,6 +98,8 @@
./share/postgresql/extension/gms_sql.control
./share/postgresql/extension/gms_i18n--1.0.sql
./share/postgresql/extension/gms_i18n.control
./share/postgresql/extension/gms_utility--1.0.sql
./share/postgresql/extension/gms_utility.control
./share/postgresql/timezone/GB-Eire
./share/postgresql/timezone/Turkey
./share/postgresql/timezone/Kwajalein
@ -780,6 +782,7 @@
./lib/postgresql/gms_lob.so
./lib/postgresql/gms_sql.so
./lib/postgresql/gms_i18n.so
./lib/postgresql/gms_utility.so
./lib/libpljava.so
./lib/libpq.a
./lib/libpq.so

View File

@ -119,6 +119,8 @@
./share/postgresql/extension/gms_lob.control
./share/postgresql/extension/gms_stats--1.0.sql
./share/postgresql/extension/gms_stats.control
./share/postgresql/extension/gms_utility--1.0.sql
./share/postgresql/extension/gms_utility.control
./share/postgresql/extension/gms_profiler--1.0.sql
./share/postgresql/extension/gms_profiler.control
./share/postgresql/extension/gms_sql--1.0.sql
@ -815,6 +817,7 @@
./lib/postgresql/gms_inaddr.so
./lib/postgresql/gms_lob.so
./lib/postgresql/gms_stats.so
./lib/postgresql/gms_utility.so
./lib/postgresql/gms_profiler.so
./lib/postgresql/gms_sql.so
./lib/postgresql/gms_tcp.so

View File

@ -63,6 +63,8 @@
./share/postgresql/extension/hstore--1.0--1.1.sql
./share/postgresql/extension/log_fdw--1.0.sql
./share/postgresql/extension/log_fdw.control
./share/postgresql/extension/gms_utility--1.0.sql
./share/postgresql/extension/gms_utility.control
./share/postgresql/extension/gms_output--1.0.sql
./share/postgresql/extension/gms_output.control
./share/postgresql/extension/gms_stats--1.0.sql
@ -765,6 +767,7 @@
./lib/postgresql/latin2_and_win1250.so
./lib/postgresql/euc2004_sjis2004.so
./lib/postgresql/pgoutput.so
./lib/postgresql/gms_utility.so
./lib/postgresql/gms_output.so
./lib/postgresql/gms_stats.so
./lib/postgresql/gms_profiler.so

View File

@ -123,6 +123,8 @@
./share/postgresql/extension/dblink.control
./share/postgresql/extension/gms_compress--1.0.sql
./share/postgresql/extension/gms_compress.control
./share/postgresql/extension/gms_utility--1.0.sql
./share/postgresql/extension/gms_utility.control
./share/postgresql/extension/gms_output--1.0.sql
./share/postgresql/extension/gms_output.control
./share/postgresql/extension/gms_inaddr--1.0.sql
@ -838,6 +840,7 @@
./lib/postgresql/java/pljava.jar
./lib/postgresql/postgres_fdw.so
./lib/postgresql/dblink.so
./lib/postgresql/gms_utility.so
./lib/postgresql/gms_lob.so
./lib/postgresql/gms_stats.so
./lib/postgresql/gms_tcp.so

View File

@ -29,6 +29,7 @@ set(CMAKE_MODULE_PATH
${CMAKE_CURRENT_SOURCE_DIR}/datavec
${CMAKE_CURRENT_SOURCE_DIR}/chparser
${CMAKE_CURRENT_SOURCE_DIR}/gms_stats
${CMAKE_CURRENT_SOURCE_DIR}/gms_utility
${CMAKE_CURRENT_SOURCE_DIR}/gms_profiler
${CMAKE_CURRENT_SOURCE_DIR}/gms_lob
${CMAKE_CURRENT_SOURCE_DIR}/gms_sql
@ -60,6 +61,7 @@ add_subdirectory(pagehack)
add_subdirectory(pg_xlogdump)
add_subdirectory(file_fdw)
add_subdirectory(log_fdw)
add_subdirectory(gms_utility)
add_subdirectory(gms_stats)
add_subdirectory(gms_sql)
add_subdirectory(gms_tcp)

View File

@ -57,6 +57,7 @@ SUBDIRS = \
vacuumlo \
security_plugin \
ndpplugin \
gms_utility \
gms_profiler \
gms_inaddr \
gms_output \

View File

@ -0,0 +1,21 @@
#This is the main CMAKE for build all gms_utility.
# gms_utility
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TGT_gms_utility_SRC)
set(TGT_gms_utility_INC
${PROJECT_OPENGS_DIR}/contrib/gms_utility
${PROJECT_OPENGS_DIR}/contrib
)
set(gms_utility_DEF_OPTIONS ${MACRO_OPTIONS})
set(gms_utility_COMPILE_OPTIONS ${OPTIMIZE_OPTIONS} ${OS_OPTIONS} ${PROTECT_OPTIONS} ${WARNING_OPTIONS} ${LIB_SECURE_OPTIONS} ${CHECK_OPTIONS})
set(gms_utility_LINK_OPTIONS ${LIB_LINK_OPTIONS})
add_shared_libtarget(gms_utility TGT_gms_utility_SRC TGT_gms_utility_INC "${gms_utility_DEF_OPTIONS}" "${gms_utility_COMPILE_OPTIONS}" "${gms_utility_LINK_OPTIONS}")
set_target_properties(gms_utility PROPERTIES PREFIX "")
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gms_utility.control
DESTINATION share/postgresql/extension/
)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/gms_utility--1.0.sql
DESTINATION share/postgresql/extension/
)
install(TARGETS gms_utility DESTINATION lib/postgresql)

View File

@ -0,0 +1,32 @@
# contrib/gms_utility/Makefile
MODULE_big = gms_utility
OBJS = gms_utility.o
EXTENSION = gms_utility
DATA = gms_utility--1.0.sql
exclude_option = -fPIE
override CPPFLAGS := -fstack-protector-strong $(filter-out $(exclude_option),$(CPPFLAGS))
REGRESS = gms_utility
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/gms_utility
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
regress_home = $(top_builddir)/src/test/regress
REGRESS_OPTS = -c 0 -d 1 -r 1 -p 36789 --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_utility.o: gms_utility.cpp
check_utility:
chmod +x ./smartmatch.pl
make check

View File

@ -0,0 +1 @@
The openGauss regression needs this file to run.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,309 @@
/* contrib/gms_utility/gms_utility--1.0.sql */
-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION gms_utility" to load this file. \quit
-- gms_utility package begin
-- gms_utility schema
CREATE SCHEMA gms_utility;
GRANT USAGE ON SCHEMA gms_utility TO PUBLIC;
/*
* ----------------------------
* -- DB_VERSION
* ----------------------------
*/
CREATE OR REPLACE PROCEDURE GMS_UTILITY.DB_VERSION(
version OUT varchar2,
compatibility OUT varchar2
)
AS
BEGIN
version := 'openGauss ' || opengauss_version();
compatibility := 'openGuass ' || opengauss_version();
END;
/*
* ----------------------------
* -- ANALYZE_SCHEMA
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.ANALYZE_SCHEMA_C_FUN (
schema VARCHAR2,
method VARCHAR2,
estimate_rows NUMBER DEFAULT NULL,
estimate_percent NUMBER DEFAULT NULL,
method_opt VARCHAR2 DEFAULT NULL
) RETURNS void
AS 'MODULE_PATHNAME','gms_analyze_schema'
LANGUAGE C VOLATILE NOT FENCED;
CREATE OR REPLACE PROCEDURE GMS_UTILITY.ANALYZE_SCHEMA (
schema IN VARCHAR2,
method IN VARCHAR2,
estimate_rows IN NUMBER DEFAULT NULL,
estimate_percent IN NUMBER DEFAULT NULL,
method_opt IN VARCHAR2 DEFAULT NULL
)
AS
BEGIN
GMS_UTILITY.ANALYZE_SCHEMA_C_FUN(schema, method, estimate_rows, estimate_percent, method_opt);
END;
/*
* ----------------------------
* -- ANALYZE_DATABASE
* ----------------------------
*/
CREATE OR REPLACE PROCEDURE GMS_UTILITY.ANALYZE_DATABASE (
method IN VARCHAR2,
estimate_rows IN NUMBER DEFAULT NULL,
estimate_percent IN NUMBER DEFAULT NULL,
method_opt IN VARCHAR2 DEFAULT NULL
)
AS
schema_name text;
BEGIN
FOR schema_name IN SELECT nspname FROM pg_namespace
LOOP
GMS_UTILITY.ANALYZE_SCHEMA_C_FUN(schema_name, method, estimate_rows, estimate_percent, method_opt);
END LOOP;
END;
/*
* ----------------------------
* -- CANONICALIZE
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.CANONICALIZE_C_FUNC (
name VARCHAR2,
canon_len INTEGER
) RETURNS VARCHAR2
AS 'MODULE_PATHNAME','gms_canonicalize'
LANGUAGE C VOLATILE NOT FENCED;
CREATE OR REPLACE PROCEDURE GMS_UTILITY.CANONICALIZE (
name IN VARCHAR2,
canon_name OUT VARCHAR2,
canon_len IN INTEGER
)
AS
BEGIN
if name IS NULL then
canon_name := NULL;
else
canon_name := GMS_UTILITY.CANONICALIZE_C_FUNC(name, canon_len);
end if;
END;
/*
* ----------------------------
* -- COMPILE_SCHEMA
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.COMPILE_SCHEMA_C_FUNC (
schema VARCHAR2,
compile_all BOOLEAN DEFAULT TRUE,
reuse_settings BOOLEAN DEFAULT FALSE
) RETURNS void
AS 'MODULE_PATHNAME','gms_compile_schema'
LANGUAGE C VOLATILE NOT FENCED;
CREATE OR REPLACE PROCEDURE GMS_UTILITY.COMPILE_SCHEMA (
schema IN VARCHAR2,
compile_all IN BOOLEAN DEFAULT TRUE,
reuse_settings IN BOOLEAN DEFAULT FALSE
)
AS
BEGIN
GMS_UTILITY.COMPILE_SCHEMA_C_FUNC(schema, compile_all, reuse_settings);
END;
/*
* ----------------------------
* -- EXPAND_SQL_TEXT
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.EXPAND_SQL_TEXT_C_FUNC (
input_sql_text IN CLOB,
output_sql_text OUT CLOB
)
AS 'MODULE_PATHNAME','gms_expand_sql_text'
LANGUAGE C VOLATILE NOT FENCED;
CREATE OR REPLACE PROCEDURE GMS_UTILITY.EXPAND_SQL_TEXT (
input_sql_text IN CLOB,
output_sql_text OUT CLOB
)
AS
BEGIN
output_sql_text := GMS_UTILITY.EXPAND_SQL_TEXT_C_FUNC(input_sql_text);
END;
/*
* ----------------------------
* -- GET_CPU_TIME
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.GET_CPU_TIME
RETURNS NUMBER
AS 'MODULE_PATHNAME','gms_get_cpu_time'
LANGUAGE C VOLATILE NOT FENCED;
/*
* ----------------------------
* -- GET_ENDIANNESS
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.GET_ENDIANNESS
RETURNS integer
AS 'MODULE_PATHNAME','gms_get_endianness'
LANGUAGE C VOLATILE NOT FENCED;
/*
* ----------------------------
* -- GET_SQL_HASH
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.GET_SQL_HASH_C_FUNC (
name IN VARCHAR2,
hash OUT RAW,
pre10ihash OUT NUMBER
)
AS 'MODULE_PATHNAME','gms_get_sql_hash'
LANGUAGE C VOLATILE NOT FENCED;
CREATE OR REPLACE PROCEDURE GMS_UTILITY.GET_SQL_HASH (
name IN VARCHAR2,
hash OUT RAW,
last4byte OUT NUMBER
)
AS
TYPE RET IS RECORD(hash RAW, last4byte NUMBER);
rec RET;
BEGIN
rec := GMS_UTILITY.GET_SQL_HASH_C_FUNC(name);
hash := rec.hash;
last4byte := rec.last4byte;
END;
/*
* ----------------------------
* -- NAME_TOKENIZE
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.NAME_TOKENIZE_C_FUNC (
name IN VARCHAR2,
a OUT VARCHAR2,
b OUT VARCHAR2,
c OUT VARCHAR2,
dblink OUT VARCHAR2,
nextpos OUT BINARY_INTEGER
)
AS 'MODULE_PATHNAME','gms_name_tokenize'
LANGUAGE C VOLATILE NOT FENCED;
CREATE OR REPLACE PROCEDURE GMS_UTILITY.NAME_TOKENIZE (
name IN VARCHAR2,
a OUT VARCHAR2,
b OUT VARCHAR2,
c OUT VARCHAR2,
dblink OUT VARCHAR2,
nextpos OUT BINARY_INTEGER
)
AS
TYPE RET IS RECORD(a VARCHAR2, b VARCHAR2, c VARCHAR2, dblink VARCHAR2, nextpos INT);
rec RET;
BEGIN
rec := GMS_UTILITY.NAME_TOKENIZE_C_FUNC(name);
a := rec.a;
b := rec.b;
c := rec.c;
dblink := rec.dblink;
nextpos := rec.nextpos;
END;
/*
* ----------------------------
* -- NAME_RESOLVE
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.NAME_RESOLVE_C_FUNC (
name IN VARCHAR2,
context IN NUMBER,
schema OUT VARCHAR2,
part1 OUT VARCHAR2,
part2 OUT VARCHAR2,
dblink OUT VARCHAR2,
part1_type OUT NUMBER,
object_number OUT NUMBER
)
AS 'MODULE_PATHNAME','gms_name_resolve'
LANGUAGE C VOLATILE NOT FENCED;
CREATE OR REPLACE PROCEDURE GMS_UTILITY.NAME_RESOLVE (
name IN VARCHAR2,
context IN NUMBER,
schema OUT VARCHAR2,
part1 OUT VARCHAR2,
part2 OUT VARCHAR2,
dblink OUT VARCHAR2,
part1_type OUT NUMBER,
object_number OUT NUMBER
)
AS
TYPE RET IS RECORD(s VARCHAR2, p1 VARCHAR2, p2 VARCHAR2, dblink VARCHAR2, p1_type NUMBER, obj_num NUMBER);
rec RET;
BEGIN
rec := GMS_UTILITY.NAME_RESOLVE_C_FUNC(name, context);
schema := rec.s;
part1 := rec.p1;
part2 := rec.p2;
dblink := rec.dblink;
part1_type := rec.p1_type;
object_number := rec.obj_num;
END;
/*
* ----------------------------
* -- IS_BIT_SET
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.IS_BIT_SET (
r IN RAW,
n IN NUMBER
) RETURNS NUMBER
AS 'MODULE_PATHNAME','gms_is_bit_set'
LANGUAGE C VOLATILE NOT FENCED;
/*
* ----------------------------
* -- IS_CLUSTER_DATABASE
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.IS_CLUSTER_DATABASE ()
RETURNS BOOLEAN
AS $$ SELECT FALSE::BOOLEAN $$
LANGUAGE SQL IMMUTABLE STRICT;
/*
* ----------------------------
* -- OLD_CURRENT_SCHEMA
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.OLD_CURRENT_SCHEMA ()
RETURNS VARCHAR2
AS 'MODULE_PATHNAME','gms_old_current_schema'
LANGUAGE C VOLATILE NOT FENCED;
/*
* ----------------------------
* -- OLD_CURRENT_USER
* ----------------------------
*/
CREATE OR REPLACE FUNCTION GMS_UTILITY.OLD_CURRENT_USER ()
RETURNS VARCHAR2
AS $$ SELECT CURRENT_USER::VARCHAR2 $$
LANGUAGE SQL IMMUTABLE STRICT;

View File

@ -0,0 +1,5 @@
# gms_utility extension
comment = 'collection of gms_utility for PL/SQL applications'
default_version = '1.0'
module_pathname = '$libdir/gms_utility'
relocatable = true

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
/*---------------------------------------------------------------------------------------*
* gms_utility.h
*
* Definition about gms_utility package.
*
* IDENTIFICATION
* contrib/gms_utility/gms_utility.h
*
* ---------------------------------------------------------------------------------------
*/
#ifndef GMS_UTILITY_H
#define GMS_UTILITY_H
#include "postgres.h"
#include "funcapi.h"
#include "fmgr.h"
#include "catalog/pg_proc.h"
#include "catalog/gs_package.h"
#include "catalog/pg_object.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_synonym.h"
#include "parser/parse_relation.h"
typedef enum {
METHOD_OPT_TABLE,
METHOD_OPT_ALL_COLUMN,
METHOD_OPT_ALL_INDEX
} AnalyzeMethodOpt;
typedef struct AnalyzeVar {
bool isEstimate;
bool validRows;
int64 estimateRows;
bool validPercent;
int64 estimatePercent;
} AnalyzeVar;
typedef struct TokenizeVar {
List* list;
char* dblink;
int nextpos;
} TokenizeVar;
typedef struct NameResolveVar {
char* schema;
char* part1;
char* part2;
int part1Type;
Oid objectId;
int len;
bool synonym;
} NameResolveVar;
/*
* name resolve function input param context valid value: 0~9
*/
typedef enum {
NR_CONTEXT_TABLE,
NR_CONTEXT_PLSQL,
NR_CONTEXT_SEQUENCES,
NR_CONTEXT_TRIGGER,
NR_CONTEXT_JAVA_SOURCE,
NR_CONTEXT_JAVA_RESOURCE,
NR_CONTEXT_JAVA_CLASS,
NR_CONTEXT_TYPE,
NR_CONTEXT_JAVA_SHARED_DATA,
NR_CONTEXT_INDEX,
NR_CONTEXT_UNKNOWN
} NameResolveContext;
/*
* name resolve function output param part1_type valid value:
* 0、1、2、5、6、7、8、9、12、13
*/
#define NAME_RESOLVE_TYPE_NONE 0
#define NAME_RESOLVE_TYPE_INDEX 1
#define NAME_RESOLVE_TYPE_TABLE 2
#define NAME_RESOLVE_TYPE_SYNONYM 5
#define NAME_RESOLVE_TYPE_SEQUENCE 6
#define NAME_RESOLVE_TYPE_PROCEDURE 7
#define NAME_RESOLVE_TYPE_FUNCTION 8
#define NAME_RESOLVE_TYPE_PACKAGE 9
#define NAME_RESOLVE_TYPE_TRIGGER 12
#define NAME_RESOLVE_TYPE_TYPE 13
/*
* name parse double quote marks
*/
#define QUOTE_NONE 0x01
#define QUOTE_STARTED 0x02
#define QUOTE_ENDED 0x04
#define QUOTE_STATE(val, bits) (((val) & (bits)) == (val))
#define IS_QUOTE_STARTED(val) QUOTE_STATE(val, QUOTE_STARTED)
#define BEFORE_QUOTE_STARTED(val) QUOTE_STATE(val, QUOTE_NONE)
#define IS_QUOTE_END(val) QUOTE_STATE(val, QUOTE_ENDED)
#define NAME_TOKENIZE_MAX_ITEM_COUNT 3
extern "C" Datum gms_analyze_schema(PG_FUNCTION_ARGS);
extern "C" Datum gms_canonicalize(PG_FUNCTION_ARGS);
extern "C" Datum gms_compile_schema(PG_FUNCTION_ARGS);
extern "C" Datum gms_expand_sql_text(PG_FUNCTION_ARGS);
extern "C" Datum gms_get_cpu_time(PG_FUNCTION_ARGS);
extern "C" Datum gms_get_endianness(PG_FUNCTION_ARGS);
extern "C" Datum gms_get_sql_hash(PG_FUNCTION_ARGS);
extern "C" Datum gms_name_tokenize(PG_FUNCTION_ARGS);
extern "C" Datum gms_name_resolve(PG_FUNCTION_ARGS);
extern "C" Datum gms_is_bit_set(PG_FUNCTION_ARGS);
extern "C" Datum gms_old_current_schema(PG_FUNCTION_ARGS);
extern void RecompileSingleFunction(Oid func_oid, bool is_procedure);
extern void RecompileSinglePackage(Oid package_oid, bool is_spec);
#endif /* GMS_UTILITY_H */

View File

@ -0,0 +1,583 @@
#!/usr/bin/perl
# smartmatch:
#
# This script is extracted from Gurjeet Singh ( singh.gurjeet@gmail.com ) NEUROdiff patch.
#
# 04 Apr 2013 : First implementation
use strict;
use warnings;
sub usage
{
print "Usage: smartmatch.pl <expected-filename> <result-filename> <smartmatch-expected-filename>\n";
return;
}
# file handles for expected and results files
my $EXPECTED;
my $RESULT;
my $NEW_EXPECTED;
my $expected; # line iterator for EXPECTED file
my $result; # line iterator for RESULT file
my $re; # the Regular Expression part of a line which starts with ?
my $insideuo; # boolean, representing if we are INSIDE an UnOrdered set of lines
my $bFirstLine; # Indicates whether the line going to be printed is the first or not
my $iuo; # counter I for counting lines within an UnOrdered set
my $seenspecialinuo; # Seen special marker inside unordered group
my $smartmatch; # seen any special match syntax
my $rc = 0; # Return Code
my @earr = ( [], [] ); # 2-dimensional ARRay to keep Expected file's unmatched lines from an unordered set
my @rarr = ( [], [] ); # 2-dimensional ARRay to keep Result file's unmatched lines from unordered set
my @searr = ( [], [] ); # 2-dimensional ARRay to keep Expected file's sorted lines from an unordered set
my @srarr = ( [], [] ); # 2-dimensional ARRay to keep Result file's sorted lines from unordered set
# we require exactly 3 arguments
if( @ARGV != 3 )
{
usage();
exit(2);
}
# initialize (almost) everything
open $EXPECTED , "<", $ARGV[0] or die $!;
open $RESULT , "<", $ARGV[1] or die $!;
open $NEW_EXPECTED , ">", $ARGV[2] or die $!;
$insideuo = 0;
$iuo = 0;
$smartmatch = 0;
$bFirstLine = 1;
# process all lines from both the files
while( 1 )
{
undef $!;
my $matched = 1;
$expected = <$EXPECTED>;
undef $!;
$result = <$RESULT>;
# one file finished but not the other
if( ( !defined( $expected ) || !defined( $result ) )
&& ( defined( $expected ) || defined( $result ) ) )
{
$rc = 2;
if( defined( $expected ) )
{
if( $bFirstLine )
{
print $NEW_EXPECTED "$expected";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\n$expected";
}
}
last; # while( 1 )
}
# both files finished
if( !defined( $expected ) && !defined( $result ) )
{
last; # while( 1 )
}
# chomp away...
# Apart from getting rid of extra newlines in messages, this will also help
# us be agnostic about platform specific newline sequences.
#
# Correction: Apparently the above assumption is not true (found the hard
# way :( ).
# If the file was generated on Windows (CRLF), the Linux version of chomp
# will trim only \n and leave \r. Had to use dos2unix on the out files to
# make this script work.
chomp( $expected );
chomp( $result );
# if the line from expected file starts with a ?, treat it specially
if( $expected =~ /^--\?.*/ )
{
$smartmatch=1;
# extract the Regular Expression
$re = substr $expected, 3;
# If this is the beginning of an UnOrdered set of lines
if( $re eq 'unordered: start' )
{
if( $insideuo )
{
if( $bFirstLine )
{
print $NEW_EXPECTED "Nesting of 'unordered: start' blocks is not allowed";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\nNesting of 'unordered: start' blocks is not allowed";
}
exit( 2 );
}
# reset the variables for the UO set.
$iuo = 0;
$insideuo = 1;
$seenspecialinuo = 0;
if( $bFirstLine )
{
print $NEW_EXPECTED "$expected";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\n$expected";
}
next;
}
# end of an UnOrderd set of lines
if( $re eq 'unordered: end' )
{
if( !$insideuo )
{
print $NEW_EXPECTED "'unordered: end' line found without a matching 'unordered: start' line\n";
exit( 2 );
}
$insideuo = 0;
# If there were some lines containing RE, do comparison the hard way
if( $seenspecialinuo )
{
# begin the (m*n) processing of the two arrays. These arrays
# contain the set of unmatched lines from respective files
foreach my $eelemref ( @earr )
{
my $i = 0;
my $eelem = $eelemref->[0];
foreach my $relemref ( @rarr )
{
my $relem = $relemref->[0];
$matched = 1;
# treat these lines the same as we threat the others;
# that is, if an 'expected' line starts with a '?', we
# perform Regular Expression match, else we perform
# normal comparison.
if( $eelem =~ /^--\?.*/ )
{
my $tmpre = substr $eelem, 3;
if( $relem !~ /^$tmpre$/ )
{
$matched = 0;
}
else
{
if( $bFirstLine )
{
print $NEW_EXPECTED "$relem";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\n$relem";
}
last;
}
}
elsif( $eelem ne $relem )
{
$matched = 0;
}
else
{
if( $bFirstLine )
{
print $NEW_EXPECTED "$relem";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\n$relem";
}
last;
}
++$i;
} # foreach @rarr
if( !$matched )
{
$rc = 2;
if( $bFirstLine )
{
print $NEW_EXPECTED "$eelem";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\n$eelem";
}
}
else
{
splice @rarr, $i, 0;
}
} # foreach @earr
}
else # if there's no line containing an RE in this UO group,
# do it efficiently
{
# sort both arrays based on the text.
@searr = sort { $a->[0] cmp $b->[0] } @earr;
@srarr = sort { $a->[0] cmp $b->[0] } @rarr;
my $min_len = (scalar(@searr) <= scalar(@srarr) ? scalar(@searr) : scalar(@srarr) );
my $i;
$matched = 1;
for( $i = 0; $i < $min_len; ++$i )
{
my $eelem = $searr[$i][0];
my $relem = $srarr[$i][0];
# treat these lines the same as we threat the others; that is, if an
# 'expected' line starts with a '?', we perform Regular Expression
# match, else we perform normal comparison.
if( $eelem =~ /^--\?.*/ )
{
my $tmpre = substr $eelem, 3;
if( $relem !~ /^$tmpre$/ )
{
$matched = 0;
}
}
elsif( $eelem ne $relem )
{
$matched = 0;
}
}
if ((scalar(@searr) > $i) || (scalar(@srarr) > $i))
{
$matched = 0;
}
if ( !$matched )
{
$rc = 2;
for( my $i = 0; $i < scalar(@earr); ++$i )
{
if( $bFirstLine )
{
print $NEW_EXPECTED "$earr[$i][0]";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\n$earr[$i][0]";
}
}
}
else
{
for( my $i = 0; $i < scalar(@rarr); ++$i )
{
if( $bFirstLine )
{
print $NEW_EXPECTED "$rarr[$i][0]";
$bFirstLine = 0;
}
else
{
print $NEW_EXPECTED "\n$rarr[$i][0]";
}
}
}
$matched = 0;
} # else part of if( $seenspecialinuo )
if( $bFirstLine )
{
$bFirstLine = 0;
print $NEW_EXPECTED "$expected";
}
else
{
print $NEW_EXPECTED "\n$expected";
}
# reset the array variables to reclaim memory
@searr = @srarr = ();
@earr = @rarr = ();
next; # while( 1 )
} # if re == 'unordered: end'
# it is not an 'unordered' marker, so do regular Regular Expression match
else
{
my $re_1;
if ($result !~ /^$re/)
{
if ($re =~ /(.*)datanode.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)\(cost=.*/ )
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)\(actual time=.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)\(CPU:.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)\(RoughCheck CU:.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)Buffers:.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Actual-Total-Time>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /[.*]/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Actual-Startup-Time>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Actual-Min-Startup-Time>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Actual-Max-Startup-Time>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Actual-Min-Total-Time>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Actual-Max-Total-Time>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Exclusive-Cycles\/Row>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Exclusive-Cycles>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /(.*)<Inclusive-Cycles>.*/)
{
$re_1 = quotemeta($1);
if ($result !~ /$re_1.*/)
{
$matched = 0;
}
}
elsif ($re =~ /^\s*Sort\s+Method.*/)
{
if ($result !~ /^\s*Sort\s+Method.*/)
{
$matched = 0;
}
}
elsif ($re =~ /Total runtime:.*/)
{
if ($result !~ /^\s*Total runtime:.*/)
{
$matched = 0;
}
}
elsif ($re =~ /^\s*QUERY PLAN\s*$/)
{
if ($result !~ /^\s*QUERY PLAN\s*$/)
{
$matched = 0;
}
}
elsif ($re =~ /^\-+$/)
{
if ($result !~ /^\-+$/)
{
$matched = 0;
}
}
else
{
$matched = 0;
}
}
}
} # if $expected like ?.*
# $expected doesn't begin with the special marker, so do normal comparison
elsif( $expected ne $result )
{
$matched = 0;
}
if( !$matched || $insideuo )
{
# if the lines did not match, and if we are comparing an unordered set of lines,
# then save the lines for processing later.
if( $insideuo )
{
$earr[$iuo][0] = $expected;
$rarr[$iuo][0] = $result;
if( !$seenspecialinuo && $expected =~ /^--\?.*/ )
{
$seenspecialinuo = 1;
}
++$iuo;
}
else # print out the difference
{
$rc = 2;
if( $bFirstLine )
{
$bFirstLine = 0;
print $NEW_EXPECTED "$expected";
}
else
{
print $NEW_EXPECTED "\n$expected";
}
}
}
else
{
if( $bFirstLine )
{
$bFirstLine = 0;
print $NEW_EXPECTED "$result";
}
else
{
print $NEW_EXPECTED "\n$result";
}
}
}
close $EXPECTED;
close $RESULT;
close $NEW_EXPECTED;
exit( $rc + $smartmatch );

File diff suppressed because it is too large Load Diff

View File

@ -1069,7 +1069,7 @@ enum ValidateDependResult {
};
static ValidateDependResult ValidateDependView(Oid view_oid, char objType, List** list)
static ValidateDependResult ValidateDependView(Oid view_oid, char objType, List** list, bool force)
{
bool isValid = true;
bool existTable = false;
@ -1078,7 +1078,7 @@ static ValidateDependResult ValidateDependView(Oid view_oid, char objType, List*
List* originEvAction = NIL;
List* freshedEvAction = NIL;
// 1. filter the valid view
if (GetPgObjectValid(view_oid, objType)) {
if (!force && GetPgObjectValid(view_oid, objType)) {
return ValidateDependValid;
}
@ -1157,8 +1157,9 @@ static ValidateDependResult ValidateDependView(Oid view_oid, char objType, List*
}
} else if (relkind == RELKIND_VIEW || relkind == RELKIND_MATVIEW) {
char type = relkind == RELKIND_VIEW ? OBJECT_TYPE_VIEW : OBJECT_TYPE_MATVIEW;
ValidateDependResult result = ValidateDependView(dep_objid, type, list);
ValidateDependResult result = ValidateDependView(dep_objid, type, list, force);
if (result == ValidateDependCircularDepend) {
list_free(*list);
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg(
@ -1241,7 +1242,7 @@ static ValidateDependResult ValidateDependView(Oid view_oid, char objType, List*
bool ValidateDependView(Oid view_oid, char objType) {
List * list = NIL;
ValidateDependResult result = ValidateDependView(view_oid, objType, &list);
ValidateDependResult result = ValidateDependView(view_oid, objType, &list, false);
list_free_ext(list);
if (result == ValidateDependCircularDepend) {
ereport(ERROR,
@ -1252,6 +1253,26 @@ bool ValidateDependView(Oid view_oid, char objType) {
return result != ValidateDependInvalid;
}
bool ValidateDependViewDetectRecursion(Oid viewOid, char objType, bool force, List* records)
{
ListCell* lc;
List* list = NIL;
if (records != NIL && list_member_oid(records, viewOid)) {
return true;
}
ValidateDependResult result = ValidateDependView(viewOid, objType, &list, force);
if (result == ValidateDependCircularDepend) {
list_free(list);
ereport(ERROR, (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("infinite recursion detected in rules for relation: \"%s\"", get_rel_name(viewOid))));
}
foreach (lc, list) {
records = list_append_unique_oid(records, lfirst_oid(lc));
}
list_free(list);
return result != ValidateDependInvalid;
}
/*
* Open a table during parse analysis
*
@ -1410,7 +1431,7 @@ Relation parserOpenTable(ParseState *pstate, const RangeVar *relation, int lockm
if (RelationGetRelkind(rel) == RELKIND_VIEW &&
RelationGetRelid(rel) >= FirstNormalObjectId) {
if (ValidateDependView(RelationGetRelid(rel), OBJECT_TYPE_VIEW) == ValidateDependInvalid) {
if (!ValidateDependView(RelationGetRelid(rel), OBJECT_TYPE_VIEW)) {
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("The view %s is invalid, please make it valid before operation.",

View File

@ -97,6 +97,7 @@ static void DropExtensionInListIsSupported(List* objname)
"hdfs_fdw",
"age",
"gms_compress",
"gms_utility",
"gms_stats",
"gms_output",
"gms_inaddr",

View File

@ -236,7 +236,7 @@ static inline void clear_plsql_ctx_line_info()
u_sess->plsql_cxt.package_as_line = 0;
}
static void RecompileSinglePackage(Oid package_oid, bool is_spec)
void RecompileSinglePackage(Oid package_oid, bool is_spec)
{
Oid* save_pseudo_current_user_id = u_sess->misc_cxt.Pseudo_CurrentUserId;
_PG_init();

View File

@ -59,6 +59,7 @@ extern Oid attnumCollationId(Relation rd, int attid);
extern bool GetPartitionOidForRTE(RangeTblEntry *rte, RangeVar *relation, ParseState *pstate, Relation rel);
extern bool GetSubPartitionOidForRTE(RangeTblEntry *rte, RangeVar *relation, ParseState *pstate, Relation rel);
extern bool ValidateDependView(Oid view_oid, char obj_type);
extern bool ValidateDependViewDetectRecursion(Oid viewOid, char objType, bool force, List* records);
#ifdef PGXC
extern int specialAttNum(const char* attname);
#endif