Merge branch 'master' of https://gitee.com/opengauss/openGauss-server
This commit is contained in:
1
contrib/dblink/README
Normal file
1
contrib/dblink/README
Normal file
@ -0,0 +1 @@
|
||||
Before run check_dblink.sh, you need to make sure you have import all the environment variable
|
||||
159
contrib/dblink/check_dblink.sh
Normal file
159
contrib/dblink/check_dblink.sh
Normal file
@ -0,0 +1,159 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
function fn_print_help()
|
||||
{
|
||||
echo "Usage: $0 [OPTION]
|
||||
-?|--help show help information
|
||||
-U|--user_name cluster user
|
||||
-p|--port database server port
|
||||
"
|
||||
}
|
||||
|
||||
|
||||
function fn_prase_input_param()
|
||||
{
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
-\?|--help )
|
||||
fn_print_help
|
||||
exit 1
|
||||
;;
|
||||
-U|--user_name )
|
||||
fn_check_param user_name $2
|
||||
user_name=$2
|
||||
shift 2
|
||||
;;
|
||||
-p|--port )
|
||||
fn_check_param port $2
|
||||
host_port=$2
|
||||
shift 2
|
||||
;;
|
||||
* )
|
||||
echo "Please input right paramtenter, the following command may help you"
|
||||
echo "sh check_dblink.sh --help or sh check_dblink.sh -?"
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
function fn_check_param()
|
||||
{
|
||||
if [ "$2"X = X ]
|
||||
then
|
||||
echo "no given $1, the following command may help you"
|
||||
echo "sh check_dblink.sh --help or sh check_dblink.sh -?"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function fn_check_input()
|
||||
{
|
||||
if [ ! "$user_name" -o ! "$host_port" ]
|
||||
then
|
||||
echo "Usage: sh check_dblink.sh -U user_name -p port"
|
||||
echo "The following command may help you"
|
||||
echo "sh check_dblink.sh --help or sh check_dblink.sh -?"
|
||||
return 1
|
||||
fi
|
||||
if [ "`netstat -an | grep -w $host_port`" ]
|
||||
then
|
||||
echo "port $host_port occupied, please choose another."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
function database_install()
|
||||
{
|
||||
echo "init openGauss database"
|
||||
gs_initdb -D test_dblink/dn1 --nodename=single_node1 -w Test@123 > init.log 2>&1
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "init failed,see init.log for detail information"
|
||||
delete
|
||||
exit 1
|
||||
else
|
||||
echo "init success, begin to start"
|
||||
fi
|
||||
echo "port = $host_port" >> test_dblink/dn1/postgresql.conf
|
||||
gs_ctl start -D test_dblink/dn1 > start.log 2>&1
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "start failed,see start.log for detail information"
|
||||
delete
|
||||
exit 1
|
||||
else
|
||||
echo "openGauss start success,the port is $host_port"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function create_sql()
|
||||
{
|
||||
cp sql/dblink.tmp sql/dblink.sql
|
||||
sed -i "s/portIp/$host_port/g" sql/dblink.sql
|
||||
sed -i "s/userName/$user_name/g" sql/dblink.sql
|
||||
cp expected/dblink.tmp expected/dblink.out
|
||||
sed -i "s/portIp/$host_port/g" expected/dblink.out
|
||||
sed -i "s/userName/$user_name/g" expected/dblink.out
|
||||
}
|
||||
|
||||
|
||||
function run_check()
|
||||
{
|
||||
gsql -d postgres -p "$host_port" -c "create database regression;"
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "create database failed"
|
||||
delete
|
||||
exit 1
|
||||
fi
|
||||
|
||||
create_sql
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo "generate sql file failed"
|
||||
delete
|
||||
exit 1
|
||||
fi
|
||||
gsql -d regression -p $host_port -a < sql/dblink.sql > result/dblink.out 2>&1
|
||||
diff -u result/dblink.out expected/dblink.out > diff.log
|
||||
if [[ `cat diff.log |wc -l` -eq 0 ]]
|
||||
then
|
||||
echo -e "\033[32m OK \033[0m"
|
||||
else
|
||||
echo -e "\033[31m FAILED \033[0m"
|
||||
fi
|
||||
pid=$(ps ux | grep "test_dblink" | grep -v "grep" | tr -s ' ' | cut -d ' ' -f 2)
|
||||
kill -9 $pid
|
||||
delete
|
||||
}
|
||||
|
||||
|
||||
function delete()
|
||||
{
|
||||
rm -rf test_dblink
|
||||
rm -rf sql/dblink.sql
|
||||
rm -rf expected/dblink.out
|
||||
}
|
||||
|
||||
|
||||
function main()
|
||||
{
|
||||
fn_prase_input_param $@
|
||||
fn_check_input
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
database_install
|
||||
run_check
|
||||
}
|
||||
|
||||
|
||||
main $@
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "libpq-fe.h"
|
||||
#include "libpq/libpq-fe.h"
|
||||
#include "funcapi.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/namespace.h"
|
||||
@ -112,8 +112,8 @@ static int applyRemoteGucs(PGconn* conn);
|
||||
static void restoreLocalGucs(int nestlevel);
|
||||
|
||||
/* Global */
|
||||
static remoteConn* pconn = NULL;
|
||||
static HTAB* remoteConnHash = NULL;
|
||||
static THR_LOCAL remoteConn* pconn = NULL;
|
||||
static THR_LOCAL HTAB* remoteConnHash = NULL;
|
||||
|
||||
/*
|
||||
* Following is list that holds multiple remote connections.
|
||||
@ -2521,7 +2521,7 @@ static int applyRemoteGucs(PGconn* conn)
|
||||
static const char* const GUCsAffectingIO[] = {"DateStyle", "IntervalStyle"};
|
||||
|
||||
int nestlevel = -1;
|
||||
int i;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; i < lengthof(GUCsAffectingIO); i++) {
|
||||
const char* gucName = GUCsAffectingIO[i];
|
||||
|
||||
@ -1,16 +1,28 @@
|
||||
CREATE EXTENSION dblink;
|
||||
CREATE EXTENSION
|
||||
CREATE TABLE foo(f1 int, f2 text, f3 text[], primary key (f1,f2));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
|
||||
CREATE TABLE
|
||||
INSERT INTO foo VALUES (0,'a','{"a0","b0","c0"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (1,'b','{"a1","b1","c1"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (2,'c','{"a2","b2","c2"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (3,'d','{"a3","b3","c3"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (4,'e','{"a4","b4","c4"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (5,'f','{"a5","b5","c5"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (6,'g','{"a6","b6","c6"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (7,'h','{"a7","b7","c7"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (8,'i','{"a8","b8","c8"}');
|
||||
INSERT 0 1
|
||||
INSERT INTO foo VALUES (9,'j','{"a9","b9","c9"}');
|
||||
INSERT 0 1
|
||||
-- misc utilities
|
||||
-- list the primary key fields
|
||||
SELECT *
|
||||
@ -32,6 +44,7 @@ SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
|
||||
-- too many pk fields, should fail
|
||||
SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
|
||||
ERROR: invalid attribute number 4
|
||||
CONTEXT: referenced column: dblink_build_sql_insert
|
||||
-- build an update statement based on a local tuple,
|
||||
-- replacing the primary key values with new ones
|
||||
SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
|
||||
@ -43,6 +56,7 @@ SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
|
||||
-- too many pk fields, should fail
|
||||
SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
|
||||
ERROR: invalid attribute number 4
|
||||
CONTEXT: referenced column: dblink_build_sql_update
|
||||
-- build a delete statement based on a local tuple,
|
||||
SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
|
||||
dblink_build_sql_delete
|
||||
@ -53,11 +67,15 @@ SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
|
||||
-- too many pk fields, should fail
|
||||
SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
|
||||
ERROR: invalid attribute number 4
|
||||
CONTEXT: referenced column: dblink_build_sql_delete
|
||||
-- retest using a quoted and schema qualified table
|
||||
CREATE SCHEMA "MySchema";
|
||||
CREATE SCHEMA
|
||||
CREATE TABLE "MySchema"."Foo"(f1 int, f2 text, f3 text[], primary key (f1,f2));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "Foo_pkey" for table "Foo"
|
||||
CREATE TABLE
|
||||
INSERT INTO "MySchema"."Foo" VALUES (0,'a','{"a0","b0","c0"}');
|
||||
INSERT 0 1
|
||||
-- list the primary key fields
|
||||
SELECT *
|
||||
FROM dblink_get_pkey('"MySchema"."Foo"');
|
||||
@ -92,7 +110,7 @@ SELECT dblink_build_sql_delete('"MySchema"."Foo"','1 2',2,'{"0", "a"}');
|
||||
|
||||
-- regular old dblink
|
||||
SELECT *
|
||||
FROM dblink('dbname=contrib_regression','SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
FROM dblink('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123','SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
WHERE t.a > 7;
|
||||
a | b | c
|
||||
---+---+------------
|
||||
@ -106,7 +124,7 @@ FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
WHERE t.a > 7;
|
||||
ERROR: connection not available
|
||||
-- create a persistent connection
|
||||
SELECT dblink_connect('dbname=contrib_regression');
|
||||
SELECT dblink_connect('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -124,8 +142,9 @@ WHERE t.a > 7;
|
||||
|
||||
-- open a cursor with bad SQL and fail_on_error set to false
|
||||
SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foobar',false);
|
||||
NOTICE: relation "foobar" does not exist
|
||||
NOTICE: relation "foobar" does not exist on single_node1
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not open cursor.
|
||||
referenced column: dblink_open
|
||||
dblink_open
|
||||
-------------
|
||||
ERROR
|
||||
@ -209,6 +228,7 @@ SELECT dblink_exec('ABORT');
|
||||
SELECT dblink_close('rmt_foobar_cursor',false);
|
||||
NOTICE: cursor "rmt_foobar_cursor" does not exist
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not close cursor.
|
||||
referenced column: dblink_close
|
||||
dblink_close
|
||||
--------------
|
||||
ERROR
|
||||
@ -242,14 +262,14 @@ WHERE t.a > 7;
|
||||
ERROR: connection not available
|
||||
-- put more data into our slave table, first using arbitrary connection syntax
|
||||
-- but truncate the actual return value so we can use diff to check for success
|
||||
SELECT substr(dblink_exec('dbname=contrib_regression','INSERT INTO foo VALUES(10,''k'',''{"a10","b10","c10"}'')'),1,6);
|
||||
SELECT substr(dblink_exec('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123','INSERT INTO foo VALUES(10,''k'',''{"a10","b10","c10"}'')'),1,6);
|
||||
substr
|
||||
--------
|
||||
INSERT
|
||||
(1 row)
|
||||
|
||||
-- create a persistent connection
|
||||
SELECT dblink_connect('dbname=contrib_regression');
|
||||
SELECT dblink_connect('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -285,7 +305,7 @@ FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]);
|
||||
-- bad remote select
|
||||
SELECT *
|
||||
FROM dblink('SELECT * FROM foobar',false) AS t(a int, b text, c text[]);
|
||||
NOTICE: relation "foobar" does not exist
|
||||
NOTICE: relation "foobar" does not exist on single_node1
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute query.
|
||||
a | b | c
|
||||
---+---+---
|
||||
@ -309,8 +329,9 @@ WHERE a = 11;
|
||||
|
||||
-- botch a change to some other data
|
||||
SELECT dblink_exec('UPDATE foobar SET f3[2] = ''b99'' WHERE f1 = 11',false);
|
||||
NOTICE: relation "foobar" does not exist
|
||||
NOTICE: relation "foobar" does not exist on single_node1
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
|
||||
referenced column: dblink_exec
|
||||
dblink_exec
|
||||
-------------
|
||||
ERROR
|
||||
@ -349,7 +370,7 @@ ERROR: could not establish connection
|
||||
DETAIL: missing "=" after "myconn" in connection info string
|
||||
|
||||
-- create a named persistent connection
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -370,7 +391,7 @@ WHERE t.a > 7;
|
||||
SELECT *
|
||||
FROM dblink('myconn','SELECT * FROM foobar',false) AS t(a int, b text, c text[])
|
||||
WHERE t.a > 7;
|
||||
NOTICE: relation "foobar" does not exist
|
||||
NOTICE: relation "foobar" does not exist on single_node1
|
||||
CONTEXT: Error occurred on dblink connection named "myconn": could not execute query.
|
||||
a | b | c
|
||||
---+---+---
|
||||
@ -378,10 +399,11 @@ CONTEXT: Error occurred on dblink connection named "myconn": could not execute
|
||||
|
||||
-- create a second named persistent connection
|
||||
-- should error with "duplicate connection name"
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
ERROR: duplicate connection name
|
||||
CONTEXT: referenced column: dblink_connect
|
||||
-- create a second named persistent connection with a new name
|
||||
SELECT dblink_connect('myconn2','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn2','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -407,8 +429,9 @@ SELECT dblink_disconnect('myconn2');
|
||||
|
||||
-- open a cursor incorrectly
|
||||
SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foobar',false);
|
||||
NOTICE: relation "foobar" does not exist
|
||||
NOTICE: relation "foobar" does not exist on single_node1
|
||||
CONTEXT: Error occurred on dblink connection named "myconn": could not open cursor.
|
||||
referenced column: dblink_open
|
||||
dblink_open
|
||||
-------------
|
||||
ERROR
|
||||
@ -495,6 +518,7 @@ SELECT dblink_close('myconn','rmt_foo_cursor');
|
||||
SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
|
||||
ERROR: DECLARE CURSOR can only be used in transaction blocks
|
||||
CONTEXT: Error occurred on dblink connection named "myconn": could not execute command.
|
||||
referenced column: dblink_exec
|
||||
-- reset remote transaction state
|
||||
SELECT dblink_exec('myconn','ABORT');
|
||||
dblink_exec
|
||||
@ -576,7 +600,7 @@ ERROR: could not establish connection
|
||||
DETAIL: missing "=" after "myconn" in connection info string
|
||||
|
||||
-- create a named persistent connection
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -651,8 +675,9 @@ SELECT dblink_disconnect('myconn');
|
||||
-- should get 'connection "myconn" not available' error
|
||||
SELECT dblink_disconnect('myconn');
|
||||
ERROR: connection "myconn" not available
|
||||
CONTEXT: referenced column: dblink_disconnect
|
||||
-- test asynchronous queries
|
||||
SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest1', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -665,7 +690,7 @@ SELECT * from
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT dblink_connect('dtest2', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest2', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -678,7 +703,7 @@ SELECT * from
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT dblink_connect('dtest3', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest3', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -698,12 +723,14 @@ UNION
|
||||
UNION
|
||||
(SELECT * from dblink_get_result('dtest3') as t3(f1 int, f2 text, f3 text[]))
|
||||
ORDER by f1;
|
||||
INSERT 0 11
|
||||
-- dblink_get_connections returns an array with elements in a machine-dependent
|
||||
-- ordering, so we must resort to unnesting and sorting for a stable result
|
||||
create function unnest(anyarray) returns setof anyelement
|
||||
language sql strict immutable as $$
|
||||
select $1[i] from generate_series(array_lower($1,1), array_upper($1,1)) as i
|
||||
$$;
|
||||
CREATE FUNCTION
|
||||
SELECT * FROM unnest(dblink_get_connections()) ORDER BY 1;
|
||||
unnest
|
||||
--------
|
||||
@ -752,7 +779,7 @@ SELECT * from result;
|
||||
10 | k | {a10,b10,c10}
|
||||
(11 rows)
|
||||
|
||||
SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest1', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -783,51 +810,8 @@ SELECT dblink_disconnect('dtest1');
|
||||
OK
|
||||
(1 row)
|
||||
|
||||
-- test foreign data wrapper functionality
|
||||
CREATE USER dblink_regression_test;
|
||||
CREATE FOREIGN DATA WRAPPER postgresql;
|
||||
CREATE SERVER fdtest FOREIGN DATA WRAPPER postgresql OPTIONS (dbname 'contrib_regression');
|
||||
CREATE USER MAPPING FOR public SERVER fdtest;
|
||||
GRANT USAGE ON FOREIGN SERVER fdtest TO dblink_regression_test;
|
||||
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO dblink_regression_test;
|
||||
\set ORIGINAL_USER :USER
|
||||
\c - dblink_regression_test
|
||||
-- should fail
|
||||
SELECT dblink_connect('myconn', 'fdtest');
|
||||
ERROR: password is required
|
||||
DETAIL: Non-superusers must provide a password in the connection string.
|
||||
-- should succeed
|
||||
SELECT dblink_connect_u('myconn', 'fdtest');
|
||||
dblink_connect_u
|
||||
------------------
|
||||
OK
|
||||
(1 row)
|
||||
|
||||
SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
|
||||
a | b | c
|
||||
----+---+---------------
|
||||
0 | a | {a0,b0,c0}
|
||||
1 | b | {a1,b1,c1}
|
||||
2 | c | {a2,b2,c2}
|
||||
3 | d | {a3,b3,c3}
|
||||
4 | e | {a4,b4,c4}
|
||||
5 | f | {a5,b5,c5}
|
||||
6 | g | {a6,b6,c6}
|
||||
7 | h | {a7,b7,c7}
|
||||
8 | i | {a8,b8,c8}
|
||||
9 | j | {a9,b9,c9}
|
||||
10 | k | {a10,b10,c10}
|
||||
(11 rows)
|
||||
|
||||
\c - :ORIGINAL_USER
|
||||
REVOKE USAGE ON FOREIGN SERVER fdtest FROM dblink_regression_test;
|
||||
REVOKE EXECUTE ON FUNCTION dblink_connect_u(text, text) FROM dblink_regression_test;
|
||||
DROP USER dblink_regression_test;
|
||||
DROP USER MAPPING FOR public SERVER fdtest;
|
||||
DROP SERVER fdtest;
|
||||
DROP FOREIGN DATA WRAPPER postgresql;
|
||||
-- test asynchronous notifications
|
||||
SELECT dblink_connect('dbname=contrib_regression');
|
||||
SELECT dblink_connect('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -835,36 +819,26 @@ SELECT dblink_connect('dbname=contrib_regression');
|
||||
|
||||
--should return listen
|
||||
SELECT dblink_exec('LISTEN regression');
|
||||
dblink_exec
|
||||
-------------
|
||||
LISTEN
|
||||
(1 row)
|
||||
|
||||
ERROR: LISTEN statement is not yet supported.
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
|
||||
referenced column: dblink_exec
|
||||
--should return listen
|
||||
SELECT dblink_exec('LISTEN foobar');
|
||||
dblink_exec
|
||||
-------------
|
||||
LISTEN
|
||||
(1 row)
|
||||
|
||||
ERROR: LISTEN statement is not yet supported.
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
|
||||
referenced column: dblink_exec
|
||||
SELECT dblink_exec('NOTIFY regression');
|
||||
dblink_exec
|
||||
-------------
|
||||
NOTIFY
|
||||
(1 row)
|
||||
|
||||
ERROR: NOFITY statement is not yet supported.
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
|
||||
referenced column: dblink_exec
|
||||
SELECT dblink_exec('NOTIFY foobar');
|
||||
dblink_exec
|
||||
-------------
|
||||
NOTIFY
|
||||
(1 row)
|
||||
|
||||
ERROR: NOFITY statement is not yet supported.
|
||||
CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
|
||||
referenced column: dblink_exec
|
||||
SELECT notify_name, be_pid = (select t.be_pid from dblink('select pg_backend_pid()') as t(be_pid int)) AS is_self_notify, extra from dblink_get_notify();
|
||||
notify_name | is_self_notify | extra
|
||||
-------------+----------------+-------
|
||||
regression | t |
|
||||
foobar | t |
|
||||
(2 rows)
|
||||
(0 rows)
|
||||
|
||||
SELECT * from dblink_get_notify();
|
||||
notify_name | be_pid | extra
|
||||
@ -878,7 +852,7 @@ SELECT dblink_disconnect();
|
||||
(1 row)
|
||||
|
||||
-- test dropped columns in dblink_build_sql_insert, dblink_build_sql_update
|
||||
CREATE TEMP TABLE test_dropped
|
||||
CREATE TABLE test_dropped
|
||||
(
|
||||
col1 INT NOT NULL DEFAULT 111,
|
||||
id SERIAL PRIMARY KEY,
|
||||
@ -887,12 +861,15 @@ CREATE TEMP TABLE test_dropped
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "test_dropped_id_seq" for serial column "test_dropped.id"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "test_dropped_pkey" for table "test_dropped"
|
||||
CREATE TABLE
|
||||
INSERT INTO test_dropped VALUES(default);
|
||||
INSERT 0 1
|
||||
ALTER TABLE test_dropped
|
||||
DROP COLUMN col1,
|
||||
DROP COLUMN col2,
|
||||
ADD COLUMN col3 VARCHAR(10) NOT NULL DEFAULT 'foo',
|
||||
ADD COLUMN col4 INT NOT NULL DEFAULT 42;
|
||||
ALTER TABLE
|
||||
SELECT dblink_build_sql_insert('test_dropped', '1', 1,
|
||||
ARRAY['1'::TEXT], ARRAY['2'::TEXT]);
|
||||
dblink_build_sql_insert
|
||||
@ -916,9 +893,12 @@ SELECT dblink_build_sql_delete('test_dropped', '1', 1,
|
||||
|
||||
-- test local mimicry of remote GUC values that affect datatype I/O
|
||||
SET datestyle = ISO, MDY;
|
||||
SET
|
||||
SET intervalstyle = postgres;
|
||||
SET
|
||||
SET timezone = UTC;
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SET
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
dblink_connect
|
||||
----------------
|
||||
OK
|
||||
@ -963,10 +943,13 @@ FROM dblink_send_query('myconn',
|
||||
1
|
||||
(1 row)
|
||||
|
||||
DROP TABLE result;
|
||||
DROP TABLE
|
||||
CREATE TEMPORARY TABLE result AS
|
||||
(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
|
||||
UNION ALL
|
||||
(SELECT * from dblink_get_result('myconn') as t(t timestamptz));
|
||||
INSERT 0 1
|
||||
SELECT * FROM result;
|
||||
t
|
||||
------------------------
|
||||
@ -974,6 +957,7 @@ SELECT * FROM result;
|
||||
(1 row)
|
||||
|
||||
DROP TABLE result;
|
||||
DROP TABLE
|
||||
-- multi-row asynchronous case
|
||||
SELECT *
|
||||
FROM dblink_send_query('myconn',
|
||||
@ -991,6 +975,7 @@ UNION ALL
|
||||
(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
|
||||
UNION ALL
|
||||
(SELECT * from dblink_get_result('myconn') as t(t timestamptz));
|
||||
INSERT 0 2
|
||||
SELECT * FROM result;
|
||||
t
|
||||
------------------------
|
||||
@ -999,6 +984,7 @@ SELECT * FROM result;
|
||||
(2 rows)
|
||||
|
||||
DROP TABLE result;
|
||||
DROP TABLE
|
||||
-- Try an ambiguous interval
|
||||
SELECT dblink_exec('myconn', 'SET intervalstyle = sql_standard;');
|
||||
dblink_exec
|
||||
@ -1018,6 +1004,7 @@ FROM dblink('myconn',
|
||||
-- Try swapping to another format to ensure the GUCs are tracked
|
||||
-- properly through a change.
|
||||
CREATE TEMPORARY TABLE result (t timestamptz);
|
||||
CREATE TABLE
|
||||
SELECT dblink_exec('myconn', 'SET datestyle = ISO, MDY;');
|
||||
dblink_exec
|
||||
-------------
|
||||
@ -1029,6 +1016,7 @@ INSERT INTO result
|
||||
FROM dblink('myconn',
|
||||
'SELECT * FROM (VALUES (''03.12.2013 00:00:00+00'')) t')
|
||||
AS t(a timestamptz);
|
||||
INSERT 0 1
|
||||
SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;');
|
||||
dblink_exec
|
||||
-------------
|
||||
@ -1040,6 +1028,7 @@ INSERT INTO result
|
||||
FROM dblink('myconn',
|
||||
'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t')
|
||||
AS t(a timestamptz);
|
||||
INSERT 0 1
|
||||
SELECT * FROM result;
|
||||
t
|
||||
------------------------
|
||||
@ -1048,6 +1037,7 @@ SELECT * FROM result;
|
||||
(2 rows)
|
||||
|
||||
DROP TABLE result;
|
||||
DROP TABLE
|
||||
-- Check error throwing in dblink_fetch
|
||||
SELECT dblink_open('myconn','error_cursor',
|
||||
'SELECT * FROM (VALUES (''1''), (''not an int'')) AS t(text);');
|
||||
@ -1088,5 +1078,8 @@ SELECT dblink_disconnect('myconn');
|
||||
(1 row)
|
||||
|
||||
RESET datestyle;
|
||||
RESET
|
||||
RESET intervalstyle;
|
||||
RESET
|
||||
RESET timezone;
|
||||
RESET
|
||||
0
contrib/dblink/result/dblink.out
Normal file
0
contrib/dblink/result/dblink.out
Normal file
@ -57,7 +57,7 @@ SELECT dblink_build_sql_delete('"MySchema"."Foo"','1 2',2,'{"0", "a"}');
|
||||
|
||||
-- regular old dblink
|
||||
SELECT *
|
||||
FROM dblink('dbname=contrib_regression','SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
FROM dblink('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123','SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
WHERE t.a > 7;
|
||||
|
||||
-- should generate "connection not available" error
|
||||
@ -66,7 +66,7 @@ FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
WHERE t.a > 7;
|
||||
|
||||
-- create a persistent connection
|
||||
SELECT dblink_connect('dbname=contrib_regression');
|
||||
SELECT dblink_connect('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
|
||||
-- use the persistent connection
|
||||
SELECT *
|
||||
@ -127,10 +127,10 @@ WHERE t.a > 7;
|
||||
|
||||
-- put more data into our slave table, first using arbitrary connection syntax
|
||||
-- but truncate the actual return value so we can use diff to check for success
|
||||
SELECT substr(dblink_exec('dbname=contrib_regression','INSERT INTO foo VALUES(10,''k'',''{"a10","b10","c10"}'')'),1,6);
|
||||
SELECT substr(dblink_exec('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123','INSERT INTO foo VALUES(10,''k'',''{"a10","b10","c10"}'')'),1,6);
|
||||
|
||||
-- create a persistent connection
|
||||
SELECT dblink_connect('dbname=contrib_regression');
|
||||
SELECT dblink_connect('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
|
||||
-- put more data into our slave table, using persistent connection syntax
|
||||
-- but truncate the actual return value so we can use diff to check for success
|
||||
@ -176,7 +176,7 @@ FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
WHERE t.a > 7;
|
||||
|
||||
-- create a named persistent connection
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
|
||||
-- use the named persistent connection
|
||||
SELECT *
|
||||
@ -190,10 +190,10 @@ WHERE t.a > 7;
|
||||
|
||||
-- create a second named persistent connection
|
||||
-- should error with "duplicate connection name"
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
|
||||
-- create a second named persistent connection with a new name
|
||||
SELECT dblink_connect('myconn2','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn2','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
|
||||
-- use the second named persistent connection
|
||||
SELECT *
|
||||
@ -279,7 +279,7 @@ FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
|
||||
WHERE t.a > 7;
|
||||
|
||||
-- create a named persistent connection
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
|
||||
-- put more data into our slave table, using named persistent connection syntax
|
||||
-- but truncate the actual return value so we can use diff to check for success
|
||||
@ -313,15 +313,15 @@ SELECT dblink_disconnect('myconn');
|
||||
SELECT dblink_disconnect('myconn');
|
||||
|
||||
-- test asynchronous queries
|
||||
SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest1', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
SELECT * from
|
||||
dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
|
||||
|
||||
SELECT dblink_connect('dtest2', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest2', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
SELECT * from
|
||||
dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
|
||||
|
||||
SELECT dblink_connect('dtest3', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest3', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
SELECT * from
|
||||
dblink_send_query('dtest3', 'select * from foo where f1 > 6') as t1;
|
||||
|
||||
@ -350,7 +350,7 @@ SELECT dblink_disconnect('dtest3');
|
||||
|
||||
SELECT * from result;
|
||||
|
||||
SELECT dblink_connect('dtest1', 'dbname=contrib_regression');
|
||||
SELECT dblink_connect('dtest1', 'host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
SELECT * from
|
||||
dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
|
||||
|
||||
@ -358,33 +358,8 @@ SELECT dblink_cancel_query('dtest1');
|
||||
SELECT dblink_error_message('dtest1');
|
||||
SELECT dblink_disconnect('dtest1');
|
||||
|
||||
-- test foreign data wrapper functionality
|
||||
CREATE USER dblink_regression_test;
|
||||
|
||||
CREATE FOREIGN DATA WRAPPER postgresql;
|
||||
CREATE SERVER fdtest FOREIGN DATA WRAPPER postgresql OPTIONS (dbname 'contrib_regression');
|
||||
CREATE USER MAPPING FOR public SERVER fdtest;
|
||||
GRANT USAGE ON FOREIGN SERVER fdtest TO dblink_regression_test;
|
||||
GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO dblink_regression_test;
|
||||
|
||||
\set ORIGINAL_USER :USER
|
||||
\c - dblink_regression_test
|
||||
-- should fail
|
||||
SELECT dblink_connect('myconn', 'fdtest');
|
||||
-- should succeed
|
||||
SELECT dblink_connect_u('myconn', 'fdtest');
|
||||
SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
|
||||
|
||||
\c - :ORIGINAL_USER
|
||||
REVOKE USAGE ON FOREIGN SERVER fdtest FROM dblink_regression_test;
|
||||
REVOKE EXECUTE ON FUNCTION dblink_connect_u(text, text) FROM dblink_regression_test;
|
||||
DROP USER dblink_regression_test;
|
||||
DROP USER MAPPING FOR public SERVER fdtest;
|
||||
DROP SERVER fdtest;
|
||||
DROP FOREIGN DATA WRAPPER postgresql;
|
||||
|
||||
-- test asynchronous notifications
|
||||
SELECT dblink_connect('dbname=contrib_regression');
|
||||
SELECT dblink_connect('host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
|
||||
--should return listen
|
||||
SELECT dblink_exec('LISTEN regression');
|
||||
@ -401,7 +376,7 @@ SELECT * from dblink_get_notify();
|
||||
SELECT dblink_disconnect();
|
||||
|
||||
-- test dropped columns in dblink_build_sql_insert, dblink_build_sql_update
|
||||
CREATE TEMP TABLE test_dropped
|
||||
CREATE TABLE test_dropped
|
||||
(
|
||||
col1 INT NOT NULL DEFAULT 111,
|
||||
id SERIAL PRIMARY KEY,
|
||||
@ -430,7 +405,7 @@ SELECT dblink_build_sql_delete('test_dropped', '1', 1,
|
||||
SET datestyle = ISO, MDY;
|
||||
SET intervalstyle = postgres;
|
||||
SET timezone = UTC;
|
||||
SELECT dblink_connect('myconn','dbname=contrib_regression');
|
||||
SELECT dblink_connect('myconn','host=127.0.0.1 port=portIp dbname=regression user=userName password=Test@123');
|
||||
SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;');
|
||||
|
||||
-- single row synchronous case
|
||||
@ -452,6 +427,7 @@ SELECT *
|
||||
FROM dblink_send_query('myconn',
|
||||
'SELECT * FROM
|
||||
(VALUES (''12.03.2013 00:00:00+00'')) t');
|
||||
DROP TABLE result;
|
||||
CREATE TEMPORARY TABLE result AS
|
||||
(SELECT * from dblink_get_result('myconn') as t(t timestamptz))
|
||||
UNION ALL
|
||||
@ -240,7 +240,7 @@ bool SensitiveStrCheck(const char* target)
|
||||
|
||||
if (strstr(target_copy, "PASSWORD") != NULL || strstr(target_copy, "IDENTIFIED") != NULL ||
|
||||
strstr(target_copy, "GS_ENCRYPT_AES128") != NULL || strstr(target_copy, "GS_DECRYPT_AES128") != NULL ||
|
||||
strstr(target_copy, "GS_ENCRYPT_SM4") != NULL || strstr(target_copy, "GS_DECRYPT_SM4") != NULL) {
|
||||
strstr(target_copy, "GS_ENCRYPT_FUNCTION") != NULL || strstr(target_copy, "GS_DECRYPT_FUNCTION") != NULL) {
|
||||
free(target_copy);
|
||||
return TRUE;
|
||||
} else {
|
||||
|
||||
@ -3180,17 +3180,17 @@
|
||||
AddBuiltinFunc(_0(3465), _1("gs_decrypt_aes128"), _2(2), _3(false), _4(false), _5(gs_decrypt_aes128), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_decrypt_aes128"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"gs_decrypt_sm4", 1,
|
||||
AddBuiltinFunc(_0(6322), _1("gs_decrypt_sm4"), _2(2), _3(false), _4(false), _5(gs_decrypt_sm4), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_decrypt_sm4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("f"))
|
||||
),
|
||||
"gs_decrypt_function", 1,
|
||||
AddBuiltinFunc(_0(6322), _1("gs_decrypt_function"), _2(3), _3(false), _4(false), _5(gs_decrypt_function), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(3, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_decrypt_function"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"gs_encrypt_aes128", 1,
|
||||
AddBuiltinFunc(_0(GSENCRYPTAES128FUNCOID), _1("gs_encrypt_aes128"), _2(2), _3(false), _4(false), _5(gs_encrypt_aes128), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_encrypt_aes128"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"gs_encrypt_sm4", 1,
|
||||
AddBuiltinFunc(_0(6323), _1("gs_encrypt_sm4"), _2(2), _3(false), _4(false), _5(gs_encrypt_sm4), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_encrypt_sm4"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("f"))
|
||||
),
|
||||
"gs_encrypt_function", 1,
|
||||
AddBuiltinFunc(_0(6323), _1("gs_encrypt_function"), _2(3), _3(false), _4(false), _5(gs_encrypt_function), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(3, 25, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_encrypt_function"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
),
|
||||
AddFuncGroup(
|
||||
"gs_extend_library", 1,
|
||||
AddBuiltinFunc(_0(4210), _1("gs_extend_library"), _2(2), _3(false), _4(false), _5(gs_extend_library), _6(2275), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('v'), _19(0), _20(2, 2275, 2275), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("gs_extend_library"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33(NULL), _34('f'))
|
||||
|
||||
@ -259,10 +259,18 @@ void format_debug_print_plan(char *force_line, int index, int length)
|
||||
if (encrypt != NULL) {
|
||||
mask_position(force_line, index, length, "gs_encrypt_aes128\\");
|
||||
}
|
||||
encrypt = strstr(format_str, "gs_encrypt_function");
|
||||
if (encrypt != NULL) {
|
||||
mask_position(force_line, index, length, "gs_encrypt_function\\");
|
||||
}
|
||||
decrypt = strstr(format_str, "gs_decrypt_aes128");
|
||||
if (decrypt != NULL) {
|
||||
mask_position(force_line, index, length, "gs_decrypt_aes128\\");
|
||||
}
|
||||
decrypt = strstr(format_str, "gs_decrypt_function");
|
||||
if (decrypt != NULL) {
|
||||
mask_position(force_line, index, length, "gs_decrypt_function\\");
|
||||
}
|
||||
pfree_ext(format_str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3963,6 +3963,12 @@ static bool is_execute_cmd(const char* query_string)
|
||||
pfree_ext(format_str);
|
||||
return true;
|
||||
}
|
||||
encrypt = strstr(format_str, "gs_encrypt_function");
|
||||
decrypt = strstr(format_str, "gs_decrypt_function");
|
||||
if ((encrypt != NULL) || (decrypt != NULL)) {
|
||||
pfree_ext(format_str);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
pfree_ext(format_str);
|
||||
return false;
|
||||
@ -4034,7 +4040,7 @@ static char* mask_Password_internal(const char* query_string)
|
||||
int truncateLen = 0; /* accumulate total length for each truncate */
|
||||
|
||||
/* the functions need to mask all contents */
|
||||
const char* funCrypt[] = {"gs_encrypt_aes128", "gs_decrypt_aes128"};
|
||||
const char* funCrypt[] = {"gs_encrypt_aes128", "gs_decrypt_aes128","gs_encrypt_function", "gs_decrypt_function"};
|
||||
int funCryptNum = sizeof(funCrypt) / sizeof(funCrypt[0]);
|
||||
bool isCryptFunc = false;
|
||||
int length_crypt = 0;
|
||||
|
||||
@ -77,6 +77,9 @@ char* g_vector = NULL;
|
||||
|
||||
#define EC_ENCRYPT_PREFIX "encryptOpt"
|
||||
|
||||
#define ENCRYPT_TYPE_SM4 "sm4"
|
||||
#define ENCRYPT_TYPE_AES128 "aes128"
|
||||
|
||||
// free the malloc memory
|
||||
#define GS_FREE(ptr) \
|
||||
if (NULL != (ptr)) { \
|
||||
@ -155,7 +158,7 @@ bool gs_decrypt_aes(GS_UCHAR* ciphertext, GS_UINT32 cipherlen, GS_UCHAR* key, GS
|
||||
* Revision :Using random initial vector and one fixed salt in one thread
|
||||
* in order to avoid generating deriveKey everytime.
|
||||
*/
|
||||
Datum gs_encrypt_aes128(PG_FUNCTION_ARGS)
|
||||
bool gs_encrypt_aes128_function(FunctionCallInfo fcinfo, text** outtext)
|
||||
{
|
||||
char* key = NULL;
|
||||
GS_UINT32 keylen = 0;
|
||||
@ -166,21 +169,9 @@ Datum gs_encrypt_aes128(PG_FUNCTION_ARGS)
|
||||
GS_UINT32 retval = 0;
|
||||
char* encodetext = NULL;
|
||||
GS_UINT32 encodetextlen = 0;
|
||||
GS_UINT32 ciphertextlen_max = 0;
|
||||
text* outtext = NULL;
|
||||
GS_UINT32 ciphertextlen_max = 0;
|
||||
errno_t errorno = EOK;
|
||||
|
||||
/* check input paramaters */
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The encryption key can not be empty!")));
|
||||
}
|
||||
|
||||
plaintext = text_to_cstring(PG_GETARG_TEXT_P(0));
|
||||
plaintextlen = strlen(plaintext);
|
||||
key = text_to_cstring(PG_GETARG_TEXT_P(1));
|
||||
@ -236,13 +227,13 @@ Datum gs_encrypt_aes128(PG_FUNCTION_ARGS)
|
||||
}
|
||||
encodetextlen = strlen(encodetext);
|
||||
|
||||
outtext = cstring_to_text(encodetext);
|
||||
*outtext = cstring_to_text(encodetext);
|
||||
errorno = memset_s(encodetext, encodetextlen, '\0', encodetextlen);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
OPENSSL_free(encodetext);
|
||||
encodetext = NULL;
|
||||
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -254,7 +245,7 @@ Datum gs_encrypt_aes128(PG_FUNCTION_ARGS)
|
||||
* Revision :Save several derivekeys and salts in one thread
|
||||
* in order to avoid generating deriveKey everytime.
|
||||
*/
|
||||
Datum gs_decrypt_aes128(PG_FUNCTION_ARGS)
|
||||
bool gs_decrypt_aes128_function(FunctionCallInfo fcinfo, text** outtext)
|
||||
{
|
||||
GS_UCHAR* key = NULL;
|
||||
GS_UINT32 keylen = 0;
|
||||
@ -263,21 +254,9 @@ Datum gs_decrypt_aes128(PG_FUNCTION_ARGS)
|
||||
GS_UCHAR* ciphertext = NULL;
|
||||
GS_UINT32 retval = 0;
|
||||
GS_UCHAR* decodetext = NULL;
|
||||
GS_UINT32 decodetextlen = 0;
|
||||
text* outtext = NULL;
|
||||
GS_UINT32 decodetextlen = 0;
|
||||
errno_t errorno = EOK;
|
||||
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The decryption key can not be empty!")));
|
||||
}
|
||||
|
||||
decodetext = (GS_UCHAR*)(text_to_cstring(PG_GETARG_TEXT_P(0)));
|
||||
key = (GS_UCHAR*)(text_to_cstring(PG_GETARG_TEXT_P(1)));
|
||||
keylen = strlen((const char*)key);
|
||||
@ -345,12 +324,12 @@ Datum gs_decrypt_aes128(PG_FUNCTION_ARGS)
|
||||
OPENSSL_free(ciphertext);
|
||||
ciphertext = NULL;
|
||||
|
||||
outtext = cstring_to_text((char*)plaintext);
|
||||
*outtext = cstring_to_text((char*)plaintext);
|
||||
errorno = memset_s(plaintext, plaintextlen, '\0', plaintextlen);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
pfree_ext(plaintext);
|
||||
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2353,7 +2332,7 @@ bool isEncryptedCluster()
|
||||
return true;
|
||||
}
|
||||
|
||||
Datum gs_encrypt_sm4(PG_FUNCTION_ARGS)
|
||||
bool gs_encrypt_sm4_function(FunctionCallInfo fcinfo, text** outtext)
|
||||
{
|
||||
char* key = NULL;
|
||||
GS_UINT32 keylen = 0;
|
||||
@ -2366,37 +2345,17 @@ Datum gs_encrypt_sm4(PG_FUNCTION_ARGS)
|
||||
GS_UINT32 ciphertextlenmax = 0;
|
||||
GS_UCHAR user_key[SM4_KEY_LENGTH];
|
||||
GS_UCHAR useriv[SM4_KEY_LENGTH] = {0};
|
||||
|
||||
text* outtext = NULL;
|
||||
|
||||
errno_t errorno = EOK;
|
||||
GS_UINT32 ret = 0;
|
||||
size_t cipherLength = 0;
|
||||
|
||||
/* check input paramaters */
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The encryption key can not be empty!")));
|
||||
}
|
||||
|
||||
|
||||
plaintext = (char*)(text_to_cstring(PG_GETARG_TEXT_P(0)));
|
||||
plaintextlen = strlen((const char*)plaintext);
|
||||
|
||||
key = (text_to_cstring(PG_GETARG_TEXT_P(1)));
|
||||
keylen = strlen((const char*)key);
|
||||
|
||||
/* The input key must shorter than RANDOM_LEN(16) */
|
||||
if (keylen > SM4_KEY_LENGTH) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("The encryption key must be shorter than 16 bytes!")));
|
||||
}
|
||||
|
||||
if (!check_input_password(key)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
@ -2412,7 +2371,6 @@ Datum gs_encrypt_sm4(PG_FUNCTION_ARGS)
|
||||
securec_check_c(errorno, "\0", "\0");
|
||||
}
|
||||
|
||||
|
||||
errorno = memset_s(key, keylen, '\0', keylen);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
pfree_ext(key);
|
||||
@ -2426,7 +2384,6 @@ Datum gs_encrypt_sm4(PG_FUNCTION_ARGS)
|
||||
errorno = memset_s(ciphertext, ciphertextlenmax, '\0', ciphertextlenmax);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
|
||||
|
||||
ret = sm4_ctr_enc_partial_mode(
|
||||
plaintext, plaintextlen, ciphertext, &cipherLength, user_key, useriv);
|
||||
if (ret != 0) {
|
||||
@ -2439,7 +2396,6 @@ Datum gs_encrypt_sm4(PG_FUNCTION_ARGS)
|
||||
securec_check(errorno, "\0", "\0");
|
||||
pfree_ext(plaintext);
|
||||
|
||||
|
||||
/* encode the ciphertext for nice show and decrypt operation */
|
||||
encodestring = SEC_encodeBase64((const char*)ciphertext, cipherLength);
|
||||
errorno = memset_s(ciphertext, cipherLength, '\0', cipherLength);
|
||||
@ -2453,19 +2409,18 @@ Datum gs_encrypt_sm4(PG_FUNCTION_ARGS)
|
||||
}
|
||||
encodetextlen = strlen((const char*)encodestring);
|
||||
|
||||
outtext = cstring_to_text((const char*)encodestring);
|
||||
*outtext = cstring_to_text((const char*)encodestring);
|
||||
errorno = memset_s(encodestring, encodetextlen, '\0', encodetextlen);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
OPENSSL_free(encodestring);
|
||||
encodestring = NULL;
|
||||
|
||||
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
return true;
|
||||
}
|
||||
|
||||
Datum gs_decrypt_sm4(PG_FUNCTION_ARGS)
|
||||
bool gs_decrypt_sm4_function(FunctionCallInfo fcinfo, text** outtext)
|
||||
{
|
||||
GS_UCHAR* key = NULL;
|
||||
char* key = NULL;
|
||||
GS_UINT32 keylen = 0;
|
||||
char* ciphertext = NULL;
|
||||
GS_UINT32 ciphertextlen = 0;
|
||||
@ -2477,36 +2432,24 @@ Datum gs_decrypt_sm4(PG_FUNCTION_ARGS)
|
||||
GS_UINT32 ciphertextlenmax = 0;
|
||||
GS_UCHAR userkey[SM4_KEY_LENGTH];
|
||||
GS_UCHAR useriv[SM4_KEY_LENGTH] = {0};
|
||||
text* outtext = NULL;
|
||||
|
||||
errno_t errorno = EOK;
|
||||
size_t encodetextlen = 0;
|
||||
|
||||
/* check input paramaters */
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The decryption key can not be empty!")));
|
||||
}
|
||||
|
||||
decodetext = (GS_UCHAR*)(text_to_cstring(PG_GETARG_TEXT_P(0)));
|
||||
|
||||
decodetextlen = strlen((const char*)decodetext);
|
||||
|
||||
key = (GS_UCHAR*)(text_to_cstring(PG_GETARG_TEXT_P(1)));
|
||||
key = (char*)(text_to_cstring(PG_GETARG_TEXT_P(1)));
|
||||
keylen = strlen((const char*)key);
|
||||
|
||||
/* The input key must shorter than RANDOM_LEN(16) */
|
||||
if (keylen > SM4_KEY_LENGTH) {
|
||||
|
||||
if (!check_input_password(key)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("The decryption key must be shorter than 16 bytes!")));
|
||||
errmsg("The decryption key must be %d~%d bytes and contain at least three kinds of characters!",
|
||||
MIN_KEY_LEN, SM4_KEY_LENGTH)));
|
||||
}
|
||||
|
||||
|
||||
ciphertext = (char*)(SEC_decodeBase64((const char*)decodetext , &ciphertextlen));
|
||||
if ((ciphertext == NULL)) {
|
||||
if (ciphertext != NULL) {
|
||||
@ -2524,13 +2467,12 @@ Datum gs_decrypt_sm4(PG_FUNCTION_ARGS)
|
||||
errmsg("Decode the cipher text failed or the ciphertext is wrong!")));
|
||||
}
|
||||
|
||||
|
||||
errorno = memset_s(decodetext, decodetextlen, '\0', decodetextlen);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
pfree_ext(decodetext);
|
||||
|
||||
|
||||
errorno = memcpy_s(userkey, SM4_KEY_LENGTH, key, keylen);
|
||||
errorno = memcpy_s(userkey, SM4_KEY_LENGTH, (GS_UCHAR*)key, keylen);
|
||||
securec_check_c(errorno, "\0", "\0");
|
||||
|
||||
|
||||
@ -2548,7 +2490,6 @@ Datum gs_decrypt_sm4(PG_FUNCTION_ARGS)
|
||||
errorno = memset_s(encodetext, ciphertextlenmax, '\0', ciphertextlenmax);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
|
||||
|
||||
ret = sm4_ctr_dec_partial_mode(
|
||||
ciphertext, ciphertextlen, encodetext, &encodetextlen, userkey, useriv);
|
||||
if (ret != 0) {
|
||||
@ -2562,15 +2503,149 @@ Datum gs_decrypt_sm4(PG_FUNCTION_ARGS)
|
||||
OPENSSL_free(ciphertext);
|
||||
ciphertext = NULL;
|
||||
|
||||
|
||||
encodetextlen = strlen((const char*)encodetext);
|
||||
|
||||
outtext = cstring_to_text((char*)encodetext);
|
||||
*outtext = cstring_to_text((char*)encodetext);
|
||||
errorno = memset_s(encodetext, encodetextlen, '\0', encodetextlen);
|
||||
securec_check(errorno, "\0", "\0");
|
||||
pfree_ext(encodetext);
|
||||
encodetext = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Datum gs_encrypt_function(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GS_UCHAR* encrypttype;
|
||||
text* outtext = NULL;
|
||||
bool status = false;
|
||||
|
||||
/* check input paramaters */
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The encryption key can not be empty!")));
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(2)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The encryption type can not be empty!")));
|
||||
}
|
||||
|
||||
encrypttype = (GS_UCHAR*)(text_to_cstring(PG_GETARG_TEXT_P(2)));
|
||||
|
||||
if (strcmp((const char*)encrypttype, ENCRYPT_TYPE_SM4) == 0) {
|
||||
status = gs_encrypt_sm4_function(fcinfo, &outtext);
|
||||
} else if (strcmp((const char*)encrypttype, ENCRYPT_TYPE_AES128) == 0) {
|
||||
status = gs_encrypt_aes128_function(fcinfo, &outtext);
|
||||
} else {
|
||||
pfree_ext(encrypttype);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("Encryption type is wrong!")));
|
||||
|
||||
}
|
||||
pfree_ext(encrypttype);
|
||||
|
||||
if (!status) {
|
||||
outtext = NULL;
|
||||
}
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
Datum gs_decrypt_function(PG_FUNCTION_ARGS)
|
||||
{
|
||||
GS_UCHAR* decrypttype;
|
||||
text* outtext = NULL;
|
||||
bool status = false;
|
||||
/* check input paramaters */
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The decryption key can not be empty!")));
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(2)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The decryption type can not be empty!")));
|
||||
}
|
||||
|
||||
decrypttype = (GS_UCHAR*)(text_to_cstring(PG_GETARG_TEXT_P(2)));
|
||||
|
||||
if (strcmp((const char*)decrypttype, ENCRYPT_TYPE_SM4) == 0) {
|
||||
status = gs_decrypt_sm4_function(fcinfo, &outtext);
|
||||
} else if (strcmp((const char*)decrypttype, ENCRYPT_TYPE_AES128) == 0) {
|
||||
status = gs_decrypt_aes128_function(fcinfo, &outtext);
|
||||
} else {
|
||||
pfree_ext(decrypttype);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
|
||||
errmsg("Decryption type is wrong!")));
|
||||
|
||||
}
|
||||
pfree_ext(decrypttype);
|
||||
|
||||
if (!status) {
|
||||
outtext = NULL;
|
||||
}
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
Datum gs_encrypt_aes128(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text* outtext = NULL;
|
||||
bool status = false;
|
||||
/* check input paramaters */
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The encryption key can not be empty!")));
|
||||
}
|
||||
|
||||
status = gs_encrypt_aes128_function(fcinfo, &outtext);
|
||||
if (!status) {
|
||||
outtext = NULL;
|
||||
}
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
|
||||
}
|
||||
|
||||
Datum gs_decrypt_aes128(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text* outtext = NULL;
|
||||
bool status = false;
|
||||
/* check input paramaters */
|
||||
if (PG_ARGISNULL(0)) {
|
||||
fcinfo->isnull = true;
|
||||
outtext = NULL;
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
if (PG_ARGISNULL(1)) {
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("The decryption key can not be empty!")));
|
||||
}
|
||||
|
||||
status = gs_decrypt_aes128_function(fcinfo, &outtext);
|
||||
if (!status) {
|
||||
outtext = NULL;
|
||||
}
|
||||
PG_RETURN_TEXT_P(outtext);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1021,10 +1021,6 @@ const char *hypo_explain_get_index_name_hook(Oid indexId)
|
||||
*/
|
||||
Datum hypopg_display_index(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("not support for distributed scenarios yet.")));
|
||||
#endif
|
||||
|
||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *)fcinfo->resultinfo;
|
||||
MemoryContext per_query_ctx;
|
||||
MemoryContext oldcontext;
|
||||
@ -1065,6 +1061,7 @@ Datum hypopg_display_index(PG_FUNCTION_ARGS)
|
||||
Datum values[HYPO_INDEX_NB_COLS];
|
||||
bool nulls[HYPO_INDEX_NB_COLS];
|
||||
StringInfoData index_columns;
|
||||
char *rel_name = NULL;
|
||||
int i = 0;
|
||||
int keyno;
|
||||
|
||||
@ -1073,9 +1070,13 @@ Datum hypopg_display_index(PG_FUNCTION_ARGS)
|
||||
rc = memset_s(nulls, sizeof(nulls), 0, sizeof(nulls));
|
||||
securec_check(rc, "\0", "\0");
|
||||
|
||||
rel_name = get_rel_name(entry->relid);
|
||||
if (rel_name == NULL) {
|
||||
break;
|
||||
}
|
||||
values[i++] = CStringGetTextDatum(entry->indexname);
|
||||
values[i++] = ObjectIdGetDatum(entry->oid);
|
||||
values[i++] = CStringGetTextDatum(get_rel_name(entry->relid));
|
||||
values[i++] = CStringGetTextDatum(rel_name);
|
||||
|
||||
initStringInfo(&index_columns);
|
||||
appendStringInfo(&index_columns, "(");
|
||||
@ -1104,10 +1105,6 @@ Datum hypopg_display_index(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
Datum hypopg_create_index(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("not support for distributed scenarios yet.")));
|
||||
#endif
|
||||
|
||||
char *sql = TextDatumGetCString(PG_GETARG_TEXT_PP(0));
|
||||
List *parsetree_list;
|
||||
ListCell *parsetree_item;
|
||||
@ -1183,10 +1180,6 @@ Datum hypopg_create_index(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
Datum hypopg_drop_index(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("not support for distributed scenarios yet.")));
|
||||
#endif
|
||||
|
||||
Oid indexid = PG_GETARG_OID(0);
|
||||
|
||||
PG_RETURN_BOOL(hypo_index_remove(indexid));
|
||||
@ -1197,10 +1190,6 @@ Datum hypopg_drop_index(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
Datum hypopg_estimate_size(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("not support for distributed scenarios yet.")));
|
||||
#endif
|
||||
|
||||
BlockNumber pages;
|
||||
double tuples;
|
||||
Oid indexid = PG_GETARG_OID(0);
|
||||
@ -1228,10 +1217,6 @@ Datum hypopg_estimate_size(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
Datum hypopg_reset_index(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("not support for distributed scenarios yet.")));
|
||||
#endif
|
||||
|
||||
hypo_index_reset();
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_attribute.h"
|
||||
#include "funcapi.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/nodes.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "pg_config_manual.h"
|
||||
@ -67,7 +68,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
char *table_name;
|
||||
char *alias_name;
|
||||
List *alias_name;
|
||||
List *index;
|
||||
List *join_cond;
|
||||
List *index_print;
|
||||
@ -105,6 +106,8 @@ static void startup(DestReceiver *self, int operation, TupleDesc typeinfo);
|
||||
static void destroy(DestReceiver *self);
|
||||
static void free_global_resource();
|
||||
static void find_select_stmt(Node *);
|
||||
static void extract_stmt_from_clause(List *);
|
||||
static void extract_stmt_where_clause(Node *);
|
||||
static void parse_where_clause(Node *);
|
||||
static void field_value_trans(_out_ char *, A_Const *);
|
||||
static void parse_field_expr(List *, List *, List *);
|
||||
@ -114,12 +117,12 @@ static uint4 calculate_field_cardinality(const char *, const char *);
|
||||
static bool is_tmp_table(const char *);
|
||||
static char *find_field_name(List *);
|
||||
static char *find_table_name(List *);
|
||||
static bool check_relation_type_valid(Oid);
|
||||
static TableCell *find_or_create_tblcell(char *, char *);
|
||||
static void add_index_from_field(char *, IndexCell *);
|
||||
static char *parse_group_clause(List *, List *);
|
||||
static char *parse_order_clause(List *, List *);
|
||||
static void add_index_from_group_order(TableCell *, List *, List *, bool);
|
||||
static Oid find_table_oid(List *, const char *);
|
||||
static void generate_final_index(TableCell *, Oid);
|
||||
static void parse_from_clause(List *);
|
||||
static void add_drived_tables(RangeVar *);
|
||||
@ -134,10 +137,6 @@ static void add_index_for_drived_tables();
|
||||
|
||||
Datum gs_index_advise(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("not support for distributed scenarios yet.")));
|
||||
#endif
|
||||
|
||||
FuncCallContext *func_ctx = NULL;
|
||||
SuggestedIndex *array = NULL;
|
||||
|
||||
@ -233,6 +232,8 @@ SuggestedIndex *suggest_index(const char *query_string, _out_ int *len)
|
||||
}
|
||||
|
||||
Node *parsetree = (Node *)lfirst(list_head(parse_tree_list));
|
||||
Node* parsetree_copy = (Node*)copyObject(parsetree);
|
||||
(void)parse_analyze(parsetree_copy, query_string, NULL, 0);
|
||||
find_select_stmt(parsetree);
|
||||
|
||||
if (!g_stmt_list) {
|
||||
@ -245,9 +246,6 @@ SuggestedIndex *suggest_index(const char *query_string, _out_ int *len)
|
||||
foreach (item, g_stmt_list) {
|
||||
SelectStmt *stmt = (SelectStmt *)lfirst(item);
|
||||
parse_from_clause(stmt->fromClause);
|
||||
/* Note: the structure JoinExpr will be modified after 'parse_analyze', so 'parse_from_clause'
|
||||
should be executed first. */
|
||||
Query *query_tree = parse_analyze((Node *)stmt, query_string, NULL, 0);
|
||||
|
||||
if (g_table_list) {
|
||||
parse_where_clause(stmt->whereClause);
|
||||
@ -267,8 +265,9 @@ SuggestedIndex *suggest_index(const char *query_string, _out_ int *len)
|
||||
foreach (table_item, g_table_list) {
|
||||
TableCell *table = (TableCell *)lfirst(table_item);
|
||||
if (table->index != NIL) {
|
||||
Oid table_oid = find_table_oid(query_tree->rtable, table->table_name);
|
||||
if (table_oid == 0) {
|
||||
RangeVar* rtable = makeRangeVar(NULL, table->table_name, -1);
|
||||
Oid table_oid = RangeVarGetRelid(rtable, NoLock, true);
|
||||
if (table_oid == InvalidOid) {
|
||||
continue;
|
||||
}
|
||||
generate_final_index(table, table_oid);
|
||||
@ -277,9 +276,12 @@ SuggestedIndex *suggest_index(const char *query_string, _out_ int *len)
|
||||
g_driver_table = NULL;
|
||||
}
|
||||
}
|
||||
if (g_table_list == NIL) {
|
||||
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("can not advise for query: %s.", query_string)));
|
||||
}
|
||||
|
||||
// Format the returned result, e.g., 'table1, "(col1,col2),(col3)"'.
|
||||
int array_len = g_table_list == NIL ? 0 : g_table_list->length;
|
||||
int array_len = g_table_list->length;
|
||||
*len = array_len;
|
||||
SuggestedIndex *array = (SuggestedIndex *)palloc0(sizeof(SuggestedIndex) * array_len);
|
||||
errno_t rc = EOK;
|
||||
@ -299,6 +301,9 @@ SuggestedIndex *suggest_index(const char *query_string, _out_ int *len)
|
||||
ListCell *cur_index = NULL;
|
||||
int j = 0;
|
||||
foreach (cur_index, index_list) {
|
||||
if (strlen((char *)lfirst(cur_index)) + strlen((array + i)->column) + 3 > NAMEDATALEN) {
|
||||
continue;
|
||||
}
|
||||
if (j > 0) {
|
||||
rc = strcat_s((array + i)->column, NAMEDATALEN, ",(");
|
||||
} else {
|
||||
@ -551,79 +556,41 @@ void destroy(DestReceiver *self)
|
||||
*/
|
||||
void find_select_stmt(Node *parsetree)
|
||||
{
|
||||
switch (nodeTag(parsetree)) {
|
||||
case T_SelectStmt: {
|
||||
SelectStmt *stmt = (SelectStmt *)parsetree;
|
||||
bool has_substmt = false;
|
||||
if (parsetree == NULL || nodeTag(parsetree) != T_SelectStmt) {
|
||||
return;
|
||||
}
|
||||
SelectStmt *stmt = (SelectStmt *)parsetree;
|
||||
g_stmt_list = lappend(g_stmt_list, stmt);
|
||||
|
||||
switch (stmt->op) {
|
||||
case SETOP_UNION: {
|
||||
// analyze the set operation: union
|
||||
has_substmt = true;
|
||||
find_select_stmt((Node *)stmt->larg);
|
||||
find_select_stmt((Node *)stmt->rarg);
|
||||
break;
|
||||
switch (stmt->op) {
|
||||
case SETOP_UNION: {
|
||||
// analyze the set operation: union
|
||||
find_select_stmt((Node *)stmt->larg);
|
||||
find_select_stmt((Node *)stmt->rarg);
|
||||
break;
|
||||
}
|
||||
case SETOP_NONE: {
|
||||
// analyze the 'with' clause
|
||||
if (stmt->withClause) {
|
||||
List *cte_list = stmt->withClause->ctes;
|
||||
ListCell *item = NULL;
|
||||
|
||||
foreach (item, cte_list) {
|
||||
CommonTableExpr *cte = (CommonTableExpr *)lfirst(item);
|
||||
g_tmp_table_list = lappend(g_tmp_table_list, cte->ctename);
|
||||
find_select_stmt(cte->ctequery);
|
||||
}
|
||||
case SETOP_NONE: {
|
||||
// analyze the 'with' clause
|
||||
if (stmt->withClause) {
|
||||
List *cte_list = stmt->withClause->ctes;
|
||||
has_substmt = true;
|
||||
ListCell *item = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (item, cte_list) {
|
||||
CommonTableExpr *cte = (CommonTableExpr *)lfirst(item);
|
||||
g_tmp_table_list = lappend(g_tmp_table_list, cte->ctename);
|
||||
find_select_stmt(cte->ctequery);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// analyze the 'from' clause
|
||||
if (stmt->fromClause) {
|
||||
extract_stmt_from_clause(stmt->fromClause);
|
||||
}
|
||||
|
||||
// analyze the 'from' clause
|
||||
if (stmt->fromClause) {
|
||||
List *from_list = stmt->fromClause;
|
||||
ListCell *item = NULL;
|
||||
|
||||
foreach (item, from_list) {
|
||||
Node *from = (Node *)lfirst(item);
|
||||
if (IsA(from, RangeSubselect)) {
|
||||
has_substmt = true;
|
||||
find_select_stmt(((RangeSubselect *)from)->subquery);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// analyze the 'where' clause
|
||||
if (stmt->whereClause) {
|
||||
Node *item_where = stmt->whereClause;
|
||||
if (IsA(item_where, SubLink)) {
|
||||
has_substmt = true;
|
||||
find_select_stmt(((SubLink *)item_where)->subselect);
|
||||
}
|
||||
while (IsA(item_where, A_Expr)) {
|
||||
A_Expr *expr = (A_Expr *)item_where;
|
||||
Node *lexpr = expr->lexpr;
|
||||
Node *rexpr = expr->rexpr;
|
||||
if (IsA(lexpr, SubLink)) {
|
||||
has_substmt = true;
|
||||
find_select_stmt(((SubLink *)lexpr)->subselect);
|
||||
}
|
||||
if (IsA(rexpr, SubLink)) {
|
||||
has_substmt = true;
|
||||
find_select_stmt(((SubLink *)rexpr)->subselect);
|
||||
}
|
||||
item_where = lexpr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_substmt) {
|
||||
g_stmt_list = lappend(g_stmt_list, stmt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
// analyze the 'where' clause
|
||||
if (stmt->whereClause) {
|
||||
extract_stmt_where_clause(stmt->whereClause);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -633,20 +600,45 @@ void find_select_stmt(Node *parsetree)
|
||||
}
|
||||
}
|
||||
|
||||
Oid find_table_oid(List *list, const char *table_name)
|
||||
void extract_stmt_from_clause(List *from_list)
|
||||
{
|
||||
ListCell *item = NULL;
|
||||
|
||||
foreach (item, list) {
|
||||
RangeTblEntry *entry = (RangeTblEntry *)lfirst(item);
|
||||
if (entry != NULL && entry->relname != NULL) {
|
||||
if (strcasecmp(table_name, entry->relname) == 0) {
|
||||
return entry->relid;
|
||||
foreach (item, from_list) {
|
||||
Node *from = (Node *)lfirst(item);
|
||||
if (from && IsA(from, RangeSubselect)) {
|
||||
find_select_stmt(((RangeSubselect *)from)->subquery);
|
||||
}
|
||||
if (from && IsA(from, JoinExpr)) {
|
||||
Node *larg = ((JoinExpr *)from)->larg;
|
||||
Node *rarg = ((JoinExpr *)from)->rarg;
|
||||
if (larg && IsA(larg, RangeSubselect)) {
|
||||
find_select_stmt(((RangeSubselect *)larg)->subquery);
|
||||
}
|
||||
if (rarg && IsA(rarg, RangeSubselect)) {
|
||||
find_select_stmt(((RangeSubselect *)rarg)->subquery);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
void extract_stmt_where_clause(Node *item_where)
|
||||
{
|
||||
if (IsA(item_where, SubLink)) {
|
||||
find_select_stmt(((SubLink *)item_where)->subselect);
|
||||
}
|
||||
while (item_where && IsA(item_where, A_Expr)) {
|
||||
A_Expr *expr = (A_Expr *)item_where;
|
||||
Node *lexpr = expr->lexpr;
|
||||
Node *rexpr = expr->rexpr;
|
||||
if (lexpr && IsA(lexpr, SubLink)) {
|
||||
find_select_stmt(((SubLink *)lexpr)->subselect);
|
||||
}
|
||||
if (rexpr && IsA(rexpr, SubLink)) {
|
||||
find_select_stmt(((SubLink *)rexpr)->subselect);
|
||||
}
|
||||
item_where = lexpr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -739,6 +731,10 @@ void parse_where_clause(Node *item_where)
|
||||
Node *rexpr = expr->rexpr;
|
||||
List *field_value = NIL;
|
||||
|
||||
if (lexpr == NULL || rexpr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (expr->kind) {
|
||||
case AEXPR_OP: { // normal operator
|
||||
if (IsA(lexpr, ColumnRef) && IsA(rexpr, ColumnRef)) {
|
||||
@ -806,8 +802,13 @@ void parse_from_clause(List *from_list)
|
||||
|
||||
void add_drived_tables(RangeVar *join_node)
|
||||
{
|
||||
char *table_name = ((RangeVar *)join_node)->relname;
|
||||
TableCell *join_table = find_or_create_tblcell(table_name, NULL);
|
||||
TableCell *join_table = NULL;
|
||||
|
||||
if (join_node->alias) {
|
||||
join_table = find_or_create_tblcell(join_node->relname, join_node->alias->aliasname);
|
||||
} else {
|
||||
join_table = find_or_create_tblcell(join_node->relname, NULL);
|
||||
}
|
||||
|
||||
if (!join_table) {
|
||||
return;
|
||||
@ -928,7 +929,7 @@ void parse_join_expr(JoinExpr *join_tree)
|
||||
// convert field value to string
|
||||
void field_value_trans(_out_ char *target, A_Const *field_value)
|
||||
{
|
||||
Value value = ((A_Const *)field_value)->val;
|
||||
Value value = field_value->val;
|
||||
|
||||
if (value.type == T_Integer) {
|
||||
pg_itoa(value.val.ival, target);
|
||||
@ -963,6 +964,9 @@ void parse_field_expr(List *field, List *op, List *lfield_values)
|
||||
// get field values
|
||||
foreach (item, lfield_values) {
|
||||
char *str = (char *)palloc0(MAX_QUERY_LEN);
|
||||
if (!IsA(lfirst(item), A_Const)) {
|
||||
continue;
|
||||
}
|
||||
field_value_trans(str, (A_Const *)lfirst(item));
|
||||
if (i == 0) {
|
||||
rc = strcpy_s(field_value, MAX_QUERY_LEN, str);
|
||||
@ -976,6 +980,12 @@ void parse_field_expr(List *field, List *op, List *lfield_values)
|
||||
pfree(str);
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
pfree(field_value);
|
||||
pfree(field_expr);
|
||||
return;
|
||||
}
|
||||
|
||||
// get field expression, e.g., 'id = 100'
|
||||
if (strcasecmp(op_type, "~~") == 0) {
|
||||
// ...like...
|
||||
@ -1076,21 +1086,22 @@ char *find_table_name(List *fields)
|
||||
|
||||
char *table = NULL;
|
||||
ListCell *item = NULL;
|
||||
ListCell *sub_item = NULL;
|
||||
|
||||
// if fields have table name
|
||||
if (fields->length > 1) {
|
||||
table = strVal(linitial(fields));
|
||||
// check temporary tables and existed tables
|
||||
if (is_tmp_table(table)) {
|
||||
free_global_resource();
|
||||
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("can not advise for temporary table: %s.", table)));
|
||||
} else {
|
||||
foreach (item, g_table_list) {
|
||||
TableCell *cur_table = (TableCell *)lfirst(item);
|
||||
if (strcasecmp(table, cur_table->table_name) == 0 ||
|
||||
(cur_table->alias_name && strcasecmp(table, cur_table->alias_name) == 0)) {
|
||||
// check existed tables
|
||||
foreach (item, g_table_list) {
|
||||
TableCell *cur_table = (TableCell *)lfirst(item);
|
||||
if (strcasecmp(table, cur_table->table_name) == 0) {
|
||||
return cur_table->table_name;
|
||||
}
|
||||
foreach (sub_item, cur_table->alias_name) {
|
||||
char *cur_alias_name = (char *)lfirst(sub_item);
|
||||
if (strcasecmp(table, cur_alias_name) == 0) {
|
||||
return cur_table->table_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
@ -1127,7 +1138,33 @@ char *find_table_name(List *fields)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Check whether the table is temporary.
|
||||
// Check whether the table type is supported.
|
||||
bool check_relation_type_valid(Oid relid)
|
||||
{
|
||||
Relation relation;
|
||||
bool result = false;
|
||||
|
||||
relation = heap_open(relid, AccessShareLock);
|
||||
if (RelationIsValid(relation) == false) {
|
||||
heap_close(relation, AccessShareLock);
|
||||
return result;
|
||||
}
|
||||
if (RelationIsRelation(relation) &&
|
||||
RelationGetPartType(relation) == PARTTYPE_NON_PARTITIONED_RELATION &&
|
||||
RelationGetRelPersistence(relation) == RELPERSISTENCE_PERMANENT) {
|
||||
const char *format = ((relation->rd_options) && (((StdRdOptions *)(relation->rd_options))->orientation)) ?
|
||||
((char *)(relation->rd_options) + *(int *)&(((StdRdOptions *)(relation->rd_options))->orientation)) :
|
||||
ORIENTATION_ROW;
|
||||
if (pg_strcasecmp(format, ORIENTATION_ROW) == 0) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
heap_close(relation, AccessShareLock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool is_tmp_table(const char *table_name)
|
||||
{
|
||||
ListCell *item = NULL;
|
||||
@ -1138,6 +1175,7 @@ bool is_tmp_table(const char *table_name)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1152,30 +1190,54 @@ TableCell *find_or_create_tblcell(char *table_name, char *alias_name)
|
||||
return NULL;
|
||||
}
|
||||
if (is_tmp_table(table_name)) {
|
||||
free_global_resource();
|
||||
ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("can not advise for temporary table: %s.", table_name)));
|
||||
ereport(WARNING, (errmsg("can not advise for: %s.", table_name)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// seach the table among existed tables
|
||||
ListCell *item = NULL;
|
||||
ListCell *sub_item = NULL;
|
||||
|
||||
if (g_table_list != NIL) {
|
||||
foreach (item, g_table_list) {
|
||||
TableCell *cur_table = (TableCell *)lfirst(item);
|
||||
char *cur_table_name = cur_table->table_name;
|
||||
char *cur_alias_name = cur_table->alias_name;
|
||||
if (strcasecmp(cur_table_name, table_name) == 0 ||
|
||||
(cur_alias_name && strcasecmp(cur_alias_name, table_name) == 0)) {
|
||||
if (strcasecmp(cur_table_name, table_name) == 0) {
|
||||
if (alias_name) {
|
||||
foreach (sub_item, cur_table->alias_name) {
|
||||
char *cur_alias_name = (char *)lfirst(sub_item);
|
||||
if (strcasecmp(cur_alias_name, alias_name) == 0) {
|
||||
return cur_table;
|
||||
}
|
||||
}
|
||||
cur_table->alias_name = lappend(cur_table->alias_name, alias_name);
|
||||
}
|
||||
return cur_table;
|
||||
}
|
||||
foreach (sub_item, cur_table->alias_name) {
|
||||
char *cur_alias_name = (char *)lfirst(sub_item);
|
||||
if (strcasecmp(cur_alias_name, table_name) == 0) {
|
||||
return cur_table;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RangeVar* rtable = makeRangeVar(NULL, table_name, -1);
|
||||
Oid table_oid = RangeVarGetRelid(rtable, NoLock, true);
|
||||
if (check_relation_type_valid(table_oid) == false) {
|
||||
ereport(WARNING, (errmsg("can not advise for: %s.", table_name)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// create a new table
|
||||
TableCell *new_table = NULL;
|
||||
new_table = (TableCell *)palloc0(sizeof(*new_table));
|
||||
new_table->table_name = table_name;
|
||||
new_table->alias_name = alias_name;
|
||||
new_table->alias_name = NIL;
|
||||
if (alias_name) {
|
||||
new_table->alias_name = lappend(new_table->alias_name, alias_name);
|
||||
}
|
||||
new_table->index = NIL;
|
||||
new_table->join_cond = NIL;
|
||||
new_table->index_print = NIL;
|
||||
|
||||
@ -11,5 +11,6 @@ benefit of it for the workload.
|
||||
|
||||
## Usage
|
||||
|
||||
python index_advisor_workload.py [p PORT] [d DATABASE] [f FILE] [--h HOST] [-U USERNAME] [-W PASSWORD]
|
||||
[--max_index_num MAX_INDEX_NUM] [--multi_iter_mode]
|
||||
python index_advisor_workload.py [p PORT] [d DATABASE] [f FILE] [--h HOST] [-U USERNAME] [-W PASSWORD][--schema SCHEMA]
|
||||
[--max_index_num MAX_INDEX_NUM][--max_index_storage MAX_INDEX_STORAGE] [--multi_iter_mode] [--multi_node]
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_start_backup(IN backupid TEXT, IN fast BOOL, IN exclusive BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_stop_backup(IN exclusive BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_decrypt_sm4(IN decryptstr text, IN keystr text, OUT decrypt_reult_str text) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_encrypt_sm4(IN encryptstr text, IN keystr text, OUT encrypt_result_str text) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_decrypt_function(IN decryptstr text, IN keystr text, IN type text,OUT decrypt_result_str text) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_encrypt_function(IN encryptstr text, IN keystr text, IN type text,OUT encrypt_result_str text) CASCADE;
|
||||
@ -1,4 +1,4 @@
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_start_backup(IN BACKUPID TEXT, IN FAST BOOL, IN EXCLUSIVE BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.pg_stop_backup(IN EXCLUSIVE BOOL) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_decrypt_sm4(IN decryptstr text, IN keystr text, OUT decrypt_reult_str text) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_encrypt_sm4(IN encryptstr text, IN keystr text, OUT encrypt_result_str text) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_decrypt_function(IN decryptstr text, IN keystr text, IN type text,OUT decrypt_result_str text) CASCADE;
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_encrypt_function(IN encryptstr text, IN keystr text, IN type text,OUT encrypt_result_str text) CASCADE;
|
||||
@ -2378,3 +2378,14 @@ out labelfile pg_catalog.text,
|
||||
out spcmapfile pg_catalog.text)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_stop_backup_v2';
|
||||
|
||||
-- ----------------------------------------------------------------
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_decrypt_function(IN decryptstr text, IN keystr text, IN type text,OUT decrypt_result_str text) CASCADE;
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6322;
|
||||
CREATE FUNCTION pg_catalog.gs_decrypt_function(IN decryptstr text, IN keystr text, IN type text, OUT decrypt_result_str text) RETURNS text LANGUAGE INTERNAL as 'gs_decrypt_function';
|
||||
|
||||
|
||||
|
||||
-- ----------------------------------------------------------------
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_encrypt_function(IN encryptstr text, IN keystr text, IN type text,OUT decrypt_result_str text) CASCADE;
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6323;
|
||||
CREATE FUNCTION pg_catalog.gs_encrypt_function(IN encryptstr text, IN keystr text, IN type text, OUT encrypt_result_str text) RETURNS text LANGUAGE INTERNAL as 'gs_encrypt_function';
|
||||
@ -2411,3 +2411,13 @@ out lsn pg_catalog.text,
|
||||
out labelfile pg_catalog.text,
|
||||
out spcmapfile pg_catalog.text)
|
||||
RETURNS SETOF record LANGUAGE INTERNAL VOLATILE STRICT as 'pg_stop_backup_v2';
|
||||
-- ----------------------------------------------------------------
|
||||
-- ----------------------------------------------------------------
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_decrypt_function(IN decryptstr text, IN keystr text, IN type text,OUT decrypt_result_str text) CASCADE;
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6322;
|
||||
CREATE FUNCTION pg_catalog.gs_decrypt_function(IN decryptstr text, IN keystr text, IN type text, OUT decrypt_result_str text) RETURNS text LANGUAGE INTERNAL as 'gs_decrypt_function';
|
||||
|
||||
-- ----------------------------------------------------------------
|
||||
DROP FUNCTION IF EXISTS pg_catalog.gs_encrypt_function(IN encryptstr text, IN keystr text, IN type text,OUT decrypt_result_str text) CASCADE;
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 6323;
|
||||
CREATE FUNCTION pg_catalog.gs_encrypt_function(IN encryptstr text, IN keystr text, IN type text, OUT encrypt_result_str text) RETURNS text LANGUAGE INTERNAL as 'gs_encrypt_function';
|
||||
@ -1450,8 +1450,8 @@ extern Datum substrb_without_lenth(PG_FUNCTION_ARGS);
|
||||
/*aes encrypt/decrypt function*/
|
||||
extern Datum gs_encrypt_aes128(PG_FUNCTION_ARGS);
|
||||
extern Datum gs_decrypt_aes128(PG_FUNCTION_ARGS);
|
||||
extern Datum gs_encrypt_sm4(PG_FUNCTION_ARGS);
|
||||
extern Datum gs_decrypt_sm4(PG_FUNCTION_ARGS);
|
||||
extern Datum gs_encrypt_function(PG_FUNCTION_ARGS);
|
||||
extern Datum gs_decrypt_tunction(PG_FUNCTION_ARGS);
|
||||
|
||||
extern ScalarVector* vtimestamp_part(PG_FUNCTION_ARGS);
|
||||
extern ScalarVector* vint4mul(PG_FUNCTION_ARGS);
|
||||
|
||||
120
src/test/regress/expected/hw_cipher_aes128.out
Normal file
120
src/test/regress/expected/hw_cipher_aes128.out
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -2777,8 +2777,8 @@ WHERE d.classoid IS NULL AND p1.oid <= 9999 order by 1;
|
||||
6204 | pg_stop_backup
|
||||
6224 | gs_get_next_xid_csn
|
||||
6321 | pg_stat_file_recursive
|
||||
6322 | gs_decrypt_sm4
|
||||
6323 | gs_encrypt_sm4
|
||||
6322 | gs_decrypt_function
|
||||
6323 | gs_encrypt_function
|
||||
7777 | sysdate
|
||||
7998 | set_working_grand_version_num_manually
|
||||
8050 | datalength
|
||||
|
||||
@ -742,6 +742,7 @@ test: hw_partition_hash_dql
|
||||
test: hw_partition_list_dml
|
||||
test: hw_partition_list_dql
|
||||
test: hw_cipher_sm4
|
||||
test: hw_cipher_aes128
|
||||
test: rule_test
|
||||
|
||||
#delete limit
|
||||
|
||||
48
src/test/regress/sql/hw_cipher_aes128.sql
Normal file
48
src/test/regress/sql/hw_cipher_aes128.sql
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user