This is an automated email from the ASF dual-hosted git repository. yjhjstz pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 45496ef56ca7d12ada45f89a75d7102eaf1027f1 Author: Zhenghua Lyu <[email protected]> AuthorDate: Mon Aug 22 09:48:12 2022 +0800 Escape database name for dbconn. This is really a bug of the Python Package PyGreSQL, see issue: https://github.com/PyGreSQL/PyGreSQL/issues/77 As a workaround, let's modify GPDB's code to manually escape before passing args to pgdb. --- gpMgmt/bin/gppylib/db/dbconn.py | 11 ++++++++++- src/test/regress/input/gpcopy.source | 2 ++ src/test/regress/output/gpcopy.source | 1 + src/test/regress/test_dbconn.py | 30 ++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/gpMgmt/bin/gppylib/db/dbconn.py b/gpMgmt/bin/gppylib/db/dbconn.py index 7d3f839f68..f6633827b7 100644 --- a/gpMgmt/bin/gppylib/db/dbconn.py +++ b/gpMgmt/bin/gppylib/db/dbconn.py @@ -210,7 +210,16 @@ def connect(dburl, utility=False, verbose=False, 'password': dburl.pgpass, 'host': dburl.pghost, 'port': dburl.pgport, - 'database': dburl.pgdb, + # dbname is very subtle, Package pgdb contains a bug it will only escape the string when + # 1. a space in the dbname, and + # 2. there are other keyword arguments of pgdb.connect method + # See issue https://github.com/PyGreSQL/PyGreSQL/issues/77 for details + # The code here is test if there is space, if so, we know pgdb will escape, let's not do here + # if not, let's do escape here since pgdb forget to do. + # + # NB: we always provide port keyword argument to connect method of pgdb, thus + # we will always enter the code path of pgdb.connect of the above escape logic. + 'database': dburl.pgdb if ' ' in dburl.pgdb else dburl.pgdb.replace('\\', '\\\\').replace("'", "\\'"), } # building options diff --git a/src/test/regress/input/gpcopy.source b/src/test/regress/input/gpcopy.source index d8b2f5e078..12f0baa34c 100644 --- a/src/test/regress/input/gpcopy.source +++ b/src/test/regress/input/gpcopy.source @@ -1324,6 +1324,8 @@ DROP DATABASE IF EXISTS "funny copy""db'with\\quotes"; reset client_min_messages; CREATE DATABASE "funny copy""db'with\\quotes"; +\! python3 test_dbconn.py 1 + \c "funny copy""db'with\\quotes" -- echo will behave differently on different platforms, force to use bash with -E option COPY (SELECT 'data1') TO PROGRAM 'cat > /tmp/gpcopyenvtest; /usr/bin/env bash -c ''echo -E database in COPY TO: $GP_DATABASE >> /tmp/gpcopyenvtest '' ' ESCAPE 'OFF'; diff --git a/src/test/regress/output/gpcopy.source b/src/test/regress/output/gpcopy.source index 3de1b63621..b1ef7e5af6 100755 --- a/src/test/regress/output/gpcopy.source +++ b/src/test/regress/output/gpcopy.source @@ -1643,6 +1643,7 @@ set client_min_messages='warning'; DROP DATABASE IF EXISTS "funny copy""db'with\\quotes"; reset client_min_messages; CREATE DATABASE "funny copy""db'with\\quotes"; +\! python3 test_dbconn.py 1 \c "funny copy""db'with\\quotes" -- echo will behave differently on different platforms, force to use bash with -E option COPY (SELECT 'data1') TO PROGRAM 'cat > /tmp/gpcopyenvtest; /usr/bin/env bash -c ''echo -E database in COPY TO: $GP_DATABASE >> /tmp/gpcopyenvtest '' ' ESCAPE 'OFF'; diff --git a/src/test/regress/test_dbconn.py b/src/test/regress/test_dbconn.py new file mode 100644 index 0000000000..d9c9700dae --- /dev/null +++ b/src/test/regress/test_dbconn.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +#-*- coding: utf-8 -*- + +# This is just to test we can use dbconn to connect a database +# whose name contains special chars. This test needs to have +# a cluster running so seems not easy under unittest. Previously, +# I try to create a UDF to test it udner regress test, however, +# import dbconn, its dependency package will import sys and access +# argv, which is not allowed in plpython. So finally, I create +# the python script in this directory, and use \! to run it and +# test in regress/dispatch and regress/gpcopy. + +import sys +from gppylib.db import dbconn + +dbnames = ['funny\"db\'with\\\\quotes', # from regress/dispatch + 'funny copy\"db\'with\\\\quotes'# from regress/gpcopy +] + +def test_connect_special_dbname(dbname): + url = dbconn.DbURL(dbname=dbname) + conn = dbconn.connect(url) + count = dbconn.querySingleton(conn, "select 1") + result = (count == 1) + conn.close() + + +if __name__ == "__main__": + dbname = dbnames[int(sys.argv[1])] + test_connect_special_dbname(dbname) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
