You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by od...@apache.org on 2016/05/05 23:07:19 UTC
[1/9] incubator-hawq git commit: HAWQ-712. Add GUC
gp_vmem_idle_resource_timeout back to do timeout for gang release in idle
session
Repository: incubator-hawq
Updated Branches:
refs/heads/HAWQ-703 a042001ff -> 6917914a1
HAWQ-712. Add GUC gp_vmem_idle_resource_timeout back to do timeout for gang release in idle session
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/1363d3ef
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/1363d3ef
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/1363d3ef
Branch: refs/heads/HAWQ-703
Commit: 1363d3ef2cbd18d6e50366dd536b57da029862ed
Parents: b357dbc
Author: Ruilong Huo <rh...@pivotal.io>
Authored: Mon May 2 20:34:19 2016 -0700
Committer: Ruilong Huo <rh...@pivotal.io>
Committed: Mon May 2 20:34:19 2016 -0700
----------------------------------------------------------------------
src/backend/utils/misc/guc.c | 14 ++++++++++++++
src/backend/utils/misc/postgresql.conf.sample | 1 +
2 files changed, 15 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1363d3ef/src/backend/utils/misc/guc.c
----------------------------------------------------------------------
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8e047a2..4c9fdb1 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -5046,6 +5046,20 @@ static struct config_int ConfigureNamesInt[] =
},
{
+ {"gp_vmem_idle_resource_timeout", PGC_USERSET, CLIENT_CONN_OTHER,
+ gettext_noop("Sets the time a session can be idle (in milliseconds) before we release gangs on the segment DBs to free resources."),
+ gettext_noop("A value of 0 turns off the timeout."),
+ GUC_UNIT_MS | GUC_GPDB_ADDOPT
+ },
+ &IdleSessionGangTimeout,
+#ifdef USE_ASSERT_CHECKING
+ 600000, 0, INT_MAX, NULL, NULL /* 10 minutes by default on debug builds.*/
+#else
+ 18000, 0, INT_MAX, NULL, NULL
+#endif
+ },
+
+ {
{"vacuum_freeze_min_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
gettext_noop("Minimum age at which VACUUM should freeze a table row."),
NULL
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/1363d3ef/src/backend/utils/misc/postgresql.conf.sample
----------------------------------------------------------------------
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index c88addd..0d4ca06 100755
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -482,6 +482,7 @@ gp_segment_connect_timeout = 600s
# - Resource limits -
hawq_re_memory_overcommit_max = 8192 # Maximum quota of memory overcommit (in MB) per HAWQ physical segment in resource enforcement
+#gp_vmem_idle_resource_timeout = 18000 # idle-time before gang-release, in milliseconds (zero disables release).
#------------------------------------------------------------------------------
# CUSTOMIZED OPTIONS
[8/9] incubator-hawq git commit: HAWQ-672. Add python module pygresql
back into hawq workspace
Posted by od...@apache.org.
HAWQ-672. Add python module pygresql back into hawq workspace
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/192cff1f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/192cff1f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/192cff1f
Branch: refs/heads/HAWQ-703
Commit: 192cff1fc4714118b27504bdf84ab04c2e715dbe
Parents: 1363d3e
Author: Paul Guo <pa...@gmail.com>
Authored: Thu Apr 14 11:02:54 2016 +0800
Committer: rlei <rl...@pivotal.io>
Committed: Wed May 4 10:24:31 2016 +0800
----------------------------------------------------------------------
tools/bin/.gitignore | 1 -
tools/bin/Makefile | 26 +-
tools/bin/ext/Makefile | 27 +
tools/bin/ext/__init__.py | 0
tools/bin/ext/pygresql/__init__.py | 0
tools/bin/generate-greenplum-path.sh | 7 -
tools/bin/gpcheck | 4 +-
tools/bin/gpload.py | 2 +-
tools/bin/gppylib/commands/base.py | 2 +-
tools/bin/gppylib/commands/gp.py | 2 +-
tools/bin/gppylib/db/dbconn.py | 2 +-
tools/bin/gppylib/operations/gpMigratorUtil.py | 2 +-
.../bin/gppylib/operations/test_utils_helper.py | 2 +-
.../test/regress/test_regress_pygresql.py | 4 +-
tools/bin/hawq_ctl | 2 +-
tools/bin/hawqconfig | 2 +-
tools/bin/hawqextract | 4 +-
tools/bin/hawqfilespace | 2 +-
tools/bin/hawqstate | 2 +-
tools/bin/lib/gpcheckcat | 4 +-
tools/bin/pythonSrc/.gitignore | 1 +
.../pythonSrc/PyGreSQL-4.0/docs/announce.html | 28 +
.../pythonSrc/PyGreSQL-4.0/docs/announce.txt | 23 +
.../pythonSrc/PyGreSQL-4.0/docs/changelog.html | 333 ++
.../pythonSrc/PyGreSQL-4.0/docs/changelog.txt | 285 ++
.../bin/pythonSrc/PyGreSQL-4.0/docs/default.css | 279 ++
tools/bin/pythonSrc/PyGreSQL-4.0/docs/docs.css | 109 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/future.html | 62 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/future.txt | 48 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/index.html | 182 +
.../pythonSrc/PyGreSQL-4.0/docs/install.html | 198 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/install.txt | 188 +
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.html | 2429 +++++++++++
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.txt | 1382 +++++++
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.html | 51 +
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.txt | 42 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/readme.html | 243 ++
.../bin/pythonSrc/PyGreSQL-4.0/docs/readme.txt | 206 +
tools/bin/pythonSrc/PyGreSQL-4.0/pg.py | 711 ++++
tools/bin/pythonSrc/PyGreSQL-4.0/pgdb.py | 582 +++
tools/bin/pythonSrc/PyGreSQL-4.0/pgmodule.c | 3756 ++++++++++++++++++
tools/bin/pythonSrc/PyGreSQL-4.0/setup.py | 152 +
.../pythonSrc/PyGreSQL-4.0/tutorial/advanced.py | 198 +
.../pythonSrc/PyGreSQL-4.0/tutorial/basics.py | 296 ++
.../bin/pythonSrc/PyGreSQL-4.0/tutorial/func.py | 205 +
.../pythonSrc/PyGreSQL-4.0/tutorial/syscat.py | 149 +
46 files changed, 12198 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/.gitignore
----------------------------------------------------------------------
diff --git a/tools/bin/.gitignore b/tools/bin/.gitignore
deleted file mode 100644
index bdcc60e..0000000
--- a/tools/bin/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-ext
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/Makefile
----------------------------------------------------------------------
diff --git a/tools/bin/Makefile b/tools/bin/Makefile
index 37d119c..273b599 100644
--- a/tools/bin/Makefile
+++ b/tools/bin/Makefile
@@ -36,7 +36,7 @@ PYLIB_SRC=$(SRC)/pythonSrc
LIB_DIR=$(SRC)/lib
PYLIB_DIR=$(SRC)/ext
-all: stream
+all: stream pygresql
#
# Python Libraries
@@ -52,6 +52,18 @@ stream:
cd $(STREAM_DIR) && NO_M64=TRUE $(CC) $(CFLAGS) stream.c -o stream
cp $(STREAM_DIR)/stream lib/stream
+#
+# PyGreSQL
+#
+PYGRESQL_VERSION=4.0
+PYGRESQL_DIR=PyGreSQL-$(PYGRESQL_VERSION)
+
+pygresql:
+ @echo "--- PyGreSQL"
+ cd $(PYLIB_SRC)/$(PYGRESQL_DIR) && CC="$(CC)" CFLAGS="${CFLAGS}" LDFLAGS="-L$(top_builddir)/src/interfaces/libpq ${LDFLAGS}" python setup.py build
+ mkdir -p $(PYLIB_DIR)/pygresql
+ cp -r $(PYLIB_SRC)/$(PYGRESQL_DIR)/build/lib.*/* $(PYLIB_DIR)/pygresql
+ touch $(PYLIB_DIR)/__init__.py
PYTHON_FILES=`grep -l --exclude=Makefile --exclude=gplogfilter --exclude=gpcheckos --exclude=gpgenfsmap.py --exclude=throttlingD.py "/bin/env python" *`\
`grep -l "/bin/env python" $(SRC)/../sbin/*`\
@@ -98,16 +110,7 @@ docs: epydoc
@PYTHONPATH=$(PYTHONPATH):$(EPYDOC_PYTHONPATH) $(PYLIB_SRC)/$(EPYDOC_DIR)/build/scripts-2.6/epydoc --config=.epydoc.config
clean :
- rm -rf $(PYLIB_SRC)/$(LOCKFILE_DIR)
- rm -rf $(PYLIB_SRC)/$(PARAMIKO_DIR)
- rm -rf $(PYLIB_SRC)/$(PYCRYPTO_DIR)
- rm -rf $(PYLIB_SRC)/$(PYLINT_DIR)
- rm -rf $(PYLIB_SRC)/$(LOGILAB_COMMON_DIR)
- rm -rf $(PYLIB_SRC)/$(LOGILAB_ASTNG_DIR)
- rm -rf $(PYLIB_SRC)/$(PYGRESQL_DIR)/build
- rm -rf $(PYLIB_SRC)/$(PSI_DIR)
- rm -rf $(PYLIB_SRC)/$(PYCHECKER_DIR)
- rm -rf $(PYLIB_SRC)/$(UNITTEST2_DIR)
+ [ "x$(PYGRESQL_DIR)" != "x" ] && rm -rf $(PYLIB_SRC)/$(PYGRESQL_DIR)/build; true
rm -rf $(STREAM_DIR)/stream lib/stream
rm -rf *.pyc lib/*.pyc
@@ -119,6 +122,7 @@ install: all
for files in `find * -maxdepth 0 -type f | grep -x -v -E "${SKIP_INSTALL}"`; do ${INSTALL_SCRIPT} $${files} ${bindir}; done
${MAKE} -C gppylib $@
${MAKE} -C hawqpylib $@
+ ${MAKE} -C ext $@
${INSTALL_SCRIPT} -d ${bindir}/lib
for files in `find lib -type f`; do ${INSTALL_SCRIPT} $${files} ${bindir}/lib; done
unset LIBPATH; ./generate-greenplum-path.sh $(prefix) > ${prefix}/greenplum_path.sh
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/ext/Makefile
----------------------------------------------------------------------
diff --git a/tools/bin/ext/Makefile b/tools/bin/ext/Makefile
new file mode 100644
index 0000000..ba49f09
--- /dev/null
+++ b/tools/bin/ext/Makefile
@@ -0,0 +1,27 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for the managerment utilities
+#
+#-------------------------------------------------------------------------
+
+subdir = tools/bin/ext
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+SKIP_INSTALL=.gitignore|.p4ignore|.rcfile|Makefile|test/
+
+install:
+ ${INSTALL_SCRIPT} -d ${libdir}/python/
+ @for file in `find * -type f | grep -v -E "${SKIP_INSTALL}"`; \
+ do \
+ echo "install $${file} into ${libdir}/python/$${file}" ; \
+ ${INSTALL_SCRIPT} $${file} ${libdir}/python/$${file}; \
+ done
+ @for dirs in `find * -type d | grep -v test` ;\
+ do \
+ ${INSTALL_SCRIPT} -d ${libdir}/python/$${dirs}; \
+ for file in `find $${dirs} -type f | grep -v -E "${SKIP_INSTALL}"`; do \
+ echo "install $${file} into ${libdir}/python/$${file}" ; \
+ ${INSTALL_SCRIPT} $${file} ${libdir}/python/$${file}; \
+ done \
+ done
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/ext/__init__.py
----------------------------------------------------------------------
diff --git a/tools/bin/ext/__init__.py b/tools/bin/ext/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/ext/pygresql/__init__.py
----------------------------------------------------------------------
diff --git a/tools/bin/ext/pygresql/__init__.py b/tools/bin/ext/pygresql/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/generate-greenplum-path.sh
----------------------------------------------------------------------
diff --git a/tools/bin/generate-greenplum-path.sh b/tools/bin/generate-greenplum-path.sh
index 11ffe5b..7931356 100755
--- a/tools/bin/generate-greenplum-path.sh
+++ b/tools/bin/generate-greenplum-path.sh
@@ -90,16 +90,9 @@ EOF
fi
#setup PYTHONPATH
-# OSX does NOT need pygresql/ path
-if [ "${PLAT}" = "Darwin" ] ; then
cat <<EOF
PYTHONPATH=\$GPHOME/lib/python:\$PYTHONPATH
EOF
-else
-cat <<EOF
-PYTHONPATH=\$GPHOME/lib/python:\$GPHOME/lib/python/pygresql:\$PYTHONPATH
-EOF
-fi
# openssl configuration file path
cat <<EOF
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gpcheck
----------------------------------------------------------------------
diff --git a/tools/bin/gpcheck b/tools/bin/gpcheck
index 6099867..1aefeb4 100755
--- a/tools/bin/gpcheck
+++ b/tools/bin/gpcheck
@@ -27,8 +27,8 @@ try:
from gppylib.commands.base import WorkerPool, Command, REMOTE
from gppylib.gpcheckutil import HostType, hosttype_str
from hawqpylib.hawqlib import remote_ssh_output
- from pgdb import DatabaseError
- import pg
+ from pygresql.pgdb import DatabaseError
+ from pygresql import pg
import stat
except ImportError, e:
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gpload.py
----------------------------------------------------------------------
diff --git a/tools/bin/gpload.py b/tools/bin/gpload.py
index 3d6f87f..1c268e5 100755
--- a/tools/bin/gpload.py
+++ b/tools/bin/gpload.py
@@ -49,7 +49,7 @@ except ImportError:
sys.exit(2)
try:
- import pg
+ from pygresql import pg
except Exception, e:
errorMsg = "gpload was unable to import The PyGreSQL Python module (pg.py) - %s\n" % str(e)
sys.stderr.write(str(errorMsg))
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gppylib/commands/base.py
----------------------------------------------------------------------
diff --git a/tools/bin/gppylib/commands/base.py b/tools/bin/gppylib/commands/base.py
index 65d7495..266b9cd 100755
--- a/tools/bin/gppylib/commands/base.py
+++ b/tools/bin/gppylib/commands/base.py
@@ -42,7 +42,7 @@ import time
from gppylib import gplog
from gppylib import gpsubprocess
-#from pg import DB
+from pygresql.pg import DB
# paramiko prints deprecation warnings which are ugly to the end-user
import warnings
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gppylib/commands/gp.py
----------------------------------------------------------------------
diff --git a/tools/bin/gppylib/commands/gp.py b/tools/bin/gppylib/commands/gp.py
index 66124cf..4923d18 100644
--- a/tools/bin/gppylib/commands/gp.py
+++ b/tools/bin/gppylib/commands/gp.py
@@ -27,7 +27,7 @@ from gppylib.db import catalog
from gppylib import gparray
from base import *
from unix import *
-import pg
+from pygresql import pg
from gppylib import pgconf
from gppylib.utils import writeLinesToFile, createFromSingleHostFile
from hawqpylib.hawqlib import HawqXMLParser
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gppylib/db/dbconn.py
----------------------------------------------------------------------
diff --git a/tools/bin/gppylib/db/dbconn.py b/tools/bin/gppylib/db/dbconn.py
index 0d2209a..6a474ce 100644
--- a/tools/bin/gppylib/db/dbconn.py
+++ b/tools/bin/gppylib/db/dbconn.py
@@ -24,7 +24,7 @@ import os
import stat
try:
- import pgdb
+ from pygresql import pgdb
from gppylib.commands.unix import UserId
except ImportError, e:
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gppylib/operations/gpMigratorUtil.py
----------------------------------------------------------------------
diff --git a/tools/bin/gppylib/operations/gpMigratorUtil.py b/tools/bin/gppylib/operations/gpMigratorUtil.py
index 73c5637..a6c8c36 100644
--- a/tools/bin/gppylib/operations/gpMigratorUtil.py
+++ b/tools/bin/gppylib/operations/gpMigratorUtil.py
@@ -27,7 +27,7 @@ from threading import Thread
from Queue import Queue
import urllib # for passing strings across gpssh
import shutil # for copying
-import pg # Database interaction
+from pygresql import pg # Database interaction
from gppylib.gplog import * # Greenplum logging facility
from gppylib.commands import base # Greenplum layer for worker pools
from gppylib.commands import unix # Greenplum layer for unix interaction
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gppylib/operations/test_utils_helper.py
----------------------------------------------------------------------
diff --git a/tools/bin/gppylib/operations/test_utils_helper.py b/tools/bin/gppylib/operations/test_utils_helper.py
index 3cefe97..51be194 100755
--- a/tools/bin/gppylib/operations/test_utils_helper.py
+++ b/tools/bin/gppylib/operations/test_utils_helper.py
@@ -58,5 +58,5 @@ class ExceptionWithArgsUnsafe(Exception):
class RaiseOperation_Unpicklable(Operation):
def execute(self):
- import pg
+ from pygresql import pg
raise pg.DatabaseError()
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/gppylib/test/regress/test_regress_pygresql.py
----------------------------------------------------------------------
diff --git a/tools/bin/gppylib/test/regress/test_regress_pygresql.py b/tools/bin/gppylib/test/regress/test_regress_pygresql.py
index 5b5a8b0..e086265 100755
--- a/tools/bin/gppylib/test/regress/test_regress_pygresql.py
+++ b/tools/bin/gppylib/test/regress/test_regress_pygresql.py
@@ -22,8 +22,8 @@ import logging
import unittest2 as unittest
-import pg
-import pgdb
+from pygresql import pg
+from pygresql import pgdb
from gppylib import gplog
from gppylib.db.dbconn import *
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/hawq_ctl
----------------------------------------------------------------------
diff --git a/tools/bin/hawq_ctl b/tools/bin/hawq_ctl
index d592d25..76ca6b8 100755
--- a/tools/bin/hawq_ctl
+++ b/tools/bin/hawq_ctl
@@ -38,7 +38,7 @@ try:
from hawqpylib.hawqlib import *
from hawqpylib.HAWQ_HELP import *
from gppylib.db import dbconn
- from pg import DatabaseError
+ from pygresql.pg import DatabaseError
except ImportError, e:
sys.exit('ERROR: Cannot import modules. Please check that you '
'have sourced greenplum_path.sh. Detail: ' + str(e))
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/hawqconfig
----------------------------------------------------------------------
diff --git a/tools/bin/hawqconfig b/tools/bin/hawqconfig
index 791176a..04e1e15 100755
--- a/tools/bin/hawqconfig
+++ b/tools/bin/hawqconfig
@@ -21,7 +21,7 @@ try:
from hawqpylib.hawqlib import HawqXMLParser, parse_hosts_file, remove_property_xml, update_xml_property, local_ssh
from gppylib.commands.unix import getLocalHostname, getUserName
from gppylib.db import dbconn
- from pg import DatabaseError
+ from pygresql.pg import DatabaseError
from gppylib.gplog import setup_hawq_tool_logging, quiet_stdout_logging, enable_verbose_logging
except ImportError, e:
sys.exit('ERROR: Cannot import modules. Please check that you '
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/hawqextract
----------------------------------------------------------------------
diff --git a/tools/bin/hawqextract b/tools/bin/hawqextract
index 4789539..8dc471c 100755
--- a/tools/bin/hawqextract
+++ b/tools/bin/hawqextract
@@ -93,8 +93,8 @@ try:
from gppylib.db import dbconn
from gppylib.gplog import get_default_logger, setup_tool_logging
from gppylib.gpparseopts import OptParser, OptChecker
- import pg
- from pgdb import DatabaseError
+ from pygresql import pg
+ from pygresql.pgdb import DatabaseError
import yaml
except ImportError, e:
print e
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/hawqfilespace
----------------------------------------------------------------------
diff --git a/tools/bin/hawqfilespace b/tools/bin/hawqfilespace
index ed57002..dd85aff 100755
--- a/tools/bin/hawqfilespace
+++ b/tools/bin/hawqfilespace
@@ -67,7 +67,7 @@ try:
from gppylib.commands import unix
from gppylib.db import dbconn
from gppylib.db import catalog
- import pg # Database interaction
+ from pygresql import pg # Database interaction
from gppylib.gplog import * # Greenplum logging facility
from getpass import getpass
from gppylib.parseutils import line_reader, parse_fspacename, parse_dfs_url, parse_fspacesys, parse_fspacereplica, parse_gpfilespace_line, \
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/hawqstate
----------------------------------------------------------------------
diff --git a/tools/bin/hawqstate b/tools/bin/hawqstate
index 5ff4105..16ec58c 100755
--- a/tools/bin/hawqstate
+++ b/tools/bin/hawqstate
@@ -21,7 +21,7 @@ import sys
from optparse import Option, OptionParser
from hawqpylib.hawqlib import HawqXMLParser, parse_hosts_file, check_file_exist_list
from gppylib.db import dbconn
-from pg import DatabaseError
+from pygresql.pg import DatabaseError
from gppylib.gplog import get_default_logger, setup_hawq_tool_logging, quiet_stdout_logging, enable_verbose_logging
from gppylib.commands.unix import getLocalHostname, getUserName
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/lib/gpcheckcat
----------------------------------------------------------------------
diff --git a/tools/bin/lib/gpcheckcat b/tools/bin/lib/gpcheckcat
index 186f9c5..a7c2f16 100755
--- a/tools/bin/lib/gpcheckcat
+++ b/tools/bin/lib/gpcheckcat
@@ -46,8 +46,8 @@ try:
from gppylib.gplog import *
from gppylib.gpcatalog import *
from gppylib.commands.unix import *
- from pgdb import DatabaseError
- import pg
+ from pygresql.pgdb import DatabaseError
+ from pygresql import pg
except ImportError, e:
sys.exit('Error: unable to import module: ' + str(e))
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/.gitignore
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/.gitignore b/tools/bin/pythonSrc/.gitignore
new file mode 100644
index 0000000..0aedb4a
--- /dev/null
+++ b/tools/bin/pythonSrc/.gitignore
@@ -0,0 +1 @@
+PyGreSQL-4.0
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.html
new file mode 100644
index 0000000..2683a15
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.html
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>PyGreSQL Announcements</title>
+<link rel="stylesheet" href="docs.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="pygresql-announcements">
+<h1 class="title">PyGreSQL Announcements</h1>
+<h2 class="subtitle" id="release-of-pygresql-version-4-0">Release of PyGreSQL version 4.0</h2>
+<p>PyGreSQL v4.0 has been released.</p>
+<p>It is available at: <a class="reference" href="ftp://ftp.PyGreSQL.org/pub/distrib/PyGreSQL-4.0.tgz">ftp://ftp.PyGreSQL.org/pub/distrib/PyGreSQL-4.0.tgz</a>.</p>
+<p>If you are running NetBSD, look in the packages directory under databases.
+There is also a package in the FreeBSD ports collection.</p>
+<p>Please refer to <a class="reference" href="changelog.html">changelog.txt</a>
+for things that have changed in this version.</p>
+<p>Please refer to <a class="reference" href="readme.html">readme.txt</a>
+for general information.</p>
+<div class="line-block">
+<div class="line">D'Arcy J.M. Cain</div>
+<div class="line"><a class="reference" href="mailto:darcy@PyGreSQL.org">darcy@PyGreSQL.org</a></div>
+</div>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.txt
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.txt b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.txt
new file mode 100644
index 0000000..fa08458
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/announce.txt
@@ -0,0 +1,23 @@
+======================
+PyGreSQL Announcements
+======================
+
+-------------------------------
+Release of PyGreSQL version 4.0
+-------------------------------
+
+PyGreSQL v4.0 has been released.
+
+It is available at: ftp://ftp.PyGreSQL.org/pub/distrib/PyGreSQL-4.0.tgz.
+
+If you are running NetBSD, look in the packages directory under databases.
+There is also a package in the FreeBSD ports collection.
+
+Please refer to `changelog.txt <changelog.html>`_
+for things that have changed in this version.
+
+Please refer to `readme.txt <readme.html>`_
+for general information.
+
+| D'Arcy J.M. Cain
+| darcy@PyGreSQL.org
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.html
new file mode 100644
index 0000000..24c38e9
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.html
@@ -0,0 +1,333 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>PyGreSQL ChangeLog</title>
+<link rel="stylesheet" href="docs.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="pygresql-changelog">
+<h1 class="title">PyGreSQL ChangeLog</h1>
+<div class="section">
+<h1><a id="version-4-0-2009-01-01" name="version-4-0-2009-01-01">Version 4.0 (2009-01-01)</a></h1>
+<ul class="simple">
+<li>Dropped support for Python below 2.3 and PostgreSQL below 7.4.</li>
+<li>Improved performance of fetchall() for large result sets
+by speeding up the type casts (as suggested by Peter Schuller).</li>
+<li>Exposed exceptions as attributes of the connection object.</li>
+<li>Exposed connection as attribute of the cursor object.</li>
+<li>Cursors now support the iteration protocol.</li>
+<li>Added new method to get parameter settings.</li>
+<li>Added customizable row_factory as suggested by Simon Pamies.</li>
+<li>Separated between mandatory and additional type objects.</li>
+<li>Added keyword args to insert, update and delete methods.</li>
+<li>Added exception handling for direct copy.</li>
+<li>Release the GIL while making a connection
+(as suggested by Peter Schuller).</li>
+<li>If available, use decimal.Decimal for numeric types.</li>
+<li>Allow DB wrapper to be used with DB-API 2 connections
+(as suggested by Chris Hilton).</li>
+<li>Made private attributes of DB wrapper accessible.</li>
+<li>Dropped dependence on mx.DateTime module.</li>
+<li>Support for PQescapeStringConn() and PQescapeByteaConn();
+these are now also used by the internal _quote() functions.</li>
+<li>Added 'int8' to INTEGER types. New SMALLINT type.</li>
+<li>Added a way to find the number of rows affected by a query()
+with the classic pg module by returning it as a string.
+For single inserts, query() still returns the oid as an integer.
+The pgdb module already provides the "rowcount" cursor attribute
+for the same purpose.</li>
+<li>Improved getnotify() by calling PQconsumeInput() instead of
+submitting an empty command.</li>
+<li>Removed compatibility code for old OID munging style.</li>
+<li>The insert() and update() methods now use the "returning" clause
+if possible to get all changed values, and they also check in advance
+whether a subsequent select is possible, so that ongoing transactions
+won't break if there is no select privilege.</li>
+<li>Added "protocol_version" and "server_version" attributes.</li>
+<li>Revived the "user" attribute.</li>
+<li>The pg module now works correctly with composite primary keys;
+these are represented as frozensets.</li>
+<li>Removed the undocumented and actually unnecessary "view" parameter
+from the get() method.</li>
+<li>get() raises a nicer ProgrammingError instead of a KeyError
+if no primary key was found.</li>
+<li>delete() now also works based on the primary key if no oid available
+and returns whether the row existed or not.</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-8-1-2006-06-05" name="version-3-8-1-2006-06-05">Version 3.8.1 (2006-06-05)</a></h1>
+<ul class="simple">
+<li>Use string methods instead of deprecated string functions.</li>
+<li>Only use SQL-standard way of escaping quotes.</li>
+<li>Added the functions escape_string() and escape/unescape_bytea()
+(as suggested by Charlie Dyson and Kavous Bojnourdi a long time ago).</li>
+<li>Reverted code in clear() method that set date to current.</li>
+<li>Added code for backwards compatibility in OID munging code.</li>
+<li>Reorder attnames tests so that "interval" is checked for before "int."</li>
+<li>If caller supplies key dictionary, make sure that all has a namespace.</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-8-2006-02-17" name="version-3-8-2006-02-17">Version 3.8 (2006-02-17)</a></h1>
+<ul class="simple">
+<li>Installed new favicon.ico from Matthew Sporleder <<a class="reference" href="mailto:mspo@mspo.com">mspo@mspo.com</a>></li>
+<li>Replaced snprintf by PyOS_snprintf.</li>
+<li>Removed NO_SNPRINTF switch which is not needed any longer</li>
+<li>Clean up some variable names and namespace</li>
+<li>Add get_relations() method to get any type of relation</li>
+<li>Rewrite get_tables() to use get_relations()</li>
+<li>Use new method in get_attnames method to get attributes of views as well</li>
+<li>Add Binary type</li>
+<li>Number of rows is now -1 after executing no-result statements</li>
+<li>Fix some number handling</li>
+<li>Non-simple types do not raise an error any more</li>
+<li>Improvements to documentation framework</li>
+<li>Take into account that nowadays not every table must have an oid column</li>
+<li>Simplification and improvement of the inserttable() function</li>
+<li>Fix up unit tests</li>
+<li>The usual assortment of minor fixes and enhancements</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-7-2005-09-07" name="version-3-7-2005-09-07">Version 3.7 (2005-09-07)</a></h1>
+<p>Improvement of pgdb module:</p>
+<ul class="simple">
+<li>Use Python standard <cite>datetime</cite> if <cite>mxDateTime</cite> is not available</li>
+</ul>
+<p>Major improvements and clean-up in classic pg module:</p>
+<ul class="simple">
+<li>All members of the underlying connection directly available in <cite>DB</cite></li>
+<li>Fixes to quoting function</li>
+<li>Add checks for valid database connection to methods</li>
+<li>Improved namespace support, handle <cite>search_path</cite> correctly</li>
+<li>Removed old dust and unnessesary imports, added docstrings</li>
+<li>Internal sql statements as one-liners, smoothed out ugly code</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-6-2-2005-02-23" name="version-3-6-2-2005-02-23">Version 3.6.2 (2005-02-23)</a></h1>
+<ul class="simple">
+<li>Further fixes to namespace handling</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-6-1-2005-01-11" name="version-3-6-1-2005-01-11">Version 3.6.1 (2005-01-11)</a></h1>
+<ul class="simple">
+<li>Fixes to namespace handling</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-6-2004-12-17" name="version-3-6-2004-12-17">Version 3.6 (2004-12-17)</a></h1>
+<ul class="simple">
+<li>Better DB-API 2.0 compliance</li>
+<li>Exception hierarchy moved into C module and made available to both APIs</li>
+<li>Fix error in update method that caused false exceptions</li>
+<li>Moved to standard exception hierarchy in classic API</li>
+<li>Added new method to get transaction state</li>
+<li>Use proper Python constants where appropriate</li>
+<li>Use Python versions of strtol, etc. Allows Win32 build.</li>
+<li>Bug fixes and cleanups</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-5-2004-08-29" name="version-3-5-2004-08-29">Version 3.5 (2004-08-29)</a></h1>
+<p>Fixes and enhancements:</p>
+<ul class="simple">
+<li>Add interval to list of data types</li>
+<li>fix up method wrapping especially close()</li>
+<li>retry pkeys once if table missing in case it was just added</li>
+<li>wrap query method separately to handle debug better</li>
+<li>use isinstance instead of type</li>
+<li>fix free/PQfreemem issue - finally</li>
+<li>miscellaneous cleanups and formatting</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-4-2004-06-02" name="version-3-4-2004-06-02">Version 3.4 (2004-06-02)</a></h1>
+<p>Some cleanups and fixes.
+This is the first version where PyGreSQL is moved back out of the
+PostgreSQL tree. A lot of the changes mentioned below were actually
+made while in the PostgreSQL tree since their last release.</p>
+<ul class="simple">
+<li>Allow for larger integer returns</li>
+<li>Return proper strings for true and false</li>
+<li>Cleanup convenience method creation</li>
+<li>Enhance debugging method</li>
+<li>Add reopen method</li>
+<li>Allow programs to preload field names for speedup</li>
+<li>Move OID handling so that it returns long instead of int</li>
+<li>Miscellaneous cleanups and formatting</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-3-2001-12-03" name="version-3-3-2001-12-03">Version 3.3 (2001-12-03)</a></h1>
+<p>A few cleanups. Mostly there was some confusion about the latest version
+and so I am bumping the number to keep it straight.</p>
+<ul class="simple">
+<li>Added NUMERICOID to list of returned types. This fixes a bug when
+returning aggregates in the latest version of PostgreSQL.</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-2-2001-06-20" name="version-3-2-2001-06-20">Version 3.2 (2001-06-20)</a></h1>
+<p>Note that there are very few changes to PyGreSQL between 3.1 and 3.2.
+The main reason for the release is the move into the PostgreSQL
+development tree. Even the WIN32 changes are pretty minor.</p>
+<ul class="simple">
+<li>Add Win32 support (<a class="reference" href="mailto:gerhard@bigfoot.de">gerhard@bigfoot.de</a>)</li>
+<li>Fix some DB-API quoting problems (<a class="reference" href="mailto:niall.smart@ebeon.com">niall.smart@ebeon.com</a>)</li>
+<li>Moved development into PostgreSQL development tree.</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-1-2000-11-06" name="version-3-1-2000-11-06">Version 3.1 (2000-11-06)</a></h1>
+<ul class="simple">
+<li>Fix some quoting functions. In particular handle NULLs better.</li>
+<li>Use a method to add primary key information rather than direct
+manipulation of the class structures</li>
+<li>Break decimal out in <cite>_quote</cite> (in pg.py) and treat it as float</li>
+<li>Treat timestamp like date for quoting purposes</li>
+<li>Remove a redundant SELECT from the <cite>get</cite> method speeding it,
+and <cite>insert</cite> (since it calls <cite>get</cite>) up a little.</li>
+<li>Add test for BOOL type in typecast method to <cite>pgdbTypeCache</cite> class
+(<a class="reference" href="mailto:tv@beamnet.de">tv@beamnet.de</a>)</li>
+<li>Fix pgdb.py to send port as integer to lower level function
+(<a class="reference" href="mailto:dildog@l0pht.com">dildog@l0pht.com</a>)</li>
+<li>Change pg.py to speed up some operations</li>
+<li>Allow updates on tables with no primary keys</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-3-0-2000-05-30" name="version-3-0-2000-05-30">Version 3.0 (2000-05-30)</a></h1>
+<ul class="simple">
+<li>Remove strlen() call from pglarge_write() and get size from object
+(<a class="reference" href="mailto:Richard@Bouska.cz">Richard@Bouska.cz</a>)</li>
+<li>Add a little more error checking to the quote function in the wrapper</li>
+<li>Add extra checking in <cite>_quote</cite> function</li>
+<li>Wrap query in pg.py for debugging</li>
+<li>Add DB-API 2.0 support to pgmodule.c (<a class="reference" href="mailto:andre@via.ecp.fr">andre@via.ecp.fr</a>)</li>
+<li>Add DB-API 2.0 wrapper pgdb.py (<a class="reference" href="mailto:andre@via.ecp.fr">andre@via.ecp.fr</a>)</li>
+<li>Correct keyword clash (temp) in tutorial</li>
+<li>Clean up layout of tutorial</li>
+<li>Return NULL values as None (<a class="reference" href="mailto:rlawrence@lastfoot.com">rlawrence@lastfoot.com</a>)
+(WARNING: This will cause backwards compatibility issues)</li>
+<li>Change None to NULL in insert and update</li>
+<li>Change hash-bang lines to use /usr/bin/env</li>
+<li>Clearing date should be blank (NULL) not TODAY</li>
+<li>Quote backslashes in strings in <cite>_quote</cite> (<a class="reference" href="mailto:brian@CSUA.Berkeley.EDU">brian@CSUA.Berkeley.EDU</a>)</li>
+<li>Expanded and clarified build instructions (<a class="reference" href="mailto:tbryan@starship.python.net">tbryan@starship.python.net</a>)</li>
+<li>Make code thread safe (<a class="reference" href="mailto:Jerome.Alet@unice.fr">Jerome.Alet@unice.fr</a>)</li>
+<li>Add README.distutils (<a class="reference" href="mailto:mwa@gate.net">mwa@gate.net</a> & <a class="reference" href="mailto:jeremy@cnri.reston.va.us">jeremy@cnri.reston.va.us</a>)</li>
+<li>Many fixes and increased DB-API compliance by <a class="reference" href="mailto:chifungfan@yahoo.com">chifungfan@yahoo.com</a>,
+<a class="reference" href="mailto:tony@printra.net">tony@printra.net</a>, <a class="reference" href="mailto:jeremy@alum.mit.edu">jeremy@alum.mit.edu</a> and others to get the final
+version ready to release.</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-2-4-1999-06-15" name="version-2-4-1999-06-15">Version 2.4 (1999-06-15)</a></h1>
+<ul class="simple">
+<li>Insert returns None if the user doesn't have select permissions
+on the table. It can (and does) happen that one has insert but
+not select permissions on a table.</li>
+<li>Added ntuples() method to query object (<a class="reference" href="mailto:brit@druid.net">brit@druid.net</a>)</li>
+<li>Corrected a bug related to getresult() and the money type</li>
+<li>Corrected a bug related to negative money amounts</li>
+<li>Allow update based on primary key if munged oid not available and
+table has a primary key</li>
+<li>Add many __doc__ strings (<a class="reference" href="mailto:andre@via.ecp.fr">andre@via.ecp.fr</a>)</li>
+<li>Get method works with views if key specified</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-2-3-1999-04-17" name="version-2-3-1999-04-17">Version 2.3 (1999-04-17)</a></h1>
+<ul class="simple">
+<li>connect.host returns "localhost" when connected to Unix socket
+(<a class="reference" href="mailto:torppa@tuhnu.cutery.fi">torppa@tuhnu.cutery.fi</a>)</li>
+<li>Use <cite>PyArg_ParseTupleAndKeywords</cite> in connect() (<a class="reference" href="mailto:torppa@tuhnu.cutery.fi">torppa@tuhnu.cutery.fi</a>)</li>
+<li>fixes and cleanups (<a class="reference" href="mailto:torppa@tuhnu.cutery.fi">torppa@tuhnu.cutery.fi</a>)</li>
+<li>Fixed memory leak in dictresult() (<a class="reference" href="mailto:terekhov@emc.com">terekhov@emc.com</a>)</li>
+<li>Deprecated pgext.py - functionality now in pg.py</li>
+<li>More cleanups to the tutorial</li>
+<li>Added fileno() method - <a class="reference" href="mailto:terekhov@emc.com">terekhov@emc.com</a> (Mikhail Terekhov)</li>
+<li>added money type to quoting function</li>
+<li>Compiles cleanly with more warnings turned on</li>
+<li>Returns PostgreSQL error message on error</li>
+<li>Init accepts keywords (Jarkko Torppa)</li>
+<li>Convenience functions can be overridden (Jarkko Torppa)</li>
+<li>added close() method</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-2-2-1998-12-21" name="version-2-2-1998-12-21">Version 2.2 (1998-12-21)</a></h1>
+<ul class="simple">
+<li>Added user and password support thanks to Ng Pheng Siong (<a class="reference" href="mailto:ngps@post1.com">ngps@post1.com</a>)</li>
+<li>Insert queries return the inserted oid</li>
+<li>Add new <cite>pg</cite> wrapper (C module renamed to _pg)</li>
+<li>Wrapped database connection in a class</li>
+<li>Cleaned up some of the tutorial. (More work needed.)</li>
+<li>Added <cite>version</cite> and <cite>__version__</cite>.
+Thanks to <a class="reference" href="mailto:thilo@eevolute.com">thilo@eevolute.com</a> for the suggestion.</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-2-1-1998-03-07" name="version-2-1-1998-03-07">Version 2.1 (1998-03-07)</a></h1>
+<ul class="simple">
+<li>return fields as proper Python objects for field type</li>
+<li>Cleaned up pgext.py</li>
+<li>Added dictresult method</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-2-0-1997-12-23" name="version-2-0-1997-12-23">Version 2.0 (1997-12-23)</a></h1>
+<ul class="simple">
+<li>Updated code for PostgreSQL 6.2.1 and Python 1.5</li>
+<li>Reformatted code and converted to use full ANSI style prototypes</li>
+<li>Changed name to PyGreSQL (from PyGres95)</li>
+<li>Changed order of arguments to connect function</li>
+<li>Created new type <cite>pgqueryobject</cite> and moved certain methods to it</li>
+<li>Added a print function for pgqueryobject</li>
+<li>Various code changes - mostly stylistic</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-1-0b-1995-11-04" name="version-1-0b-1995-11-04">Version 1.0b (1995-11-04)</a></h1>
+<ul class="simple">
+<li>Keyword support for connect function moved from library file to C code
+and taken away from library</li>
+<li>Rewrote documentation</li>
+<li>Bug fix in connect function</li>
+<li>Enhancements in large objects interface methods</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-1-0a-1995-10-30" name="version-1-0a-1995-10-30">Version 1.0a (1995-10-30)</a></h1>
+<p>A limited release.</p>
+<ul class="simple">
+<li>Module adapted to standard Python syntax</li>
+<li>Keyword support for connect function in library file</li>
+<li>Rewrote default parameters interface (internal use of strings)</li>
+<li>Fixed minor bugs in module interface</li>
+<li>Redefinition of error messages</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-0-9b-1995-10-10" name="version-0-9b-1995-10-10">Version 0.9b (1995-10-10)</a></h1>
+<p>The first public release.</p>
+<ul class="simple">
+<li>Large objects implementation</li>
+<li>Many bug fixes, enhancements, ...</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="version-0-1a-1995-10-07" name="version-0-1a-1995-10-07">Version 0.1a (1995-10-07)</a></h1>
+<ul class="simple">
+<li>Basic libpq functions (SQL access)</li>
+</ul>
+</div>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.txt
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.txt b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.txt
new file mode 100644
index 0000000..ea0d71d
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/changelog.txt
@@ -0,0 +1,285 @@
+==================
+PyGreSQL ChangeLog
+==================
+
+Version 4.0 (2009-01-01)
+------------------------
+- Dropped support for Python below 2.3 and PostgreSQL below 7.4.
+- Improved performance of fetchall() for large result sets
+ by speeding up the type casts (as suggested by Peter Schuller).
+- Exposed exceptions as attributes of the connection object.
+- Exposed connection as attribute of the cursor object.
+- Cursors now support the iteration protocol.
+- Added new method to get parameter settings.
+- Added customizable row_factory as suggested by Simon Pamies.
+- Separated between mandatory and additional type objects.
+- Added keyword args to insert, update and delete methods.
+- Added exception handling for direct copy.
+- Release the GIL while making a connection
+ (as suggested by Peter Schuller).
+- If available, use decimal.Decimal for numeric types.
+- Allow DB wrapper to be used with DB-API 2 connections
+ (as suggested by Chris Hilton).
+- Made private attributes of DB wrapper accessible.
+- Dropped dependence on mx.DateTime module.
+- Support for PQescapeStringConn() and PQescapeByteaConn();
+ these are now also used by the internal _quote() functions.
+- Added 'int8' to INTEGER types. New SMALLINT type.
+- Added a way to find the number of rows affected by a query()
+ with the classic pg module by returning it as a string.
+ For single inserts, query() still returns the oid as an integer.
+ The pgdb module already provides the "rowcount" cursor attribute
+ for the same purpose.
+- Improved getnotify() by calling PQconsumeInput() instead of
+ submitting an empty command.
+- Removed compatibility code for old OID munging style.
+- The insert() and update() methods now use the "returning" clause
+ if possible to get all changed values, and they also check in advance
+ whether a subsequent select is possible, so that ongoing transactions
+ won't break if there is no select privilege.
+- Added "protocol_version" and "server_version" attributes.
+- Revived the "user" attribute.
+- The pg module now works correctly with composite primary keys;
+ these are represented as frozensets.
+- Removed the undocumented and actually unnecessary "view" parameter
+ from the get() method.
+- get() raises a nicer ProgrammingError instead of a KeyError
+ if no primary key was found.
+- delete() now also works based on the primary key if no oid available
+ and returns whether the row existed or not.
+
+
+Version 3.8.1 (2006-06-05)
+--------------------------
+- Use string methods instead of deprecated string functions.
+- Only use SQL-standard way of escaping quotes.
+- Added the functions escape_string() and escape/unescape_bytea()
+ (as suggested by Charlie Dyson and Kavous Bojnourdi a long time ago).
+- Reverted code in clear() method that set date to current.
+- Added code for backwards compatibility in OID munging code.
+- Reorder attnames tests so that "interval" is checked for before "int."
+- If caller supplies key dictionary, make sure that all has a namespace.
+
+Version 3.8 (2006-02-17)
+------------------------
+- Installed new favicon.ico from Matthew Sporleder <ms...@mspo.com>
+- Replaced snprintf by PyOS_snprintf.
+- Removed NO_SNPRINTF switch which is not needed any longer
+- Clean up some variable names and namespace
+- Add get_relations() method to get any type of relation
+- Rewrite get_tables() to use get_relations()
+- Use new method in get_attnames method to get attributes of views as well
+- Add Binary type
+- Number of rows is now -1 after executing no-result statements
+- Fix some number handling
+- Non-simple types do not raise an error any more
+- Improvements to documentation framework
+- Take into account that nowadays not every table must have an oid column
+- Simplification and improvement of the inserttable() function
+- Fix up unit tests
+- The usual assortment of minor fixes and enhancements
+
+Version 3.7 (2005-09-07)
+------------------------
+Improvement of pgdb module:
+
+- Use Python standard `datetime` if `mxDateTime` is not available
+
+Major improvements and clean-up in classic pg module:
+
+- All members of the underlying connection directly available in `DB`
+- Fixes to quoting function
+- Add checks for valid database connection to methods
+- Improved namespace support, handle `search_path` correctly
+- Removed old dust and unnessesary imports, added docstrings
+- Internal sql statements as one-liners, smoothed out ugly code
+
+Version 3.6.2 (2005-02-23)
+--------------------------
+- Further fixes to namespace handling
+
+Version 3.6.1 (2005-01-11)
+--------------------------
+- Fixes to namespace handling
+
+Version 3.6 (2004-12-17)
+------------------------
+- Better DB-API 2.0 compliance
+- Exception hierarchy moved into C module and made available to both APIs
+- Fix error in update method that caused false exceptions
+- Moved to standard exception hierarchy in classic API
+- Added new method to get transaction state
+- Use proper Python constants where appropriate
+- Use Python versions of strtol, etc. Allows Win32 build.
+- Bug fixes and cleanups
+
+Version 3.5 (2004-08-29)
+------------------------
+Fixes and enhancements:
+
+- Add interval to list of data types
+- fix up method wrapping especially close()
+- retry pkeys once if table missing in case it was just added
+- wrap query method separately to handle debug better
+- use isinstance instead of type
+- fix free/PQfreemem issue - finally
+- miscellaneous cleanups and formatting
+
+Version 3.4 (2004-06-02)
+------------------------
+Some cleanups and fixes.
+This is the first version where PyGreSQL is moved back out of the
+PostgreSQL tree. A lot of the changes mentioned below were actually
+made while in the PostgreSQL tree since their last release.
+
+- Allow for larger integer returns
+- Return proper strings for true and false
+- Cleanup convenience method creation
+- Enhance debugging method
+- Add reopen method
+- Allow programs to preload field names for speedup
+- Move OID handling so that it returns long instead of int
+- Miscellaneous cleanups and formatting
+
+Version 3.3 (2001-12-03)
+------------------------
+A few cleanups. Mostly there was some confusion about the latest version
+and so I am bumping the number to keep it straight.
+
+- Added NUMERICOID to list of returned types. This fixes a bug when
+ returning aggregates in the latest version of PostgreSQL.
+
+Version 3.2 (2001-06-20)
+------------------------
+Note that there are very few changes to PyGreSQL between 3.1 and 3.2.
+The main reason for the release is the move into the PostgreSQL
+development tree. Even the WIN32 changes are pretty minor.
+
+- Add Win32 support (gerhard@bigfoot.de)
+- Fix some DB-API quoting problems (niall.smart@ebeon.com)
+- Moved development into PostgreSQL development tree.
+
+Version 3.1 (2000-11-06)
+------------------------
+- Fix some quoting functions. In particular handle NULLs better.
+- Use a method to add primary key information rather than direct
+ manipulation of the class structures
+- Break decimal out in `_quote` (in pg.py) and treat it as float
+- Treat timestamp like date for quoting purposes
+- Remove a redundant SELECT from the `get` method speeding it,
+ and `insert` (since it calls `get`) up a little.
+- Add test for BOOL type in typecast method to `pgdbTypeCache` class
+ (tv@beamnet.de)
+- Fix pgdb.py to send port as integer to lower level function
+ (dildog@l0pht.com)
+- Change pg.py to speed up some operations
+- Allow updates on tables with no primary keys
+
+Version 3.0 (2000-05-30)
+------------------------
+- Remove strlen() call from pglarge_write() and get size from object
+ (Richard@Bouska.cz)
+- Add a little more error checking to the quote function in the wrapper
+- Add extra checking in `_quote` function
+- Wrap query in pg.py for debugging
+- Add DB-API 2.0 support to pgmodule.c (andre@via.ecp.fr)
+- Add DB-API 2.0 wrapper pgdb.py (andre@via.ecp.fr)
+- Correct keyword clash (temp) in tutorial
+- Clean up layout of tutorial
+- Return NULL values as None (rlawrence@lastfoot.com)
+ (WARNING: This will cause backwards compatibility issues)
+- Change None to NULL in insert and update
+- Change hash-bang lines to use /usr/bin/env
+- Clearing date should be blank (NULL) not TODAY
+- Quote backslashes in strings in `_quote` (brian@CSUA.Berkeley.EDU)
+- Expanded and clarified build instructions (tbryan@starship.python.net)
+- Make code thread safe (Jerome.Alet@unice.fr)
+- Add README.distutils (mwa@gate.net & jeremy@cnri.reston.va.us)
+- Many fixes and increased DB-API compliance by chifungfan@yahoo.com,
+ tony@printra.net, jeremy@alum.mit.edu and others to get the final
+ version ready to release.
+
+Version 2.4 (1999-06-15)
+------------------------
+- Insert returns None if the user doesn't have select permissions
+ on the table. It can (and does) happen that one has insert but
+ not select permissions on a table.
+- Added ntuples() method to query object (brit@druid.net)
+- Corrected a bug related to getresult() and the money type
+- Corrected a bug related to negative money amounts
+- Allow update based on primary key if munged oid not available and
+ table has a primary key
+- Add many __doc__ strings (andre@via.ecp.fr)
+- Get method works with views if key specified
+
+Version 2.3 (1999-04-17)
+------------------------
+- connect.host returns "localhost" when connected to Unix socket
+ (torppa@tuhnu.cutery.fi)
+- Use `PyArg_ParseTupleAndKeywords` in connect() (torppa@tuhnu.cutery.fi)
+- fixes and cleanups (torppa@tuhnu.cutery.fi)
+- Fixed memory leak in dictresult() (terekhov@emc.com)
+- Deprecated pgext.py - functionality now in pg.py
+- More cleanups to the tutorial
+- Added fileno() method - terekhov@emc.com (Mikhail Terekhov)
+- added money type to quoting function
+- Compiles cleanly with more warnings turned on
+- Returns PostgreSQL error message on error
+- Init accepts keywords (Jarkko Torppa)
+- Convenience functions can be overridden (Jarkko Torppa)
+- added close() method
+
+Version 2.2 (1998-12-21)
+------------------------
+- Added user and password support thanks to Ng Pheng Siong (ngps@post1.com)
+- Insert queries return the inserted oid
+- Add new `pg` wrapper (C module renamed to _pg)
+- Wrapped database connection in a class
+- Cleaned up some of the tutorial. (More work needed.)
+- Added `version` and `__version__`.
+ Thanks to thilo@eevolute.com for the suggestion.
+
+Version 2.1 (1998-03-07)
+------------------------
+- return fields as proper Python objects for field type
+- Cleaned up pgext.py
+- Added dictresult method
+
+Version 2.0 (1997-12-23)
+-------------------------
+- Updated code for PostgreSQL 6.2.1 and Python 1.5
+- Reformatted code and converted to use full ANSI style prototypes
+- Changed name to PyGreSQL (from PyGres95)
+- Changed order of arguments to connect function
+- Created new type `pgqueryobject` and moved certain methods to it
+- Added a print function for pgqueryobject
+- Various code changes - mostly stylistic
+
+Version 1.0b (1995-11-04)
+-------------------------
+- Keyword support for connect function moved from library file to C code
+ and taken away from library
+- Rewrote documentation
+- Bug fix in connect function
+- Enhancements in large objects interface methods
+
+Version 1.0a (1995-10-30)
+-------------------------
+A limited release.
+
+- Module adapted to standard Python syntax
+- Keyword support for connect function in library file
+- Rewrote default parameters interface (internal use of strings)
+- Fixed minor bugs in module interface
+- Redefinition of error messages
+
+Version 0.9b (1995-10-10)
+-------------------------
+The first public release.
+
+- Large objects implementation
+- Many bug fixes, enhancements, ...
+
+Version 0.1a (1995-10-07)
+-------------------------
+- Basic libpq functions (SQL access)
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/default.css
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/default.css b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/default.css
new file mode 100644
index 0000000..15d0778
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/default.css
@@ -0,0 +1,279 @@
+/*
+:Author: David Goodger
+:Contact: goodger@users.sourceforge.net
+:Date: $Date: 2006/01/22 16:15:33 $
+:Revision: $Revision: 1.2 $
+:Copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+
+See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
+customize this style sheet.
+*/
+
+/* used to remove borders from tables and images */
+.borderless, table.borderless td, table.borderless th {
+ border: 0 }
+
+table.borderless td, table.borderless th {
+ /* Override padding for "table.docutils td" with "! important".
+ The right padding separates the table cells. */
+ padding: 0 0.5em 0 0 ! important }
+
+.first {
+ /* Override more specific margin styles with "! important". */
+ margin-top: 0 ! important }
+
+.last, .with-subtitle {
+ margin-bottom: 0 ! important }
+
+.hidden {
+ display: none }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+blockquote.epigraph {
+ margin: 2em 5em ; }
+
+dl.docutils dd {
+ margin-bottom: 0.5em }
+
+/* Uncomment (and remove this text!) to get bold-faced definition list terms
+dl.docutils dt {
+ font-weight: bold }
+*/
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.admonition, div.attention, div.caution, div.danger, div.error,
+div.hint, div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.admonition p.admonition-title, div.hint p.admonition-title,
+div.important p.admonition-title, div.note p.admonition-title,
+div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+/* Uncomment (and remove this text!) to get reduced vertical space in
+ compound paragraphs.
+div.compound .compound-first, div.compound .compound-middle {
+ margin-bottom: 0.5em }
+
+div.compound .compound-last, div.compound .compound-middle {
+ margin-top: 0.5em }
+*/
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em ;
+ margin-right: 2em }
+
+div.footer, div.header {
+ clear: both;
+ font-size: smaller }
+
+div.line-block {
+ display: block ;
+ margin-top: 1em ;
+ margin-bottom: 1em }
+
+div.line-block div.line-block {
+ margin-top: 0 ;
+ margin-bottom: 0 ;
+ margin-left: 1.5em }
+
+div.sidebar {
+ margin-left: 1em ;
+ border: medium outset ;
+ padding: 1em ;
+ background-color: #ffffee ;
+ width: 40% ;
+ float: right ;
+ clear: right }
+
+div.sidebar p.rubric {
+ font-family: sans-serif ;
+ font-size: medium }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
+h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
+ margin-top: 0.4em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr.docutils {
+ width: 75% }
+
+img.align-left {
+ clear: left }
+
+img.align-right {
+ clear: right }
+
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+p.attribution {
+ text-align: right ;
+ margin-left: 50% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.rubric {
+ font-weight: bold ;
+ font-size: larger ;
+ color: maroon ;
+ text-align: center }
+
+p.sidebar-title {
+ font-family: sans-serif ;
+ font-weight: bold ;
+ font-size: larger }
+
+p.sidebar-subtitle {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font-family: serif ;
+ font-size: 100% }
+
+pre.literal-block, pre.doctest-block {
+ margin-left: 2em ;
+ margin-right: 2em ;
+ background-color: #eeeeee }
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+span.section-subtitle {
+ /* font-size relative to parent (h1..h6 element) */
+ font-size: 80% }
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.docutils {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.footnote {
+ border-left: solid 1px black;
+ margin-left: 1px }
+
+table.docutils td, table.docutils th,
+table.docinfo td, table.docinfo th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+table.docutils th.field-name, table.docinfo th.docinfo-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap ;
+ padding-left: 0 }
+
+h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
+h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
+ font-size: 100% }
+
+tt.docutils {
+ background-color: #eeeeee }
+
+ul.auto-toc {
+ list-style-type: none }
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/docs.css
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/docs.css b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/docs.css
new file mode 100644
index 0000000..3d99c95
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/docs.css
@@ -0,0 +1,109 @@
+/*
+Stylesheet for use with Docutils.
+
+Customized for PyGreSQL docs.
+*/
+
+@import url(default.css);
+
+body {
+ margin: 8pt;
+ padding: 8pt;
+ background-color: #f8f8ff;
+ color: #000008;
+ text-align: justify;
+ font-family: Arial, Verdana, Helvetica, sans-serif;
+ font-size: 11pt; }
+
+a {
+ text-decoration: none; }
+
+a:hover {
+ text-decoration: underline; }
+
+.title, .subtitle {
+ color: #003; }
+
+.topic-title {
+ color: #006;
+ font-size: 14pt; }
+
+h1, h2, h3, h4 {
+ color: #006; }
+
+h1 {
+ padding-top: 20pt;
+ font-size: 17pt; }
+
+div#pygresql-changelog div.section h1 {
+ font-size: 12pt;
+}
+
+h1.title {
+ font-size: 20pt;
+}
+
+h2 {
+ font-size: 14pt; }
+
+h2.subtitle {
+ font-size: 16pt;
+}
+
+h3 {
+ font-size: 13pt; }
+
+h4 {
+ font-size: 12pt; }
+
+a.toc-backref {
+ color: #006; }
+
+ul.simple li {
+ margin-top: 4pt; }
+
+ul.simple ul li {
+ margin-top: 2pt; }
+
+div.contents ul {
+ list-style-type: none; }
+
+div.contents ul li {
+ margin-top: 4pt;
+ font-size: 12pt; }
+
+div.contents ul ul li {
+ margin-top: 2pt;
+ font-size: 11pt; }
+
+cite {
+ font-style: normal;
+ font-family: monospace;
+ font-weight: bold; }
+
+table.field-list th.field-name {
+ font-style: normal;
+ font-family: monospace;
+ font-weight: bold; }
+
+tt.literal, pre.literal-block {
+ font-style: normal;
+ font-family: monospace;
+ font-weight: bold;
+ background-color: #fff; }
+
+tt.literal {
+ padding-left: 2pt;
+ padding-right: 2pt; }
+
+pre.literal-block {
+ padding: 4pt;
+ border: 1px dotted #ccc; }
+
+table.docutils {
+ border-spacing: 0px;
+ border-collapse: collapse; }
+
+table.docutils td {
+ margin: 0px;
+ padding: 2pt; }
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.html
new file mode 100644
index 0000000..358de81
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.html
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>PyGreSQL future directions</title>
+<link rel="stylesheet" href="docs.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="pygresql-future-directions">
+<h1 class="title">PyGreSQL future directions</h1>
+<div class="section">
+<h1><a id="to-do" name="to-do">To Do</a></h1>
+<ul class="simple">
+<li>Documentation for the pgdb module (everything specific to PyGreSQL).</li>
+<li>The large object and direct access functions need much more attention.</li>
+<li>The C module needs to be cleaned up and redundant code merged,
+and should get its own unit test module.</li>
+<li>The fetch method should use real cursors.</li>
+<li>What shall we do with the "tutorial" directory
+(it's rather a tutorial for Postgres/SQL than for PyGreSQL,
+it's using only the query method from the classic pg module and
+no other PyGreSQL functionality, it's rather a demo than a tutorial)?</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="proposed-patches" name="proposed-patches">Proposed Patches</a></h1>
+<ul class="simple">
+<li>Notice handling with PQsetNoticeReceiver and PQsetNoticeProcessor
+(one possible implementation was already suggested by Dmitry Dvoinikov
+<a class="reference" href="http://mailman.vex.net/pipermail/pygresql/2005-November/001530.html">http://mailman.vex.net/pipermail/pygresql/2005-November/001530.html</a>).
+Maybe also make notifications accessible via the optional cursor and
+connection attribute "messages" proposed in the DB-API specs.</li>
+</ul>
+</div>
+<div class="section">
+<h1><a id="wish-list" name="wish-list">Wish List</a></h1>
+<ul class="simple">
+<li>Make SQLSTATE error codes available.</li>
+<li>Make use of PQexecParams() and PQprepare(). This could speed up
+executemany() and allow retrieving binary data directly by setting
+the resultFormat parameter to one.</li>
+<li>Support optional "errorhandler" extension.</li>
+<li>Support optional cursor and connection attribute "messages".</li>
+<li>Connection as context manager (see <a class="reference" href="http://tinyurl.com/6j9cef">http://tinyurl.com/6j9cef</a>).</li>
+<li>Users should be able to register their own types with _pg.</li>
+<li>Let pg and pgdb support namedtuples (as available in Py 2.6).
+pg could get a new method namedresult(), and pgdb could provide
+a row factory for namedtuples (similar to sqlite3).</li>
+<li>New methods in the classic module, similar to getresult() and
+dictresult(), but returning dictionaries of rows instead of lists
+of rows (with primary key or oids as keys).</li>
+<li>Make PyGreSQL thread-safe on the connection level.</li>
+<li>The API documentation could be created with Epydoc.</li>
+<li>Write a tutorial for beginners and advanced use.</li>
+<li>More and better documented examples.</li>
+</ul>
+</div>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.txt
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.txt b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.txt
new file mode 100644
index 0000000..8dec0fb
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/future.txt
@@ -0,0 +1,48 @@
+==========================
+PyGreSQL future directions
+==========================
+
+
+To Do
+-----
+
+- Documentation for the pgdb module (everything specific to PyGreSQL).
+- The large object and direct access functions need much more attention.
+- The C module needs to be cleaned up and redundant code merged,
+ and should get its own unit test module.
+- The fetch method should use real cursors.
+- What shall we do with the "tutorial" directory
+ (it's rather a tutorial for Postgres/SQL than for PyGreSQL,
+ it's using only the query method from the classic pg module and
+ no other PyGreSQL functionality, it's rather a demo than a tutorial)?
+
+Proposed Patches
+----------------
+
+- Notice handling with PQsetNoticeReceiver and PQsetNoticeProcessor
+ (one possible implementation was already suggested by Dmitry Dvoinikov
+ http://mailman.vex.net/pipermail/pygresql/2005-November/001530.html).
+ Maybe also make notifications accessible via the optional cursor and
+ connection attribute "messages" proposed in the DB-API specs.
+
+Wish List
+---------
+
+- Make SQLSTATE error codes available.
+- Make use of PQexecParams() and PQprepare(). This could speed up
+ executemany() and allow retrieving binary data directly by setting
+ the resultFormat parameter to one.
+- Support optional "errorhandler" extension.
+- Support optional cursor and connection attribute "messages".
+- Connection as context manager (see http://tinyurl.com/6j9cef).
+- Users should be able to register their own types with _pg.
+- Let pg and pgdb support namedtuples (as available in Py 2.6).
+ pg could get a new method namedresult(), and pgdb could provide
+ a row factory for namedtuples (similar to sqlite3).
+- New methods in the classic module, similar to getresult() and
+ dictresult(), but returning dictionaries of rows instead of lists
+ of rows (with primary key or oids as keys).
+- Make PyGreSQL thread-safe on the connection level.
+- The API documentation could be created with Epydoc.
+- Write a tutorial for beginners and advanced use.
+- More and better documented examples.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/index.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/index.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/index.html
new file mode 100644
index 0000000..be2b37c
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/index.html
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>PyGreSQL - PostgreSQL module for Python</title>
+ <meta http-equiv="Content-Type" content="text/html; CHARSET=iso-8859-1">
+ <meta name="description" content="PyGreSQL homepage">
+ <meta name="keywords" content="PyGreSQL, Python, PostgreSQL, database, driver, DB-API, pg, pgdb">
+ <style type="text/css">
+ <!--
+ body {
+ margin: 8pt;
+ padding: 8pt;
+ background-color: #f8f8ff;
+ color: #000008;
+ text-align: justify;
+ font-family: Arial, Verdana, Helvetica, sans-serif;
+ font-size: 12pt; }
+ a {
+ text-decoration: none; }
+ a:hover {
+ text-decoration: underline; }
+ h1, h2 {
+ color: #006; }
+ h1 {
+ padding-top: 16pt;
+ font-size: 18pt; }
+ h2 {
+ padding-top: 8pt;
+ font-size: 16pt; }
+ ul {
+ list-style-type: none; }
+ ul li {
+ margin-top: 4pt;
+ font-size: 13pt; }
+ ul ul li {
+ margin-top: 2pt;
+ font-size: 12pt; }
+ #title {
+ position: absolute;
+ top: 0px;
+ left: 16px;
+ font-size: 36px;
+ font-style: italic;
+ letter-spacing: 5px;
+ color: #666;
+ z-index: 600; }
+ #version {
+ position: absolute;
+ top: 42px;
+ left: 64px;
+ font-size: 11px;
+ font-style: italic;
+ letter-spacing: 5px;
+ color: #000;
+ z-index: 610; }
+ #banner {
+ position: absolute;
+ padding-top: 0px;
+ padding-bottom: 0px;
+ text-align: center;
+ top: 27px;
+ left: 0px;
+ width: 100%;
+ height: 30px;
+ background: #ccd4e2;
+ z-index: 550;
+ border-top: 1px #999 solid;
+ border-bottom: 1px #999 solid; }
+ #bannertext {
+ position: absolute;
+ text-align: center;
+ font-size: 14px;
+ font-weight: bold;
+ letter-spacing: 4px;
+ color: #000066;
+ top: 39px;
+ right: 5%;
+ z-index: 560; }
+ #content {
+ margin: 36px 20px 2px 20px;
+ padding: 4pt 8pt 4pt 16pt;
+ border-left: 1px dashed #555;
+ border-bottom: 1px dashed #555; }
+ #copyright {
+ padding-top: 6pt;
+ font-size: 10pt;
+ color: #333;
+ text-align: center; }
+ -->
+ </style>
+</head>
+
+<body>
+
+ <div id="title">PyGreSQL</div>
+ <div id="version">Version 4.0</div>
+ <div id="banner"></div>
+ <div id="bannertext">:: PostgreSQL module for Python ::</div>
+
+ <div id="content">
+
+ <h1>PyGreSQL – PostgreSQL module for Python</h1>
+
+ <p><b>PyGreSQL</b> is an <em>open-source</em>
+ <a href="http://www.python.org">Python</a> module
+ that interfaces to a <a href="http://www.postgresql.org">PostgreSQL</a> database.
+ It embeds the PostgreSQL query library to allow easy use of the powerful PostgreSQL
+ features from a Python script.</p>
+
+ <p>This software is copyright © 1995, Pascal Andre.<br />
+ Further modifications are copyright © 1997-2006 by D'Arcy J.M. Cain.</p>
+
+ <p>See the
+ <a href="readme.html#copyright-notice">copyright notice</a>
+ for detailed information.</p>
+
+ <a name="documentation"></a>
+ <h2>Documentation</h2>
+
+ <p>The following information is also available in the <b>docs</b> folder of the distribution:</p>
+
+ <ul>
+ <li><a href="readme.html"><b>readme</b> – General Information</a>
+ <ul>
+ <li><a href="readme.html#copyright-notice">Copyright notice</a></li>
+ <li><a href="readme.html#introduction">Introduction</a></li>
+ <li><a href="readme.html#where-to-get">Where to get ... ?</a></li>
+ <li><a href="readme.html#distribution-files">Distribution files</a></li>
+ </ul></li>
+ <li><a href="announce.html"><b>announce</b> – Last announcement</a></li>
+ <li><a href="install.html"><b>install</b> – Installation</a></li>
+ <li><a href="pg.html"><b>pg</b> – The “classic” PyGreSQL interface</a></li>
+ <li><a href="pgdb.html"><b>pgdb</b> – The DB-API compliant PyGreSQL interface</a></li>
+ <li><a href="changelog.html"><b>changelog</b> – Historical changes</a></li>
+ <li><a href="future.html"><b>future</b> – Future directions</a></li>
+ </ul>
+
+ <a name="cvs"></a>
+ <h2>CVS Access</h2>
+
+ <p>The
+ <a href="http://www.pygresql.org/cvsweb.cgi/pygresql">CVS repository</a>
+ is available through
+ <a href="http://www.freebsd.org/projects/cvsweb.html">CVSWeb</a>.</p>
+
+ <a name="mailinglist"></a>
+ <h2>Mailing list</h2>
+
+ <p>You can join
+ <a href="http://mailman.vex.net/mailman/listinfo/pygresql">the mailing
+ list</a> to discuss future development of the PyGreSQL interface.
+ This is usually a low volume list except when there are new features
+ being added.</p>
+
+ <a name="examples"></a>
+ <h2>Examples</h2>
+
+ <p>I am starting to collect examples of applications that use PyGreSQL.
+ So far I only have a few but if you have an example for me, you can
+ either send me the files or the URL for me to point to.</p>
+
+ <p>Here is a <a href="http://ontario.bikerides.ca">List of motorcycle
+ rides in Ontario</a> that uses a PostgreSQL database to store the
+ rides. There is a link at the bottom of the page to view the source code.</p>
+
+ <p>
+ Oleg Broytmann has written a simple example
+ <a href="http://phd.pp.ru/Software/Python/#rgb_example">RGB
+ database demo</a>.
+ </p>
+
+ </div>
+
+ <div id="copyright">
+ Created and maintained by D'Arcy J.M. Cain –
+ last update: 17 February 2006.<br />
+ If you have any comments, <a href="mailto:darcy@pygresql.org">send mail</a> to me.
+ </div>
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.html
new file mode 100644
index 0000000..f1e48c0
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.html
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>PyGreSQL Installation</title>
+<link rel="stylesheet" href="docs.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="pygresql-installation">
+<h1 class="title">PyGreSQL Installation</h1>
+<div class="contents topic">
+<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
+<ul class="auto-toc simple">
+<li><a class="reference" href="#general" id="id1" name="id1">1 General</a></li>
+<li><a class="reference" href="#installing-from-a-binary-distribution" id="id2" name="id2">2 Installing from a Binary Distribution</a></li>
+<li><a class="reference" href="#installing-from-source" id="id3" name="id3">3 Installing from Source</a><ul class="auto-toc">
+<li><a class="reference" href="#building-and-installing-with-distutils" id="id4" name="id4">3.1 Building and installing with Distutils</a></li>
+<li><a class="reference" href="#compiling-manually" id="id5" name="id5">3.2 Compiling Manually</a></li>
+<li><a class="reference" href="#stand-alone" id="id6" name="id6">3.3 Stand-Alone</a></li>
+<li><a class="reference" href="#built-in-to-python-interpreter" id="id7" name="id7">3.4 Built-in to Python interpreter</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id1" id="general" name="general">1 General</a></h1>
+<p>You must first have installed Python and PostgreSQL on your system.
+If you want to access remote database only, you don't need to install
+the full PostgreSQL server, but only the C interface (libpq). If you
+are on Windows, make sure that the directory with libpq.dll is in your
+<tt class="docutils literal"><span class="pre">PATH</span></tt> environment variable.</p>
+<p>The current version of PyGreSQL has been tested with Python 2.5 and
+PostGreSQL 8.3. Older version should work as well, but you will need
+at least Python 2.3 and PostgreSQL 7.4.</p>
+<p>PyGreSQL will be installed as three modules, a dynamic module called
+_pg.pyd, and two pure Python wrapper modules called pg.py and pgdb.py.
+All three files will be installed directly into the Python site-packages
+directory. To uninstall PyGreSQL, simply remove these three files again.</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id2" id="installing-from-a-binary-distribution" name="installing-from-a-binary-distribution">2 Installing from a Binary Distribution</a></h1>
+<p>This is the easiest way to install PyGreSQL.</p>
+<p>You can currently download PyGreSQL as Linux RPM, NetBSD package and Windows
+installer. Make sure the required Python version of the binary package matches
+the Python version you have installed.</p>
+<p>Install the package as usual on your system.</p>
+<p>Note that the documentation is currently only included in the source package.</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id3" id="installing-from-source" name="installing-from-source">3 Installing from Source</a></h1>
+<p>If you want to install PyGreSQL from Source, or there is no binary
+package available for your platform, follow these instructions.</p>
+<p>Make sure the Python header files and PostgreSQL client and server header
+files are installed. These come usually with the "devel" packages on Unix
+systems and the installer executables on Windows systems.</p>
+<p>If you are using a precompiled PostgreSQL, you will also need the pg_config
+tool. This is usually also part of the "devel" package on Unix, and will be
+installed as part of the database server feature on Windows systems.</p>
+<div class="section">
+<h2><a class="toc-backref" href="#id4" id="building-and-installing-with-distutils" name="building-and-installing-with-distutils">3.1 Building and installing with Distutils</a></h2>
+<p>You can build and install PyGreSQL using
+<a class="reference" href="http://docs.python.org/install/">Distutils</a>.</p>
+<p>Download and unpack the PyGreSQL source tarball if you haven't already done so.</p>
+<p>Type the following commands to build and install PyGreSQL:</p>
+<pre class="literal-block">
+python setup.py build
+python setup.py install
+</pre>
+<p>If you are using <a class="reference" href="http://www.mingw.org">MinGW</a> to build PyGreSQL under
+Microsoft Windows, please note that Python newer version 2.3 is using msvcr71
+instead of msvcrt as its common runtime library. You can allow for that by
+editing the file <tt class="docutils literal"><span class="pre">%MinGWpath%/lib/gcc/%MinGWversion%/specs</span></tt> and changing
+the entry that reads <tt class="docutils literal"><span class="pre">-lmsvcrt</span></tt> to <tt class="docutils literal"><span class="pre">-lmsvcr71</span></tt>. You may also need to copy
+<tt class="docutils literal"><span class="pre">libpq.lib</span></tt> to <tt class="docutils literal"><span class="pre">libpq.a</span></tt> in the PostgreSQL <tt class="docutils literal"><span class="pre">lib</span></tt> directory. Then use
+the following command to build and install PyGreSQL:</p>
+<pre class="literal-block">
+python setup.py build -c mingw32 install
+</pre>
+<p>Now you should be ready to use PyGreSQL.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id5" id="compiling-manually" name="compiling-manually">3.2 Compiling Manually</a></h2>
+<p>The source file for compiling the dynamic module is called pgmodule.c.
+You have two options. You can compile PyGreSQL as a stand-alone module
+or you can build it into the Python interpreter.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id6" id="stand-alone" name="stand-alone">3.3 Stand-Alone</a></h2>
+<ul>
+<li><p class="first">In the directory containing <tt class="docutils literal"><span class="pre">pgmodule.c</span></tt>, run the following command:</p>
+<pre class="literal-block">
+cc -fpic -shared -o _pg.so -I$PYINC -I$PGINC -I$PSINC -L$PGLIB -lpq pgmodule.c
+</pre>
+<p>where you have to set:</p>
+<pre class="literal-block">
+PYINC = path to the Python include files
+ (usually something like /usr/include/python)
+PGINC = path to the PostgreSQL client include files
+ (something like /usr/include/pgsql or /usr/include/postgresql)
+PSINC = path to the PostgreSQL server include files
+ (like /usr/include/pgsql/server or /usr/include/postgresql/server)
+PGLIB = path to the PostgreSQL object code libraries (usually /usr/lib)
+</pre>
+<p>If you are not sure about the above paths, try something like:</p>
+<pre class="literal-block">
+PYINC=`find /usr -name Python.h`
+PGINC=`find /usr -name libpq-fe.h`
+PSINC=`find /usr -name postgres.h`
+PGLIB=`find /usr -name libpq.so`
+</pre>
+<p>If you have the <tt class="docutils literal"><span class="pre">pg_config</span></tt> tool installed, you can set:</p>
+<pre class="literal-block">
+PGINC=`pg_config --includedir`
+PSINC=`pg_config --includedir-server`
+PGLIB=`pg_config --libdir`
+</pre>
+<p>Some options may be added to this line:</p>
+<pre class="literal-block">
+-DNO_DEF_VAR no default variables support
+-DNO_DIRECT no direct access methods
+-DNO_LARGE no large object support
+-DNO_PQSOCKET if running an older PostgreSQL
+</pre>
+<p>Define <tt class="docutils literal"><span class="pre">NO_PQSOCKET</span></tt> if you are using a version of PostgreSQL before 6.4
+that does not have the PQsocket function. The other options will be
+described in the next sections.</p>
+<p>On some systems you may need to include <tt class="docutils literal"><span class="pre">-lcrypt</span></tt> in the list of libraries
+to make it compile.</p>
+</li>
+<li><p class="first">Test the new module. Something like the following should work:</p>
+<pre class="literal-block">
+$ python
+
+>>> import _pg
+>>> db = _pg.connect('thilo','localhost')
+>>> db.query("INSERT INTO test VALUES ('ping','pong')")
+18304
+>>> db.query("SELECT * FROM test")
+eins|zwei
+----+----
+ping|pong
+(1 row)
+</pre>
+</li>
+<li><p class="first">Finally, move the <tt class="docutils literal"><span class="pre">_pg.so</span></tt>, <tt class="docutils literal"><span class="pre">pg.py</span></tt>, and <tt class="docutils literal"><span class="pre">pgdb.py</span></tt> to a directory in
+your <tt class="docutils literal"><span class="pre">PYTHONPATH</span></tt>. A good place would be <tt class="docutils literal"><span class="pre">/usr/lib/python/site-packages</span></tt>
+if your Python modules are in <tt class="docutils literal"><span class="pre">/usr/lib/python</span></tt>.</p>
+</li>
+</ul>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id7" id="built-in-to-python-interpreter" name="built-in-to-python-interpreter">3.4 Built-in to Python interpreter</a></h2>
+<ul>
+<li><p class="first">Find the directory where your <tt class="docutils literal"><span class="pre">Setup</span></tt> file lives (usually in the <tt class="docutils literal"><span class="pre">Modules</span></tt>
+subdirectory) in the Python source hierarchy and copy or symlink the
+<tt class="docutils literal"><span class="pre">pgmodule.c</span></tt> file there.</p>
+</li>
+<li><p class="first">Add the following line to your 'Setup' file:</p>
+<pre class="literal-block">
+_pg pgmodule.c -I$PGINC -I$PSINC -L$PGLIB -lpq
+</pre>
+<p>where:</p>
+<pre class="literal-block">
+PGINC = path to the PostgreSQL client include files (see above)
+PSINC = path to the PostgreSQL server include files (see above)
+PGLIB = path to the PostgreSQL object code libraries (see above)
+</pre>
+<p>Some options may be added to this line:</p>
+<pre class="literal-block">
+-DNO_DEF_VAR no default variables support
+-DNO_DIRECT no direct access methods
+-DNO_LARGE no large object support
+-DNO_PQSOCKET if running an older PostgreSQL (see above)
+</pre>
+<p>On some systems you may need to include <tt class="docutils literal"><span class="pre">-lcrypt</span></tt> in the list of libraries
+to make it compile.</p>
+</li>
+<li><p class="first">If you want a shared module, make sure that the <tt class="docutils literal"><span class="pre">shared</span></tt> keyword is
+uncommented and add the above line below it. You used to need to install
+your shared modules with <tt class="docutils literal"><span class="pre">make</span> <span class="pre">sharedinstall</span></tt> but this no longer seems
+to be true.</p>
+</li>
+<li><p class="first">Copy <tt class="docutils literal"><span class="pre">pg.py</span></tt> to the lib directory where the rest of your modules are.
+For example, that's <tt class="docutils literal"><span class="pre">/usr/local/lib/Python</span></tt> on my system.</p>
+</li>
+<li><p class="first">Rebuild Python from the root directory of the Python source hierarchy by
+running <tt class="docutils literal"><span class="pre">make</span> <span class="pre">-f</span> <span class="pre">Makefile.pre.in</span> <span class="pre">boot</span></tt> and <tt class="docutils literal"><span class="pre">make</span> <span class="pre">&&</span> <span class="pre">make</span> <span class="pre">install</span></tt>.</p>
+</li>
+<li><p class="first">For more details read the documentation at the top of <tt class="docutils literal"><span class="pre">Makefile.pre.in</span></tt>.</p>
+</li>
+</ul>
+</div>
+</div>
+</div>
+</body>
+</html>
[4/9] incubator-hawq git commit: HAWQ-672. Add python module pygresql
back into hawq workspace
Posted by od...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/pg.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/pg.py b/tools/bin/pythonSrc/PyGreSQL-4.0/pg.py
new file mode 100644
index 0000000..53c6669
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/pg.py
@@ -0,0 +1,711 @@
+#!/usr/bin/env python
+#
+# pg.py
+#
+# Written by D'Arcy J.M. Cain
+# Improved by Christoph Zwerschke
+#
+# $Id: pg.py,v 1.77 2008/12/30 16:40:00 darcy Exp $
+#
+
+"""PyGreSQL classic interface.
+
+This pg module implements some basic database management stuff.
+It includes the _pg module and builds on it, providing the higher
+level wrapper class named DB with addtional functionality.
+This is known as the "classic" ("old style") PyGreSQL interface.
+For a DB-API 2 compliant interface use the newer pgdb module.
+
+"""
+
+from _pg import *
+try:
+ frozenset
+except NameError: # Python < 2.4
+ from sets import ImmutableSet as frozenset
+try:
+ from decimal import Decimal
+ set_decimal(Decimal)
+except ImportError:
+ pass # Python < 2.4
+
+
+# Auxiliary functions which are independent from a DB connection:
+
+def _is_quoted(s):
+ """Check whether this string is a quoted identifier."""
+ s = s.replace('_', 'a')
+ return not s.isalnum() or s[:1].isdigit() or s != s.lower()
+
+def _is_unquoted(s):
+ """Check whether this string is an unquoted identifier."""
+ s = s.replace('_', 'a')
+ return s.isalnum() and not s[:1].isdigit()
+
+def _split_first_part(s):
+ """Split the first part of a dot separated string."""
+ s = s.lstrip()
+ if s[:1] == '"':
+ p = []
+ s = s.split('"', 3)[1:]
+ p.append(s[0])
+ while len(s) == 3 and s[1] == '':
+ p.append('"')
+ s = s[2].split('"', 2)
+ p.append(s[0])
+ p = [''.join(p)]
+ s = '"'.join(s[1:]).lstrip()
+ if s:
+ if s[:0] == '.':
+ p.append(s[1:])
+ else:
+ s = _split_first_part(s)
+ p[0] += s[0]
+ if len(s) > 1:
+ p.append(s[1])
+ else:
+ p = s.split('.', 1)
+ s = p[0].rstrip()
+ if _is_unquoted(s):
+ s = s.lower()
+ p[0] = s
+ return p
+
+def _split_parts(s):
+ """Split all parts of a dot separated string."""
+ q = []
+ while s:
+ s = _split_first_part(s)
+ q.append(s[0])
+ if len(s) < 2:
+ break
+ s = s[1]
+ return q
+
+def _join_parts(s):
+ """Join all parts of a dot separated string."""
+ return '.'.join([_is_quoted(p) and '"%s"' % p or p for p in s])
+
+def _oid_key(qcl):
+ """Build oid key from qualified class name."""
+ return 'oid(%s)' % qcl
+
+
+# The PostGreSQL database connection interface:
+
+class DB(object):
+ """Wrapper class for the _pg connection type."""
+
+ def __init__(self, *args, **kw):
+ """Create a new connection.
+
+ You can pass either the connection parameters or an existing
+ _pg or pgdb connection. This allows you to use the methods
+ of the classic pg interface with a DB-API 2 pgdb connection.
+
+ """
+ if not args and len(kw) == 1:
+ db = kw.get('db')
+ elif not kw and len(args) == 1:
+ db = args[0]
+ else:
+ db = None
+ if db:
+ if isinstance(db, DB):
+ db = db.db
+ else:
+ try:
+ db = db._cnx
+ except AttributeError:
+ pass
+ if not db or not hasattr(db, 'db') or not hasattr(db, 'query'):
+ db = connect(*args, **kw)
+ self._closeable = 1
+ else:
+ self._closeable = 0
+ self.db = db
+ self.dbname = db.db
+ self._attnames = {}
+ self._pkeys = {}
+ self._privileges = {}
+ self._args = args, kw
+ self.debug = None # For debugging scripts, this can be set
+ # * to a string format specification (e.g. in CGI set to "%s<BR>"),
+ # * to a file object to write debug statements or
+ # * to a callable object which takes a string argument.
+
+ def __getattr__(self, name):
+ # All undefined members are the same as in the underlying pg connection:
+ if self.db:
+ return getattr(self.db, name)
+ else:
+ raise InternalError('Connection is not valid')
+
+ # Auxiliary methods
+
+ def _do_debug(self, s):
+ """Print a debug message."""
+ if self.debug:
+ if isinstance(self.debug, basestring):
+ print self.debug % s
+ elif isinstance(self.debug, file):
+ print >> self.debug, s
+ elif callable(self.debug):
+ self.debug(s)
+
+ def _quote_text(self, d):
+ """Quote text value."""
+ if not isinstance(d, basestring):
+ d = str(d)
+ return "'%s'" % self.escape_string(d)
+
+ _bool_true = frozenset('t true 1 y yes on'.split())
+
+ def _quote_bool(self, d):
+ """Quote boolean value."""
+ if isinstance(d, basestring):
+ if not d:
+ return 'NULL'
+ d = d.lower() in self._bool_true
+ else:
+ d = bool(d)
+ return ("'f'", "'t'")[d]
+
+ _date_literals = frozenset('current_date current_time'
+ ' current_timestamp localtime localtimestamp'.split())
+
+ def _quote_date(self, d):
+ """Quote date value."""
+ if not d:
+ return 'NULL'
+ if isinstance(d, basestring) and d.lower() in self._date_literals:
+ return d
+ return self._quote_text(d)
+
+ def _quote_num(self, d):
+ """Quote numeric value."""
+ if not d and d != 0:
+ return 'NULL'
+ return str(d)
+
+ def _quote_money(self, d):
+ """Quote money value."""
+ if not d:
+ return 'NULL'
+ return "'%.2f'" % float(d)
+
+ _quote_funcs = dict( # quote methods for each type
+ text=_quote_text, bool=_quote_bool, date=_quote_date,
+ int=_quote_num, num=_quote_num, float=_quote_num,
+ money=_quote_money)
+
+ def _quote(self, d, t):
+ """Return quotes if needed."""
+ if d is None:
+ return 'NULL'
+ try:
+ quote_func = self._quote_funcs[t]
+ except KeyError:
+ quote_func = self._quote_funcs['text']
+ return quote_func(self, d)
+
+ def _split_schema(self, cl):
+ """Return schema and name of object separately.
+
+ This auxiliary function splits off the namespace (schema)
+ belonging to the class with the name cl. If the class name
+ is not qualified, the function is able to determine the schema
+ of the class, taking into account the current search path.
+
+ """
+ s = _split_parts(cl)
+ if len(s) > 1: # name already qualfied?
+ # should be database.schema.table or schema.table
+ if len(s) > 3:
+ raise ProgrammingError('Too many dots in class name %s' % cl)
+ schema, cl = s[-2:]
+ else:
+ cl = s[0]
+ # determine search path
+ q = 'SELECT current_schemas(TRUE)'
+ schemas = self.db.query(q).getresult()[0][0][1:-1].split(',')
+ if schemas: # non-empty path
+ # search schema for this object in the current search path
+ q = ' UNION '.join(
+ ["SELECT %d::integer AS n, '%s'::name AS nspname"
+ % s for s in enumerate(schemas)])
+ q = ("SELECT nspname FROM pg_class"
+ " JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid"
+ " JOIN (%s) AS p USING (nspname)"
+ " WHERE pg_class.relname = '%s'"
+ " ORDER BY n LIMIT 1" % (q, cl))
+ schema = self.db.query(q).getresult()
+ if schema: # schema found
+ schema = schema[0][0]
+ else: # object not found in current search path
+ schema = 'public'
+ else: # empty path
+ schema = 'public'
+ return schema, cl
+
+ def _add_schema(self, cl):
+ """Ensure that the class name is prefixed with a schema name."""
+ return _join_parts(self._split_schema(cl))
+
+ # Public methods
+
+ # escape_string and escape_bytea exist as methods,
+ # so we define unescape_bytea as a method as well
+ unescape_bytea = staticmethod(unescape_bytea)
+
+ def close(self):
+ """Close the database connection."""
+ # Wraps shared library function so we can track state.
+ if self._closeable:
+ if self.db:
+ self.db.close()
+ self.db = None
+ else:
+ raise InternalError('Connection already closed')
+
+ def reset(self):
+ """Reset connection with current parameters.
+
+ All derived queries and large objects derived from this connection
+ will not be usable after this call.
+
+ """
+ self.db.reset()
+
+ def reopen(self):
+ """Reopen connection to the database.
+
+ Used in case we need another connection to the same database.
+ Note that we can still reopen a database that we have closed.
+
+ """
+ # There is no such shared library function.
+ if self._closeable:
+ db = connect(*self._args[0], **self._args[1])
+ if self.db:
+ self.db.close()
+ self.db = db
+
+ def query(self, qstr):
+ """Executes a SQL command string.
+
+ This method simply sends a SQL query to the database. If the query is
+ an insert statement that inserted exactly one row into a table that
+ has OIDs, the return value is the OID of the newly inserted row.
+ If the query is an update or delete statement, or an insert statement
+ that did not insert exactly one row in a table with OIDs, then the
+ numer of rows affected is returned as a string. If it is a statement
+ that returns rows as a result (usually a select statement, but maybe
+ also an "insert/update ... returning" statement), this method returns
+ a pgqueryobject that can be accessed via getresult() or dictresult()
+ or simply printed. Otherwise, it returns `None`.
+
+ """
+ # Wraps shared library function for debugging.
+ if not self.db:
+ raise InternalError('Connection is not valid')
+ self._do_debug(qstr)
+ return self.db.query(qstr)
+
+ def pkey(self, cl, newpkey=None):
+ """This method gets or sets the primary key of a class.
+
+ Composite primary keys are represented as frozensets. Note that
+ this raises an exception if the table does not have a primary key.
+
+ If newpkey is set and is not a dictionary then set that
+ value as the primary key of the class. If it is a dictionary
+ then replace the _pkeys dictionary with a copy of it.
+
+ """
+ # First see if the caller is supplying a dictionary
+ if isinstance(newpkey, dict):
+ # make sure that all classes have a namespace
+ self._pkeys = dict([
+ ('.' in cl and cl or 'public.' + cl, pkey)
+ for cl, pkey in newpkey.iteritems()])
+ return self._pkeys
+
+ qcl = self._add_schema(cl) # build fully qualified class name
+ # Check if the caller is supplying a new primary key for the class
+ if newpkey:
+ self._pkeys[qcl] = newpkey
+ return newpkey
+
+ # Get all the primary keys at once
+ if qcl not in self._pkeys:
+ # if not found, check again in case it was added after we started
+ self._pkeys = {}
+ if self.server_version >= 80200:
+ # the ANY syntax works correctly only with PostgreSQL >= 8.2
+ any_indkey = "= ANY (pg_index.indkey)"
+ else:
+ any_indkey = "IN (%s)" % ', '.join(
+ ['pg_index.indkey[%d]' % i for i in range(16)])
+ for r in self.db.query(
+ "SELECT pg_namespace.nspname, pg_class.relname,"
+ " pg_attribute.attname FROM pg_class"
+ " JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace"
+ " AND pg_namespace.nspname NOT LIKE 'pg_%'"
+ " JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid"
+ " AND pg_attribute.attisdropped = 'f'"
+ " JOIN pg_index ON pg_index.indrelid = pg_class.oid"
+ " AND pg_index.indisprimary = 't'"
+ " AND pg_attribute.attnum " + any_indkey).getresult():
+ cl, pkey = _join_parts(r[:2]), r[2]
+ self._pkeys.setdefault(cl, []).append(pkey)
+ # (only) for composite primary keys, the values will be frozensets
+ for cl, pkey in self._pkeys.iteritems():
+ self._pkeys[cl] = len(pkey) > 1 and frozenset(pkey) or pkey[0]
+ self._do_debug(self._pkeys)
+
+ # will raise an exception if primary key doesn't exist
+ return self._pkeys[qcl]
+
+ def get_databases(self):
+ """Get list of databases in the system."""
+ return [s[0] for s in
+ self.db.query('SELECT datname FROM pg_database').getresult()]
+
+ def get_relations(self, kinds=None):
+ """Get list of relations in connected database of specified kinds.
+
+ If kinds is None or empty, all kinds of relations are returned.
+ Otherwise kinds can be a string or sequence of type letters
+ specifying which kind of relations you want to list.
+
+ """
+ where = kinds and "pg_class.relkind IN (%s) AND" % ','.join(
+ ["'%s'" % x for x in kinds]) or ''
+ return map(_join_parts, self.db.query(
+ "SELECT pg_namespace.nspname, pg_class.relname "
+ "FROM pg_class "
+ "JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace "
+ "WHERE %s pg_class.relname !~ '^Inv' AND "
+ "pg_class.relname !~ '^pg_' "
+ "ORDER BY 1, 2" % where).getresult())
+
+ def get_tables(self):
+ """Return list of tables in connected database."""
+ return self.get_relations('r')
+
+ def get_attnames(self, cl, newattnames=None):
+ """Given the name of a table, digs out the set of attribute names.
+
+ Returns a dictionary of attribute names (the names are the keys,
+ the values are the names of the attributes' types).
+ If the optional newattnames exists, it must be a dictionary and
+ will become the new attribute names dictionary.
+
+ """
+ if isinstance(newattnames, dict):
+ self._attnames = newattnames
+ return
+ elif newattnames:
+ raise ProgrammingError(
+ 'If supplied, newattnames must be a dictionary')
+ cl = self._split_schema(cl) # split into schema and class
+ qcl = _join_parts(cl) # build fully qualified name
+ # May as well cache them:
+ if qcl in self._attnames:
+ return self._attnames[qcl]
+ if qcl not in self.get_relations('rv'):
+ raise ProgrammingError('Class %s does not exist' % qcl)
+ t = {}
+ for att, typ in self.db.query("SELECT pg_attribute.attname,"
+ " pg_type.typname FROM pg_class"
+ " JOIN pg_namespace ON pg_class.relnamespace = pg_namespace.oid"
+ " JOIN pg_attribute ON pg_attribute.attrelid = pg_class.oid"
+ " JOIN pg_type ON pg_type.oid = pg_attribute.atttypid"
+ " WHERE pg_namespace.nspname = '%s' AND pg_class.relname = '%s'"
+ " AND (pg_attribute.attnum > 0 or pg_attribute.attname = 'oid')"
+ " AND pg_attribute.attisdropped = 'f'"
+ % cl).getresult():
+ if typ.startswith('bool'):
+ t[att] = 'bool'
+ elif typ.startswith('abstime'):
+ t[att] = 'date'
+ elif typ.startswith('date'):
+ t[att] = 'date'
+ elif typ.startswith('interval'):
+ t[att] = 'date'
+ elif typ.startswith('timestamp'):
+ t[att] = 'date'
+ elif typ.startswith('oid'):
+ t[att] = 'int'
+ elif typ.startswith('int'):
+ t[att] = 'int'
+ elif typ.startswith('float'):
+ t[att] = 'float'
+ elif typ.startswith('numeric'):
+ t[att] = 'num'
+ elif typ.startswith('money'):
+ t[att] = 'money'
+ else:
+ t[att] = 'text'
+ self._attnames[qcl] = t # cache it
+ return self._attnames[qcl]
+
+ def has_table_privilege(self, cl, privilege='select'):
+ """Check whether current user has specified table privilege."""
+ qcl = self._add_schema(cl)
+ privilege = privilege.lower()
+ try:
+ return self._privileges[(qcl, privilege)]
+ except KeyError:
+ q = "SELECT has_table_privilege('%s', '%s')" % (qcl, privilege)
+ ret = self.db.query(q).getresult()[0][0] == 't'
+ self._privileges[(qcl, privilege)] = ret
+ return ret
+
+ def get(self, cl, arg, keyname=None):
+ """Get a tuple from a database table or view.
+
+ This method is the basic mechanism to get a single row. The keyname
+ that the key specifies a unique row. If keyname is not specified
+ then the primary key for the table is used. If arg is a dictionary
+ then the value for the key is taken from it and it is modified to
+ include the new values, replacing existing values where necessary.
+ For a composite key, keyname can also be a sequence of key names.
+ The OID is also put into the dictionary if the table has one, but
+ in order to allow the caller to work with multiple tables, it is
+ munged as oid(schema.table).
+
+ """
+ if cl.endswith('*'): # scan descendant tables?
+ cl = cl[:-1].rstrip() # need parent table name
+ # build qualified class name
+ qcl = self._add_schema(cl)
+ # To allow users to work with multiple tables,
+ # we munge the name of the "oid" the key
+ qoid = _oid_key(qcl)
+ if not keyname:
+ # use the primary key by default
+ try:
+ keyname = self.pkey(qcl)
+ except KeyError:
+ raise ProgrammingError('Class %s has no primary key' % qcl)
+ # We want the oid for later updates if that isn't the key
+ if keyname == 'oid':
+ if isinstance(arg, dict):
+ if qoid not in arg:
+ raise ProgrammingError('%s not in arg' % qoid)
+ else:
+ arg = {qoid: arg}
+ where = 'oid = %s' % arg[qoid]
+ attnames = '*'
+ else:
+ attnames = self.get_attnames(qcl)
+ if isinstance(keyname, basestring):
+ keyname = (keyname,)
+ if not isinstance(arg, dict):
+ if len(keyname) > 1:
+ raise ProgrammingError('Composite key needs dict as arg')
+ arg = dict([(k, arg) for k in keyname])
+ where = ' AND '.join(['%s = %s'
+ % (k, self._quote(arg[k], attnames[k])) for k in keyname])
+ attnames = ', '.join(attnames)
+ q = 'SELECT %s FROM %s WHERE %s LIMIT 1' % (attnames, qcl, where)
+ self._do_debug(q)
+ res = self.db.query(q).dictresult()
+ if not res:
+ raise DatabaseError('No such record in %s where %s' % (qcl, where))
+ for att, value in res[0].iteritems():
+ arg[att == 'oid' and qoid or att] = value
+ return arg
+
+ def insert(self, cl, d=None, **kw):
+ """Insert a tuple into a database table.
+
+ This method inserts a row into a table. If a dictionary is
+ supplied it starts with that. Otherwise it uses a blank dictionary.
+ Either way the dictionary is updated from the keywords.
+
+ The dictionary is then, if possible, reloaded with the values actually
+ inserted in order to pick up values modified by rules, triggers, etc.
+
+ Note: The method currently doesn't support insert into views
+ although PostgreSQL does.
+
+ """
+ qcl = self._add_schema(cl)
+ qoid = _oid_key(qcl)
+ if d is None:
+ d = {}
+ d.update(kw)
+ attnames = self.get_attnames(qcl)
+ names, values = [], []
+ for n in attnames:
+ if n != 'oid' and n in d:
+ names.append('"%s"' % n)
+ values.append(self._quote(d[n], attnames[n]))
+ names, values = ', '.join(names), ', '.join(values)
+ selectable = self.has_table_privilege(qcl)
+ if selectable and self.server_version >= 80200:
+ ret = ' RETURNING %s*' % ('oid' in attnames and 'oid, ' or '')
+ else:
+ ret = ''
+ q = 'INSERT INTO %s (%s) VALUES (%s)%s' % (qcl, names, values, ret)
+ self._do_debug(q)
+ res = self.db.query(q)
+ if ret:
+ res = res.dictresult()
+ for att, value in res[0].iteritems():
+ d[att == 'oid' and qoid or att] = value
+ elif isinstance(res, int):
+ d[qoid] = res
+ if selectable:
+ self.get(qcl, d, 'oid')
+ elif selectable:
+ if qoid in d:
+ self.get(qcl, d, 'oid')
+ else:
+ try:
+ self.get(qcl, d)
+ except ProgrammingError:
+ pass # table has no primary key
+ return d
+
+ def update(self, cl, d=None, **kw):
+ """Update an existing row in a database table.
+
+ Similar to insert but updates an existing row. The update is based
+ on the OID value as munged by get or passed as keyword, or on the
+ primary key of the table. The dictionary is modified, if possible,
+ to reflect any changes caused by the update due to triggers, rules,
+ default values, etc.
+
+ """
+ # Update always works on the oid which get returns if available,
+ # otherwise use the primary key. Fail if neither.
+ # Note that we only accept oid key from named args for safety
+ qcl = self._add_schema(cl)
+ qoid = _oid_key(qcl)
+ if 'oid' in kw:
+ kw[qoid] = kw['oid']
+ del kw['oid']
+ if d is None:
+ d = {}
+ d.update(kw)
+ attnames = self.get_attnames(qcl)
+ if qoid in d:
+ where = 'oid = %s' % d[qoid]
+ keyname = ()
+ else:
+ try:
+ keyname = self.pkey(qcl)
+ except KeyError:
+ raise ProgrammingError('Class %s has no primary key' % qcl)
+ if isinstance(keyname, basestring):
+ keyname = (keyname,)
+ try:
+ where = ' AND '.join(['%s = %s'
+ % (k, self._quote(d[k], attnames[k])) for k in keyname])
+ except KeyError:
+ raise ProgrammingError('Update needs primary key or oid.')
+ values = []
+ for n in attnames:
+ if n in d and n not in keyname:
+ values.append('%s = %s' % (n, self._quote(d[n], attnames[n])))
+ if not values:
+ return d
+ values = ', '.join(values)
+ selectable = self.has_table_privilege(qcl)
+ if selectable and self.server_version >= 880200:
+ ret = ' RETURNING %s*' % ('oid' in attnames and 'oid, ' or '')
+ else:
+ ret = ''
+ q = 'UPDATE %s SET %s WHERE %s%s' % (qcl, values, where, ret)
+ self._do_debug(q)
+ res = self.db.query(q)
+ if ret:
+ res = self.db.query(q).dictresult()
+ for att, value in res[0].iteritems():
+ d[att == 'oid' and qoid or att] = value
+ else:
+ self.db.query(q)
+ if selectable:
+ if qoid in d:
+ self.get(qcl, d, 'oid')
+ else:
+ self.get(qcl, d)
+ return d
+
+ def clear(self, cl, a=None):
+ """
+
+ This method clears all the attributes to values determined by the types.
+ Numeric types are set to 0, Booleans are set to 'f', and everything
+ else is set to the empty string. If the array argument is present,
+ it is used as the array and any entries matching attribute names are
+ cleared with everything else left unchanged.
+
+ """
+ # At some point we will need a way to get defaults from a table.
+ qcl = self._add_schema(cl)
+ if a is None:
+ a = {} # empty if argument is not present
+ attnames = self.get_attnames(qcl)
+ for n, t in attnames.iteritems():
+ if n == 'oid':
+ continue
+ if t in ('int', 'float', 'num', 'money'):
+ a[n] = 0
+ elif t == 'bool':
+ a[n] = 'f'
+ else:
+ a[n] = ''
+ return a
+
+ def delete(self, cl, d=None, **kw):
+ """Delete an existing row in a database table.
+
+ This method deletes the row from a table. It deletes based on the
+ OID value as munged by get or passed as keyword, or on the primary
+ key of the table. The return value is the number of deleted rows
+ (i.e. 0 if the row did not exist and 1 if the row was deleted).
+
+ """
+ # Like update, delete works on the oid.
+ # One day we will be testing that the record to be deleted
+ # isn't referenced somewhere (or else PostgreSQL will).
+ # Note that we only accept oid key from named args for safety
+ qcl = self._add_schema(cl)
+ qoid = _oid_key(qcl)
+ if 'oid' in kw:
+ kw[qoid] = kw['oid']
+ del kw['oid']
+ if d is None:
+ d = {}
+ d.update(kw)
+ if qoid in d:
+ where = 'oid = %s' % d[qoid]
+ else:
+ try:
+ keyname = self.pkey(qcl)
+ except KeyError:
+ raise ProgrammingError('Class %s has no primary key' % qcl)
+ if isinstance(keyname, basestring):
+ keyname = (keyname,)
+ attnames = self.get_attnames(qcl)
+ try:
+ where = ' AND '.join(['%s = %s'
+ % (k, self._quote(d[k], attnames[k])) for k in keyname])
+ except KeyError:
+ raise ProgrammingError('Delete needs primary key or oid.')
+ q = 'DELETE FROM %s WHERE %s' % (qcl, where)
+ self._do_debug(q)
+ return int(self.db.query(q))
+
+
+# if run as script, print some information
+
+if __name__ == '__main__':
+ print 'PyGreSQL version', version
+ print
+ print __doc__
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/pgdb.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/pgdb.py b/tools/bin/pythonSrc/PyGreSQL-4.0/pgdb.py
new file mode 100644
index 0000000..4b4344c
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/pgdb.py
@@ -0,0 +1,582 @@
+#!/usr/bin/env python
+#
+# pgdb.py
+#
+# Written by D'Arcy J.M. Cain
+#
+# $Id: pgdb.py,v 1.54 2008/11/23 14:32:18 cito Exp $
+#
+
+"""pgdb - DB-API 2.0 compliant module for PygreSQL.
+
+(c) 1999, Pascal Andre <an...@via.ecp.fr>.
+See package documentation for further information on copyright.
+
+Inline documentation is sparse.
+See DB-API 2.0 specification for usage information:
+http://www.python.org/peps/pep-0249.html
+
+Basic usage:
+
+ pgdb.connect(connect_string) # open a connection
+ # connect_string = 'host:database:user:password:opt:tty'
+ # All parts are optional. You may also pass host through
+ # password as keyword arguments. To pass a port,
+ # pass it in the host keyword parameter:
+ pgdb.connect(host='localhost:5432')
+
+ connection.cursor() # open a cursor
+
+ cursor.execute(query[, params])
+ # Execute a query, binding params (a dictionary) if they are
+ # passed. The binding syntax is the same as the % operator
+ # for dictionaries, and no quoting is done.
+
+ cursor.executemany(query, list of params)
+ # Execute a query many times, binding each param dictionary
+ # from the list.
+
+ cursor.fetchone() # fetch one row, [value, value, ...]
+
+ cursor.fetchall() # fetch all rows, [[value, value, ...], ...]
+
+ cursor.fetchmany([size])
+ # returns size or cursor.arraysize number of rows,
+ # [[value, value, ...], ...] from result set.
+ # Default cursor.arraysize is 1.
+
+ cursor.description # returns information about the columns
+ # [(column_name, type_name, display_size,
+ # internal_size, precision, scale, null_ok), ...]
+ # Note that precision, scale and null_ok are not implemented.
+
+ cursor.rowcount # number of rows available in the result set
+ # Available after a call to execute.
+
+ connection.commit() # commit transaction
+
+ connection.rollback() # or rollback transaction
+
+ cursor.close() # close the cursor
+
+ connection.close() # close the connection
+
+"""
+
+from _pg import *
+import time
+try:
+ frozenset
+except NameError: # Python < 2.4
+ from sets import ImmutableSet as frozenset
+from datetime import datetime, timedelta
+try: # use Decimal if available
+ from decimal import Decimal
+ set_decimal(Decimal)
+except ImportError: # otherwise (Python < 2.4)
+ Decimal = float # use float instead of Decimal
+
+
+### Module Constants
+
+# compliant with DB SIG 2.0
+apilevel = '2.0'
+
+# module may be shared, but not connections
+threadsafety = 1
+
+# this module use extended python format codes
+paramstyle = 'pyformat'
+
+
+### Internal Types Handling
+
+def decimal_type(decimal_type=None):
+ """Get or set global type to be used for decimal values."""
+ global Decimal
+ if decimal_type is not None:
+ Decimal = decimal_type
+ set_decimal(decimal_type)
+ return Decimal
+
+
+def _cast_bool(value):
+ return value[:1] in ['t', 'T']
+
+
+def _cast_money(value):
+ return Decimal(''.join(filter(
+ lambda v: v in '0123456789.-', value)))
+
+
+_cast = {'bool': _cast_bool,
+ 'int2': int, 'int4': int, 'serial': int,
+ 'int8': long, 'oid': long, 'oid8': long,
+ 'float4': float, 'float8': float,
+ 'numeric': Decimal, 'money': _cast_money}
+
+
+class pgdbTypeCache(dict):
+ """Cache for database types."""
+
+ def __init__(self, cnx):
+ """Initialize type cache for connection."""
+ super(pgdbTypeCache, self).__init__()
+ self._src = cnx.source()
+
+ def typecast(typ, value):
+ """Cast value to database type."""
+ if value is None:
+ # for NULL values, no typecast is necessary
+ return None
+ cast = _cast.get(typ)
+ if cast is None:
+ # no typecast available or necessary
+ return value
+ else:
+ return cast(value)
+ typecast = staticmethod(typecast)
+
+ def getdescr(self, oid):
+ """Get name of database type with given oid."""
+ try:
+ return self[oid]
+ except KeyError:
+ self._src.execute(
+ "SELECT typname, typlen "
+ "FROM pg_type WHERE oid=%s" % oid)
+ res = self._src.fetch(1)[0]
+ # The column name is omitted from the return value.
+ # It will have to be prepended by the caller.
+ res = (res[0], None, int(res[1]),
+ None, None, None)
+ self[oid] = res
+ return res
+
+
+class _quotedict(dict):
+ """Dictionary with auto quoting of its items.
+
+ The quote attribute must be set to the desired quote function.
+
+ """
+
+ def __getitem__(self, key):
+ return self.quote(super(_quotedict, self).__getitem__(key))
+
+
+### Cursor Object
+
+class pgdbCursor(object):
+ """Cursor Object."""
+
+ def __init__(self, dbcnx):
+ """Create a cursor object for the database connection."""
+ self.connection = self._dbcnx = dbcnx
+ self._cnx = dbcnx._cnx
+ self._type_cache = dbcnx._type_cache
+ self._src = self._cnx.source()
+ self.description = None
+ self.rowcount = -1
+ self.arraysize = 1
+ self.lastrowid = None
+
+ def __iter__(self):
+ """Return self to make cursors compatible to the iteration protocol."""
+ return self
+
+ def _quote(self, val):
+ """Quote value depending on its type."""
+ if isinstance(val, datetime):
+ val = str(val)
+ elif isinstance(val, unicode):
+ val = val.encode( 'utf8' )
+ if isinstance(val, str):
+ val = "'%s'" % self._cnx.escape_string(val)
+ elif isinstance(val, (int, long, float)):
+ pass
+ elif val is None:
+ val = 'NULL'
+ elif isinstance(val, (list, tuple)):
+ val = '(%s)' % ','.join(map(lambda v: str(self._quote(v)), val))
+ elif Decimal is not float and isinstance(val, Decimal):
+ pass
+ elif hasattr(val, '__pg_repr__'):
+ val = val.__pg_repr__()
+ else:
+ raise InterfaceError(
+ 'do not know how to handle type %s' % type(val))
+ return val
+
+ def _quoteparams(self, string, params):
+ """Quote parameters.
+
+ This function works for both mappings and sequences.
+
+ """
+ if isinstance(params, dict):
+ params = _quotedict(params)
+ params.quote = self._quote
+ else:
+ params = tuple(map(self._quote, params))
+ return string % params
+
+ def row_factory(row):
+ """Process rows before they are returned.
+
+ You can overwrite this with a custom row factory,
+ e.g. a dict factory:
+
+ class myCursor(pgdb.pgdbCursor):
+ def cursor.row_factory(self, row):
+ d = {}
+ for idx, col in enumerate(self.description):
+ d[col[0]] = row[idx]
+ return d
+ cursor = myCursor(cnx)
+
+ """
+ return row
+ row_factory = staticmethod(row_factory)
+
+ def close(self):
+ """Close the cursor object."""
+ self._src.close()
+ self.description = None
+ self.rowcount = -1
+ self.lastrowid = None
+
+ def execute(self, operation, params=None):
+ """Prepare and execute a database operation (query or command)."""
+ # The parameters may also be specified as list of
+ # tuples to e.g. insert multiple rows in a single
+ # operation, but this kind of usage is deprecated:
+ if (params and isinstance(params, list)
+ and isinstance(params[0], tuple)):
+ self.executemany(operation, params)
+ else:
+ # not a list of tuples
+ self.executemany(operation, (params,))
+
+ def executemany(self, operation, param_seq):
+ """Prepare operation and execute it against a parameter sequence."""
+ if not param_seq:
+ # don't do anything without parameters
+ return
+ self.description = None
+ self.rowcount = -1
+ # first try to execute all queries
+ totrows = 0
+ sql = "BEGIN"
+ try:
+ if not self._dbcnx._tnx:
+ try:
+ self._cnx.source().execute(sql)
+ except Exception:
+ raise OperationalError("can't start transaction")
+ self._dbcnx._tnx = True
+ for params in param_seq:
+ if params:
+ sql = self._quoteparams(operation, params)
+ else:
+ sql = operation
+ rows = self._src.execute(sql)
+ if rows: # true if not DML
+ totrows += rows
+ else:
+ self.rowcount = -1
+ except Error, msg:
+ raise DatabaseError("error '%s' in '%s'" % (msg, sql))
+ except Exception, err:
+ raise OperationalError("internal error in '%s': %s" % (sql, err))
+ # then initialize result raw count and description
+ if self._src.resulttype == RESULT_DQL:
+ self.rowcount = self._src.ntuples
+ getdescr = self._type_cache.getdescr
+ coltypes = self._src.listinfo()
+ self.description = [typ[1:2] + getdescr(typ[2]) for typ in coltypes]
+ self.lastrowid = self._src.oidstatus()
+ else:
+ self.rowcount = totrows
+ self.description = None
+ self.lastrowid = self._src.oidstatus()
+
+ def fetchone(self):
+ """Fetch the next row of a query result set."""
+ res = self.fetchmany(1, False)
+ try:
+ return res[0]
+ except IndexError:
+ return None
+
+ def fetchall(self):
+ """Fetch all (remaining) rows of a query result."""
+ return self.fetchmany(-1, False)
+
+ def fetchmany(self, size=None, keep=False):
+ """Fetch the next set of rows of a query result.
+
+ The number of rows to fetch per call is specified by the
+ size parameter. If it is not given, the cursor's arraysize
+ determines the number of rows to be fetched. If you set
+ the keep parameter to true, this is kept as new arraysize.
+
+ """
+ if size is None:
+ size = self.arraysize
+ if keep:
+ self.arraysize = size
+ try:
+ result = self._src.fetch(size)
+ except Error, err:
+ raise DatabaseError(str(err))
+ row_factory = self.row_factory
+ typecast = self._type_cache.typecast
+ coltypes = [desc[1] for desc in self.description]
+ return [row_factory([typecast(*args)
+ for args in zip(coltypes, row)]) for row in result]
+
+ def next(self):
+ """Return the next row (support for the iteration protocol)."""
+ res = self.fetchone()
+ if res is None:
+ raise StopIteration
+ return res
+
+ def nextset():
+ """Not supported."""
+ raise NotSupportedError("nextset() is not supported")
+ nextset = staticmethod(nextset)
+
+ def setinputsizes(sizes):
+ """Not supported."""
+ pass
+ setinputsizes = staticmethod(setinputsizes)
+
+ def setoutputsize(size, column=0):
+ """Not supported."""
+ pass
+ setoutputsize = staticmethod(setoutputsize)
+
+
+### Connection Objects
+
+class pgdbCnx(object):
+ """Connection Object."""
+
+ # expose the exceptions as attributes on the connection object
+ Error = Error
+ Warning = Warning
+ InterfaceError = InterfaceError
+ DatabaseError = DatabaseError
+ InternalError = InternalError
+ OperationalError = OperationalError
+ ProgrammingError = ProgrammingError
+ IntegrityError = IntegrityError
+ DataError = DataError
+ NotSupportedError = NotSupportedError
+
+ def __init__(self, cnx):
+ """Create a database connection object."""
+ self._cnx = cnx # connection
+ self._tnx = False # transaction state
+ self._type_cache = pgdbTypeCache(cnx)
+ try:
+ self._cnx.source()
+ except Exception:
+ raise OperationalError("invalid connection")
+
+ def close(self):
+ """Close the connection object."""
+ if self._cnx:
+ self._cnx.close()
+ self._cnx = None
+ else:
+ raise OperationalError("connection has been closed")
+
+ def commit(self):
+ """Commit any pending transaction to the database."""
+ if self._cnx:
+ if self._tnx:
+ self._tnx = False
+ try:
+ self._cnx.source().execute("COMMIT")
+ except Exception:
+ raise OperationalError("can't commit")
+ else:
+ raise OperationalError("connection has been closed")
+
+ def rollback(self):
+ """Roll back to the start of any pending transaction."""
+ if self._cnx:
+ if self._tnx:
+ self._tnx = False
+ try:
+ self._cnx.source().execute("ROLLBACK")
+ except Exception:
+ raise OperationalError("can't rollback")
+ else:
+ raise OperationalError("connection has been closed")
+
+ def cursor(self):
+ """Return a new Cursor Object using the connection."""
+ if self._cnx:
+ try:
+ return pgdbCursor(self)
+ except Exception:
+ raise OperationalError("invalid connection")
+ else:
+ raise OperationalError("connection has been closed")
+
+
+### Module Interface
+
+_connect_ = connect
+
+def connect(dsn=None,
+ user=None, password=None,
+ host=None, database=None):
+ """Connects to a database."""
+ # first get params from DSN
+ dbport = -1
+ dbhost = ""
+ dbbase = ""
+ dbuser = ""
+ dbpasswd = ""
+ dbopt = ""
+ dbtty = ""
+ try:
+ params = dsn.split(":")
+ dbhost = params[0]
+ dbport = int(params[1])
+ dbbase = params[2]
+ dbuser = params[3]
+ dbpasswd = params[4]
+ dbopt = params[5]
+ dbtty = params[6]
+ except (AttributeError, IndexError, TypeError):
+ pass
+
+ # override if necessary
+ if user is not None:
+ dbuser = user
+ if password is not None:
+ dbpasswd = password
+ if database is not None:
+ dbbase = database
+ if host is not None:
+ try:
+ params = host.split(":")
+ dbhost = params[0]
+ dbport = int(params[1])
+ except (AttributeError, IndexError, TypeError, ValueError):
+ pass
+
+ # empty host is localhost
+ if dbhost == "":
+ dbhost = None
+ if dbuser == "":
+ dbuser = None
+
+ # open the connection
+ cnx = _connect_(dbbase, dbhost, dbport, dbopt,
+ dbtty, dbuser, dbpasswd)
+ return pgdbCnx(cnx)
+
+
+### Types Handling
+
+class pgdbType(frozenset):
+ """Type class for a couple of PostgreSQL data types.
+
+ PostgreSQL is object-oriented: types are dynamic.
+ We must thus use type names as internal type codes.
+
+ """
+
+ if frozenset.__module__ == '__builtin__':
+ def __new__(cls, values):
+ if isinstance(values, basestring):
+ values = values.split()
+ return super(pgdbType, cls).__new__(cls, values)
+ else: # Python < 2.4
+ def __init__(self, values):
+ if isinstance(values, basestring):
+ values = values.split()
+ super(pgdbType, self).__init__(values)
+
+ def __eq__(self, other):
+ if isinstance(other, basestring):
+ return other in self
+ else:
+ return super(pgdbType, self).__eq__(other)
+
+ def __ne__(self, other):
+ if isinstance(other, basestring):
+ return other not in self
+ else:
+ return super(pgdbType, self).__ne__(other)
+
+
+# Mandatory type objects defined by DB-API 2 specs:
+
+STRING = pgdbType('char bpchar name text varchar')
+BINARY = pgdbType('bytea')
+NUMBER = pgdbType('int2 int4 serial int8 float4 float8 numeric money')
+DATETIME = pgdbType('date time timetz timestamp timestamptz datetime abstime'
+ ' interval tinterval timespan reltime')
+ROWID = pgdbType('oid oid8')
+
+
+# Additional type objects (more specific):
+
+BOOL = pgdbType('bool')
+SMALLINT = pgdbType('int2')
+INTEGER = pgdbType('int2 int4 int8 serial')
+LONG = pgdbType('int8')
+FLOAT = pgdbType('float4 float8')
+NUMERIC = pgdbType('numeric')
+MONEY = pgdbType('money')
+DATE = pgdbType('date')
+TIME = pgdbType('time timetz')
+TIMESTAMP = pgdbType('timestamp timestamptz datetime abstime')
+INTERVAL = pgdbType('interval tinterval timespan reltime')
+
+
+# Mandatory type helpers defined by DB-API 2 specs:
+
+def Date(year, month, day):
+ """Construct an object holding a date value."""
+ return datetime(year, month, day)
+
+def Time(hour, minute, second):
+ """Construct an object holding a time value."""
+ return timedelta(hour, minute, second)
+
+def Timestamp(year, month, day, hour, minute, second):
+ """construct an object holding a time stamp value."""
+ return datetime(year, month, day, hour, minute, second)
+
+def DateFromTicks(ticks):
+ """Construct an object holding a date value from the given ticks value."""
+ return Date(*time.localtime(ticks)[:3])
+
+def TimeFromTicks(ticks):
+ """construct an object holding a time value from the given ticks value."""
+ return Time(*time.localtime(ticks)[3:6])
+
+def TimestampFromTicks(ticks):
+ """construct an object holding a time stamp from the given ticks value."""
+ return Timestamp(*time.localtime(ticks)[:6])
+
+def Binary(value):
+ """construct an object capable of holding a binary (long) string value."""
+ return value
+
+
+# If run as script, print some information:
+
+if __name__ == '__main__':
+ print 'PyGreSQL version', version
+ print
+ print __doc__
[7/9] incubator-hawq git commit: HAWQ-672. Add python module pygresql
back into hawq workspace
Posted by od...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.txt
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.txt b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.txt
new file mode 100644
index 0000000..3f19a2c
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/install.txt
@@ -0,0 +1,188 @@
+=====================
+PyGreSQL Installation
+=====================
+
+.. sectnum::
+.. contents:: Contents
+
+
+General
+=======
+
+You must first have installed Python and PostgreSQL on your system.
+If you want to access remote database only, you don't need to install
+the full PostgreSQL server, but only the C interface (libpq). If you
+are on Windows, make sure that the directory with libpq.dll is in your
+``PATH`` environment variable.
+
+The current version of PyGreSQL has been tested with Python 2.5 and
+PostGreSQL 8.3. Older version should work as well, but you will need
+at least Python 2.3 and PostgreSQL 7.4.
+
+PyGreSQL will be installed as three modules, a dynamic module called
+_pg.pyd, and two pure Python wrapper modules called pg.py and pgdb.py.
+All three files will be installed directly into the Python site-packages
+directory. To uninstall PyGreSQL, simply remove these three files again.
+
+
+Installing from a Binary Distribution
+=====================================
+
+This is the easiest way to install PyGreSQL.
+
+You can currently download PyGreSQL as Linux RPM, NetBSD package and Windows
+installer. Make sure the required Python version of the binary package matches
+the Python version you have installed.
+
+Install the package as usual on your system.
+
+Note that the documentation is currently only included in the source package.
+
+
+Installing from Source
+======================
+
+If you want to install PyGreSQL from Source, or there is no binary
+package available for your platform, follow these instructions.
+
+Make sure the Python header files and PostgreSQL client and server header
+files are installed. These come usually with the "devel" packages on Unix
+systems and the installer executables on Windows systems.
+
+If you are using a precompiled PostgreSQL, you will also need the pg_config
+tool. This is usually also part of the "devel" package on Unix, and will be
+installed as part of the database server feature on Windows systems.
+
+Building and installing with Distutils
+--------------------------------------
+
+You can build and install PyGreSQL using
+`Distutils <http://docs.python.org/install/>`_.
+
+Download and unpack the PyGreSQL source tarball if you haven't already done so.
+
+Type the following commands to build and install PyGreSQL::
+
+ python setup.py build
+ python setup.py install
+
+If you are using `MinGW <http://www.mingw.org>`_ to build PyGreSQL under
+Microsoft Windows, please note that Python newer version 2.3 is using msvcr71
+instead of msvcrt as its common runtime library. You can allow for that by
+editing the file ``%MinGWpath%/lib/gcc/%MinGWversion%/specs`` and changing
+the entry that reads ``-lmsvcrt`` to ``-lmsvcr71``. You may also need to copy
+``libpq.lib`` to ``libpq.a`` in the PostgreSQL ``lib`` directory. Then use
+the following command to build and install PyGreSQL::
+
+ python setup.py build -c mingw32 install
+
+Now you should be ready to use PyGreSQL.
+
+Compiling Manually
+------------------
+
+The source file for compiling the dynamic module is called pgmodule.c.
+You have two options. You can compile PyGreSQL as a stand-alone module
+or you can build it into the Python interpreter.
+
+Stand-Alone
+-----------
+
+* In the directory containing ``pgmodule.c``, run the following command::
+
+ cc -fpic -shared -o _pg.so -I$PYINC -I$PGINC -I$PSINC -L$PGLIB -lpq pgmodule.c
+
+ where you have to set::
+
+ PYINC = path to the Python include files
+ (usually something like /usr/include/python)
+ PGINC = path to the PostgreSQL client include files
+ (something like /usr/include/pgsql or /usr/include/postgresql)
+ PSINC = path to the PostgreSQL server include files
+ (like /usr/include/pgsql/server or /usr/include/postgresql/server)
+ PGLIB = path to the PostgreSQL object code libraries (usually /usr/lib)
+
+ If you are not sure about the above paths, try something like::
+
+ PYINC=`find /usr -name Python.h`
+ PGINC=`find /usr -name libpq-fe.h`
+ PSINC=`find /usr -name postgres.h`
+ PGLIB=`find /usr -name libpq.so`
+
+ If you have the ``pg_config`` tool installed, you can set::
+
+ PGINC=`pg_config --includedir`
+ PSINC=`pg_config --includedir-server`
+ PGLIB=`pg_config --libdir`
+
+ Some options may be added to this line::
+
+ -DNO_DEF_VAR no default variables support
+ -DNO_DIRECT no direct access methods
+ -DNO_LARGE no large object support
+ -DNO_PQSOCKET if running an older PostgreSQL
+
+ Define ``NO_PQSOCKET`` if you are using a version of PostgreSQL before 6.4
+ that does not have the PQsocket function. The other options will be
+ described in the next sections.
+
+ On some systems you may need to include ``-lcrypt`` in the list of libraries
+ to make it compile.
+
+* Test the new module. Something like the following should work::
+
+ $ python
+
+ >>> import _pg
+ >>> db = _pg.connect('thilo','localhost')
+ >>> db.query("INSERT INTO test VALUES ('ping','pong')")
+ 18304
+ >>> db.query("SELECT * FROM test")
+ eins|zwei
+ ----+----
+ ping|pong
+ (1 row)
+
+* Finally, move the ``_pg.so``, ``pg.py``, and ``pgdb.py`` to a directory in
+ your ``PYTHONPATH``. A good place would be ``/usr/lib/python/site-packages``
+ if your Python modules are in ``/usr/lib/python``.
+
+Built-in to Python interpreter
+------------------------------
+
+* Find the directory where your ``Setup`` file lives (usually in the ``Modules``
+ subdirectory) in the Python source hierarchy and copy or symlink the
+ ``pgmodule.c`` file there.
+
+* Add the following line to your 'Setup' file::
+
+ _pg pgmodule.c -I$PGINC -I$PSINC -L$PGLIB -lpq
+
+ where::
+
+ PGINC = path to the PostgreSQL client include files (see above)
+ PSINC = path to the PostgreSQL server include files (see above)
+ PGLIB = path to the PostgreSQL object code libraries (see above)
+
+ Some options may be added to this line::
+
+ -DNO_DEF_VAR no default variables support
+ -DNO_DIRECT no direct access methods
+ -DNO_LARGE no large object support
+ -DNO_PQSOCKET if running an older PostgreSQL (see above)
+
+ On some systems you may need to include ``-lcrypt`` in the list of libraries
+ to make it compile.
+
+* If you want a shared module, make sure that the ``shared`` keyword is
+ uncommented and add the above line below it. You used to need to install
+ your shared modules with ``make sharedinstall`` but this no longer seems
+ to be true.
+
+* Copy ``pg.py`` to the lib directory where the rest of your modules are.
+ For example, that's ``/usr/local/lib/Python`` on my system.
+
+* Rebuild Python from the root directory of the Python source hierarchy by
+ running ``make -f Makefile.pre.in boot`` and ``make && make install``.
+
+* For more details read the documentation at the top of ``Makefile.pre.in``.
[6/9] incubator-hawq git commit: HAWQ-672. Add python module pygresql
back into hawq workspace
Posted by od...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.html
new file mode 100644
index 0000000..2e90378
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.html
@@ -0,0 +1,2429 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>PyGreSQL Programming Information</title>
+<meta content="The classic PyGreSQL interface (pg module)" name="description" />
+<meta content="PyGreSQL, pg, PostGreSQL, Python" name="keywords" />
+<link rel="stylesheet" href="docs.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="pygresql-programming-information">
+<h1 class="title">PyGreSQL Programming Information</h1>
+<h2 class="subtitle" id="the-classic-pygresql-interface-pg-module">The classic PyGreSQL interface (pg module)</h2>
+<div class="contents topic">
+<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
+<ul class="auto-toc simple">
+<li><a class="reference" href="#introduction" id="id5" name="id5">1 Introduction</a></li>
+<li><a class="reference" href="#module-functions-and-constants" id="id6" name="id6">2 Module functions and constants</a><ul class="auto-toc">
+<li><a class="reference" href="#connect-opens-a-pg-connection" id="id7" name="id7">2.1 connect - opens a pg connection</a></li>
+<li><a class="reference" href="#get-defhost-set-defhost-default-server-host-dv" id="id8" name="id8">2.2 get_defhost, set_defhost - default server host [DV]</a></li>
+<li><a class="reference" href="#get-defport-set-defport-default-server-port-dv" id="id9" name="id9">2.3 get_defport, set_defport - default server port [DV]</a></li>
+<li><a class="reference" href="#get-defopt-set-defopt-default-connection-options-dv" id="id10" name="id10">2.4 get_defopt, set_defopt - default connection options [DV]</a></li>
+<li><a class="reference" href="#get-deftty-set-deftty-default-debug-tty-dv" id="id11" name="id11">2.5 get_deftty, set_deftty - default debug tty [DV]</a></li>
+<li><a class="reference" href="#get-defbase-set-defbase-default-database-name-dv" id="id12" name="id12">2.6 get_defbase, set_defbase - default database name [DV]</a></li>
+<li><a class="reference" href="#escape-string-escape-a-string-for-use-within-sql" id="id13" name="id13">2.7 escape_string - escape a string for use within SQL</a></li>
+<li><a class="reference" href="#escape-bytea-escape-binary-data-for-use-within-sql-as-type-bytea" id="id14" name="id14">2.8 escape_bytea - escape binary data for use within SQL as type <cite>bytea</cite></a></li>
+<li><a class="reference" href="#unescape-bytea-unescape-bytea-data-that-has-been-retrieved-as-text" id="id15" name="id15">2.9 unescape_bytea -- unescape <cite>bytea</cite> data that has been retrieved as text</a></li>
+<li><a class="reference" href="#set-decimal-set-a-decimal-type-to-be-used-for-numeric-values" id="id16" name="id16">2.10 set_decimal -- set a decimal type to be used for numeric values</a></li>
+<li><a class="reference" href="#module-constants" id="id17" name="id17">2.11 Module constants</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#connection-objects-pgobject" id="id18" name="id18">3 Connection objects: pgobject</a><ul class="auto-toc">
+<li><a class="reference" href="#query-executes-a-sql-command-string" id="id19" name="id19">3.1 query - executes a SQL command string</a></li>
+<li><a class="reference" href="#reset-resets-the-connection" id="id20" name="id20">3.2 reset - resets the connection</a></li>
+<li><a class="reference" href="#cancel-abandon-processing-of-current-sql-command" id="id21" name="id21">3.3 cancel - abandon processing of current SQL command</a></li>
+<li><a class="reference" href="#close-close-the-database-connection" id="id22" name="id22">3.4 close - close the database connection</a></li>
+<li><a class="reference" href="#fileno-returns-the-socket-used-to-connect-to-the-database" id="id23" name="id23">3.5 fileno - returns the socket used to connect to the database</a></li>
+<li><a class="reference" href="#getnotify-gets-the-last-notify-from-the-server" id="id24" name="id24">3.6 getnotify - gets the last notify from the server</a></li>
+<li><a class="reference" href="#inserttable-insert-a-list-into-a-table" id="id25" name="id25">3.7 inserttable - insert a list into a table</a></li>
+<li><a class="reference" href="#putline-writes-a-line-to-the-server-socket-da" id="id26" name="id26">3.8 putline - writes a line to the server socket [DA]</a></li>
+<li><a class="reference" href="#getline-gets-a-line-from-server-socket-da" id="id27" name="id27">3.9 getline - gets a line from server socket [DA]</a></li>
+<li><a class="reference" href="#endcopy-synchronizes-client-and-server-da" id="id28" name="id28">3.10 endcopy - synchronizes client and server [DA]</a></li>
+<li><a class="reference" href="#locreate-create-a-large-object-in-the-database-lo" id="id29" name="id29">3.11 locreate - create a large object in the database [LO]</a></li>
+<li><a class="reference" href="#getlo-build-a-large-object-from-given-oid-lo" id="id30" name="id30">3.12 getlo - build a large object from given oid [LO]</a></li>
+<li><a class="reference" href="#loimport-import-a-file-to-a-large-object-lo" id="id31" name="id31">3.13 loimport - import a file to a large object [LO]</a></li>
+<li><a class="reference" href="#object-attributes" id="id32" name="id32">3.14 Object attributes</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#the-db-wrapper-class" id="id33" name="id33">4 The DB wrapper class</a><ul class="auto-toc">
+<li><a class="reference" href="#initialization" id="id34" name="id34">4.1 Initialization</a></li>
+<li><a class="reference" href="#pkey-return-the-primary-key-of-a-table" id="id35" name="id35">4.2 pkey - return the primary key of a table</a></li>
+<li><a class="reference" href="#get-databases-get-list-of-databases-in-the-system" id="id36" name="id36">4.3 get_databases - get list of databases in the system</a></li>
+<li><a class="reference" href="#get-relations-get-list-of-relations-in-connected-database" id="id37" name="id37">4.4 get_relations - get list of relations in connected database</a></li>
+<li><a class="reference" href="#get-tables-get-list-of-tables-in-connected-database" id="id38" name="id38">4.5 get_tables - get list of tables in connected database</a></li>
+<li><a class="reference" href="#get-attnames-get-the-attribute-names-of-a-table" id="id39" name="id39">4.6 get_attnames - get the attribute names of a table</a></li>
+<li><a class="reference" href="#has-table-privilege-check-whether-current-user-has-specified-table-privilege" id="id40" name="id40">4.7 has_table_privilege - check whether current user has specified table privilege</a></li>
+<li><a class="reference" href="#get-get-a-row-from-a-database-table-or-view" id="id41" name="id41">4.8 get - get a row from a database table or view</a></li>
+<li><a class="reference" href="#insert-insert-a-row-into-a-database-table" id="id42" name="id42">4.9 insert - insert a row into a database table</a></li>
+<li><a class="reference" href="#update-update-a-row-in-a-database-table" id="id43" name="id43">4.10 update - update a row in a database table</a></li>
+<li><a class="reference" href="#clear-clears-row-values-in-memory" id="id44" name="id44">4.11 clear - clears row values in memory</a></li>
+<li><a class="reference" href="#delete-delete-a-row-from-a-database-table" id="id45" name="id45">4.12 delete - delete a row from a database table</a></li>
+<li><a class="reference" href="#id1" id="id46" name="id46">4.13 escape_string - escape a string for use within SQL</a></li>
+<li><a class="reference" href="#id2" id="id47" name="id47">4.14 escape_bytea - escape binary data for use within SQL as type <cite>bytea</cite></a></li>
+<li><a class="reference" href="#id3" id="id48" name="id48">4.15 unescape_bytea -- unescape <cite>bytea</cite> data that has been retrieved as text</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#pgqueryobject-methods" id="id49" name="id49">5 pgqueryobject methods</a><ul class="auto-toc">
+<li><a class="reference" href="#getresult-get-query-values-as-list-of-tuples" id="id50" name="id50">5.1 getresult - get query values as list of tuples</a></li>
+<li><a class="reference" href="#dictresult-get-query-values-as-list-of-dictionaries" id="id51" name="id51">5.2 dictresult - get query values as list of dictionaries</a></li>
+<li><a class="reference" href="#listfields-lists-fields-names-of-previous-query-result" id="id52" name="id52">5.3 listfields - lists fields names of previous query result</a></li>
+<li><a class="reference" href="#fieldname-fieldnum-field-name-number-conversion" id="id53" name="id53">5.4 fieldname, fieldnum - field name/number conversion</a></li>
+<li><a class="reference" href="#ntuples-return-number-of-tuples-in-query-object" id="id54" name="id54">5.5 ntuples - return number of tuples in query object</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#large-objects-pglarge" id="id55" name="id55">6 Large objects: pglarge</a><ul class="auto-toc">
+<li><a class="reference" href="#open-opens-a-large-object" id="id56" name="id56">6.1 open - opens a large object</a></li>
+<li><a class="reference" href="#close-closes-a-large-object" id="id57" name="id57">6.2 close - closes a large object</a></li>
+<li><a class="reference" href="#read-write-tell-seek-unlink-file-like-large-object-handling" id="id58" name="id58">6.3 read, write, tell, seek, unlink - file like large object handling</a></li>
+<li><a class="reference" href="#size-gives-the-large-object-size" id="id59" name="id59">6.4 size - gives the large object size</a></li>
+<li><a class="reference" href="#export-saves-a-large-object-to-a-file" id="id60" name="id60">6.5 export - saves a large object to a file</a></li>
+<li><a class="reference" href="#id4" id="id61" name="id61">6.6 Object attributes</a></li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id5" id="introduction" name="introduction">1 Introduction</a></h1>
+<p>You may either choose to use the
+<a class="reference" href="pg.html">"classic" PyGreSQL interface</a>
+provided by the <cite>pg</cite> module or else the
+<a class="reference" href="pgdb.html">DB-API 2.0 compliant interface</a>
+provided by the <cite>pgdb</cite> module.</p>
+<p>The following documentation covers only the older <cite>pg</cite> API.</p>
+<p>The <cite>pg</cite> module handles three types of objects,</p>
+<ul class="simple">
+<li>the <cite>pgobject</cite>, which handles the connection
+and all the requests to the database,</li>
+<li>the <cite>pglarge</cite> object, which handles
+all the accesses to PostgreSQL large objects,</li>
+<li>the <cite>pgqueryobject</cite> that handles query results</li>
+</ul>
+<p>and it provides a convenient wrapper class <cite>DB</cite> for the <cite>pgobject</cite>.</p>
+<p>If you want to see a simple example of the use of some of these functions,
+see <a class="reference" href="http://ontario.bikerides.ca">http://ontario.bikerides.ca</a> where you can find a link at the bottom to the
+actual Python code for the page.</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id6" id="module-functions-and-constants" name="module-functions-and-constants">2 Module functions and constants</a></h1>
+<p>The <cite>pg</cite> module defines a few functions that allow to connect
+to a database and to define "default variables" that override
+the environment variables used by PostgreSQL.</p>
+<p>These "default variables" were designed to allow you to handle general
+connection parameters without heavy code in your programs. You can prompt the
+user for a value, put it in the default variable, and forget it, without
+having to modify your environment. The support for default variables can be
+disabled by setting the -DNO_DEF_VAR option in the Python setup file. Methods
+relative to this are specified by the tag [DV].</p>
+<p>All variables are set to <cite>None</cite> at module initialization, specifying that
+standard environment variables should be used.</p>
+<div class="section">
+<h2><a class="toc-backref" href="#id7" id="connect-opens-a-pg-connection" name="connect-opens-a-pg-connection">2.1 connect - opens a pg connection</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+connect([dbname], [host], [port], [opt], [tty], [user], [passwd])
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">dbname:</th><td class="field-body">name of connected database (string/None)</td>
+</tr>
+<tr class="field"><th class="field-name">host:</th><td class="field-body">name of the server host (string/None)</td>
+</tr>
+<tr class="field"><th class="field-name">port:</th><td class="field-body">port used by the database server (integer/-1)</td>
+</tr>
+<tr class="field"><th class="field-name">opt:</th><td class="field-body">connection options (string/None)</td>
+</tr>
+<tr class="field"><th class="field-name">tty:</th><td class="field-body">debug terminal (string/None)</td>
+</tr>
+<tr class="field"><th class="field-name">user:</th><td class="field-body">PostgreSQL user (string/None)</td>
+</tr>
+<tr class="field"><th class="field-name">passwd:</th><td class="field-body">password for user (string/None)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">pgobject:</th><td class="field-body">If successful, the <cite>pgobject</cite> handling the connection</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+<tr class="field"><th class="field-name">SyntaxError:</th><td class="field-body">duplicate argument definition</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.InternalError:</th></tr>
+<tr><td> </td><td class="field-body">some error occurred during pg connection definition</td>
+</tr>
+</tbody>
+</table>
+<p class="last">(plus all exceptions relative to object allocation)</p>
+</dd>
+<dt>Description:</dt>
+<dd>This function opens a connection to a specified database on a given
+PostgreSQL server. You can use keywords here, as described in the
+Python tutorial. The names of the keywords are the name of the
+parameters given in the syntax line. For a precise description
+of the parameters, please refer to the PostgreSQL user manual.</dd>
+</dl>
+<p>Examples:</p>
+<pre class="literal-block">
+import pg
+
+con1 = pg.connect('testdb', 'myhost', 5432, None, None, 'bob', None)
+con2 = pg.connect(dbname='testdb', host='localhost', user='bob')
+</pre>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id8" id="get-defhost-set-defhost-default-server-host-dv" name="get-defhost-set-defhost-default-server-host-dv">2.2 get_defhost, set_defhost - default server host [DV]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_defhost()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">default host specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the current default host specification,
+or <cite>None</cite> if the environment variables should be used.
+Environment variables won't be looked up.</dd>
+</dl>
+<p>Syntax:</p>
+<pre class="literal-block">
+set_defhost(host)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">host:</th><td class="field-body">new default host (string/None)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">previous default host specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This methods sets the default host value for new connections.
+If <cite>None</cite> is supplied as parameter, environment variables will
+be used in future connections. It returns the previous setting
+for default host.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id9" id="get-defport-set-defport-default-server-port-dv" name="get-defport-set-defport-default-server-port-dv">2.3 get_defport, set_defport - default server port [DV]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_defport()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">integer, None:</th><td class="field-body">default port specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the current default port specification,
+or <cite>None</cite> if the environment variables should be used.
+Environment variables won't be looked up.</dd>
+</dl>
+<p>Syntax:</p>
+<pre class="literal-block">
+set_defport(port)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">port:</th><td class="field-body">new default port (integer/-1)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">integer, None:</th><td class="field-body">previous default port specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This methods sets the default port value for new connections. If -1 is
+supplied as parameter, environment variables will be used in future
+connections. It returns the previous setting for default port.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id10" id="get-defopt-set-defopt-default-connection-options-dv" name="get-defopt-set-defopt-default-connection-options-dv">2.4 get_defopt, set_defopt - default connection options [DV]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_defopt()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">default options specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the current default connection options specification,
+or <cite>None</cite> if the environment variables should be used. Environment variables
+won't be looked up.</dd>
+</dl>
+<p>Syntax:</p>
+<pre class="literal-block">
+set_defopt(options)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">options:</th><td class="field-body">new default connection options (string/None)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">previous default options specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This methods sets the default connection options value for new connections.
+If <cite>None</cite> is supplied as parameter, environment variables will be used in
+future connections. It returns the previous setting for default options.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id11" id="get-deftty-set-deftty-default-debug-tty-dv" name="get-deftty-set-deftty-default-debug-tty-dv">2.5 get_deftty, set_deftty - default debug tty [DV]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_deftty()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">default debug terminal specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the current default debug terminal specification, or
+<cite>None</cite> if the environment variables should be used. Environment variables
+won't be looked up.</dd>
+</dl>
+<p>Syntax:</p>
+<pre class="literal-block">
+set_deftty(terminal)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">terminal:</th><td class="field-body">new default debug terminal (string/None)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">previous default debug terminal specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This methods sets the default debug terminal value for new connections. If
+<cite>None</cite> is supplied as parameter, environment variables will be used in future
+connections. It returns the previous setting for default terminal.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id12" id="get-defbase-set-defbase-default-database-name-dv" name="get-defbase-set-defbase-default-database-name-dv">2.6 get_defbase, set_defbase - default database name [DV]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_defbase()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">default database name specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the current default database name specification, or
+<cite>None</cite> if the environment variables should be used. Environment variables
+won't be looked up.</dd>
+</dl>
+<p>Syntax:</p>
+<pre class="literal-block">
+set_defbase(base)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">base:</th><td class="field-body">new default base name (string/None)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string, None:</th><td class="field-body">previous default database name specification</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method sets the default database name value for new connections. If
+<cite>None</cite> is supplied as parameter, environment variables will be used in
+future connections. It returns the previous setting for default host.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id13" id="escape-string-escape-a-string-for-use-within-sql" name="escape-string-escape-a-string-for-use-within-sql">2.7 escape_string - escape a string for use within SQL</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+escape_string(string)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string:</th><td class="field-body">the string that is to be escaped</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">str:</th><td class="field-body">the escaped string</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This function escapes a string for use within an SQL command.
+This is useful when inserting data values as literal constants
+in SQL commands. Certain characters (such as quotes and backslashes)
+must be escaped to prevent them from being interpreted specially
+by the SQL parser. <cite>escape_string</cite> performs this operation.
+Note that there is also a <cite>pgobject</cite> method with the same name
+which takes connection properties into account.</dd>
+</dl>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p class="last">It is especially important to do proper escaping when
+handling strings that were received from an untrustworthy source.
+Otherwise there is a security risk: you are vulnerable to "SQL injection"
+attacks wherein unwanted SQL commands are fed to your database.</p>
+</div>
+<p>Example:</p>
+<pre class="literal-block">
+name = raw_input("Name? ")
+phone = con.query("select phone from employees"
+ " where name='%s'" % escape_string(name)).getresult()
+</pre>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id14" id="escape-bytea-escape-binary-data-for-use-within-sql-as-type-bytea" name="escape-bytea-escape-binary-data-for-use-within-sql-as-type-bytea">2.8 escape_bytea - escape binary data for use within SQL as type <cite>bytea</cite></a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+escape_bytea(datastring)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">datastring:</th><td class="field-body">string containing the binary data that is to be escaped</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">str:</th><td class="field-body">the escaped string</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Escapes binary data for use within an SQL command with the type <cite>bytea</cite>.
+As with <cite>escape_string</cite>, this is only used when inserting data directly
+into an SQL command string.
+Note that there is also a <cite>pgobject</cite> method with the same name
+which takes connection properties into account.</dd>
+</dl>
+<p>Example:</p>
+<pre class="literal-block">
+picture = file('garfield.gif', 'rb').read()
+con.query("update pictures set img='%s' where name='Garfield'"
+ % escape_bytea(picture))
+</pre>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id15" id="unescape-bytea-unescape-bytea-data-that-has-been-retrieved-as-text" name="unescape-bytea-unescape-bytea-data-that-has-been-retrieved-as-text">2.9 unescape_bytea -- unescape <cite>bytea</cite> data that has been retrieved as text</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+unescape_bytea(string)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">datastring:</th><td class="field-body">the <cite>bytea</cite> data string that has been retrieved as text</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">str:</th><td class="field-body">string containing the binary data</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Converts an escaped string representation of binary data into binary
+data - the reverse of <cite>escape_bytea</cite>. This is needed when retrieving
+<cite>bytea</cite> data with the <cite>getresult()</cite> or <cite>dictresult()</cite> method.</dd>
+</dl>
+<p>Example:</p>
+<pre class="literal-block">
+picture = unescape_bytea(con.query(
+ "select img from pictures where name='Garfield'").getresult[0][0])
+file('garfield.gif', 'wb').write(picture)
+</pre>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id16" id="set-decimal-set-a-decimal-type-to-be-used-for-numeric-values" name="set-decimal-set-a-decimal-type-to-be-used-for-numeric-values">2.10 set_decimal -- set a decimal type to be used for numeric values</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+set_decimal(cls)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">cls:</th><td class="field-body">the Python class to be used for PostgreSQL numeric values</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This function can be used to specify the Python class that shall be
+used by PyGreSQL to hold PostgreSQL numeric values. The default class
+is decimal.Decimal if available, otherwise the float type is used.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id17" id="module-constants" name="module-constants">2.11 Module constants</a></h2>
+<p>Some constants are defined in the module dictionary.
+They are intended to be used as parameters for methods calls.
+You should refer to the libpq description in the PostgreSQL user manual
+for more information about them. These constants are:</p>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name" colspan="2">version, __version__:</th></tr>
+<tr><td> </td><td class="field-body">constants that give the current version.</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">INV_READ, INV_WRITE:</th></tr>
+<tr><td> </td><td class="field-body">large objects access modes,
+used by <cite>(pgobject.)locreate</cite> and <cite>(pglarge.)open</cite></td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">SEEK_SET, SEEK_CUR, SEEK_END:</th></tr>
+<tr><td> </td><td class="field-body">positional flags,
+used by <cite>(pglarge.)seek</cite></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id18" id="connection-objects-pgobject" name="connection-objects-pgobject">3 Connection objects: pgobject</a></h1>
+<p>This object handles a connection to a PostgreSQL database. It embeds and
+hides all the parameters that define this connection, thus just leaving really
+significant parameters in function calls.</p>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p>Some methods give direct access to the connection socket.
+<em>Do not use them unless you really know what you are doing.</em>
+If you prefer disabling them,
+set the -DNO_DIRECT option in the Python setup file.</p>
+<p class="last"><strong>These methods are specified by the tag [DA].</strong></p>
+</div>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p>Some other methods give access to large objects
+(refer to PostgreSQL user manual for more information about these).
+If you want to forbid access to these from the module,
+set the -DNO_LARGE option in the Python setup file.</p>
+<p class="last"><strong>These methods are specified by the tag [LO].</strong></p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id19" id="query-executes-a-sql-command-string" name="query-executes-a-sql-command-string">3.1 query - executes a SQL command string</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+query(command)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">command:</th><td class="field-body">SQL command (string)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name" colspan="2">pgqueryobject, None:</th></tr>
+<tr><td> </td><td class="field-body">result values</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">bad argument type, or too many arguments</td>
+</tr>
+<tr class="field"><th class="field-name">ValueError:</th><td class="field-body">empty SQL query or lost connection</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.ProgrammingError:</th></tr>
+<tr><td> </td><td class="field-body">error in query</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.InternalError':</th></tr>
+<tr><td> </td><td class="field-body">error during query processing</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method simply sends a SQL query to the database. If the query is an
+insert statement that inserted exactly one row into a table that has OIDs, the
+return value is the OID of the newly inserted row. If the query is an update
+or delete statement, or an insert statement that did not insert exactly one
+row in a table with OIDs, then the numer of rows affected is returned as a
+string. If it is a statement that returns rows as a result (usually a select
+statement, but maybe also an "insert/update ... returning" statement), this
+method returns a <cite>pgqueryobject</cite> that can be accessed via the <cite>getresult()</cite>
+or <cite>dictresult()</cite> method or simply printed. Otherwise, it returns <cite>None</cite>.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id20" id="reset-resets-the-connection" name="reset-resets-the-connection">3.2 reset - resets the connection</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+reset()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd>None</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many (any) arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method resets the current database connection.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id21" id="cancel-abandon-processing-of-current-sql-command" name="cancel-abandon-processing-of-current-sql-command">3.3 cancel - abandon processing of current SQL command</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+cancel()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd>None</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many (any) arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method requests that the server abandon processing
+of the current SQL command.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id22" id="close-close-the-database-connection" name="close-close-the-database-connection">3.4 close - close the database connection</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+close()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd>None</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many (any) arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method closes the database connection. The connection will
+be closed in any case when the connection is deleted but this
+allows you to explicitly close it. It is mainly here to allow
+the DB-SIG API wrapper to implement a close function.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id23" id="fileno-returns-the-socket-used-to-connect-to-the-database" name="fileno-returns-the-socket-used-to-connect-to-the-database">3.5 fileno - returns the socket used to connect to the database</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+fileno()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many (any) arguments</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the underlying socket id used to connect
+to the database. This is useful for use in select calls, etc.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id24" id="getnotify-gets-the-last-notify-from-the-server" name="getnotify-gets-the-last-notify-from-the-server">3.6 getnotify - gets the last notify from the server</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+getnotify()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">tuple, None:</th><td class="field-body">last notify from server</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This methods try to get a notify from the server (from the SQL statement
+NOTIFY). If the server returns no notify, the methods returns None.
+Otherwise, it returns a tuple (couple) <cite>(relname, pid)</cite>, where <cite>relname</cite>
+is the name of the notify and <cite>pid</cite> the process id of the connection that
+triggered the notify. Remember to do a listen query first otherwise
+getnotify() will always return <cite>None</cite>.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id25" id="inserttable-insert-a-list-into-a-table" name="inserttable-insert-a-list-into-a-table">3.7 inserttable - insert a list into a table</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+inserttable(table, values)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">the table name (string)</td>
+</tr>
+<tr class="field"><th class="field-name">values:</th><td class="field-body">list of rows values (list)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd>None</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection, bad argument type, or too many arguments</td>
+</tr>
+<tr class="field"><th class="field-name">MemoryError:</th><td class="field-body">insert buffer could not be allocated</td>
+</tr>
+<tr class="field"><th class="field-name">ValueError:</th><td class="field-body">unsupported values</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method allow to <em>quickly</em> insert large blocks of data in a table:
+It inserts the whole values list into the given table. Internally, it
+uses the COPY command of the PostgreSQL database. The list is a list
+of tuples/lists that define the values for each inserted row. The rows
+values may contain string, integer, long or double (real) values.</dd>
+</dl>
+<div class="caution">
+<p class="first admonition-title">Caution!</p>
+<p class="last"><em>Be very careful</em>:
+This method doesn't typecheck the fields according to the table definition;
+it just look whether or not it knows how to handle such types.</p>
+</div>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id26" id="putline-writes-a-line-to-the-server-socket-da" name="putline-writes-a-line-to-the-server-socket-da">3.8 putline - writes a line to the server socket [DA]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+putline(line)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">line:</th><td class="field-body">line to be written (string)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd>None</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection, bad parameter type, or too many parameters</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method allows to directly write a string to the server socket.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id27" id="getline-gets-a-line-from-server-socket-da" name="getline-gets-a-line-from-server-socket-da">3.9 getline - gets a line from server socket [DA]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+getline()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string:</th><td class="field-body">the line read</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection</td>
+</tr>
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name">MemoryError:</th><td class="field-body">buffer overflow</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method allows to directly read a string from the server socket.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id28" id="endcopy-synchronizes-client-and-server-da" name="endcopy-synchronizes-client-and-server-da">3.10 endcopy - synchronizes client and server [DA]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+endcopy()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd>None</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection</td>
+</tr>
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many parameters</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>The use of direct access methods may desynchonize client and server.
+This method ensure that client and server will be synchronized.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id29" id="locreate-create-a-large-object-in-the-database-lo" name="locreate-create-a-large-object-in-the-database-lo">3.11 locreate - create a large object in the database [LO]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+locreate(mode)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">mode:</th><td class="field-body">large object create mode</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">pglarge:</th><td class="field-body">object handling the PostGreSQL large object</td>
+</tr>
+</tbody>
+</table>
+</dd>
+</dl>
+<p>Exceptions raised:</p>
+<blockquote>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection, bad parameter type, or too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.OperationalError:</th></tr>
+<tr><td> </td><td class="field-body">creation error</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<dl class="docutils">
+<dt>Description:</dt>
+<dd>This method creates a large object in the database. The mode can be defined
+by OR-ing the constants defined in the pg module (INV_READ, INV_WRITE and
+INV_ARCHIVE). Please refer to PostgreSQL user manual for a description of
+the mode values.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id30" id="getlo-build-a-large-object-from-given-oid-lo" name="getlo-build-a-large-object-from-given-oid-lo">3.12 getlo - build a large object from given oid [LO]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+getlo(oid)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">oid:</th><td class="field-body">OID of the existing large object (integer)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">pglarge:</th><td class="field-body">object handling the PostGreSQL large object</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection, bad parameter type, or too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name">ValueError:</th><td class="field-body">bad OID value (0 is invalid_oid)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method allows to reuse a formerly created large object through the
+<cite>pglarge</cite> interface, providing the user have its OID.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id31" id="loimport-import-a-file-to-a-large-object-lo" name="loimport-import-a-file-to-a-large-object-lo">3.13 loimport - import a file to a large object [LO]</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+loimport(name)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">name:</th><td class="field-body">the name of the file to be imported (string)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">pglarge:</th><td class="field-body">object handling the PostGreSQL large object</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection, bad argument type, or too many arguments</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.OperationalError:</th></tr>
+<tr><td> </td><td class="field-body">error during file import</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This methods allows to create large objects in a very simple way. You just
+give the name of a file containing the data to be use.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id32" id="object-attributes" name="object-attributes">3.14 Object attributes</a></h2>
+<p>Every <cite>pgobject</cite> defines a set of read-only attributes that describe the
+connection and its status. These attributes are:</p>
+<blockquote>
+<table class="docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">host:</th><td class="field-body">the host name of the server (string)</td>
+</tr>
+<tr class="field"><th class="field-name">port:</th><td class="field-body">the port of the server (integer)</td>
+</tr>
+<tr class="field"><th class="field-name">db:</th><td class="field-body">the selected database (string)</td>
+</tr>
+<tr class="field"><th class="field-name">options:</th><td class="field-body">the connection options (string)</td>
+</tr>
+<tr class="field"><th class="field-name">tty:</th><td class="field-body">the connection debug terminal (string)</td>
+</tr>
+<tr class="field"><th class="field-name">user:</th><td class="field-body">user name on the database system (string)</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">protocol_version:</th></tr>
+<tr><td> </td><td class="field-body">the frontend/backend protocol being used (integer)</td>
+</tr>
+<tr class="field"><th class="field-name">server_version:</th><td class="field-body">the backend version (integer, e.g. 80305 for 8.3.5)</td>
+</tr>
+<tr class="field"><th class="field-name">status:</th><td class="field-body">the status of the connection (integer: 1 - OK, 0 - bad)</td>
+</tr>
+<tr class="field"><th class="field-name">error:</th><td class="field-body">the last warning/error message from the server (string)</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id33" id="the-db-wrapper-class" name="the-db-wrapper-class">4 The DB wrapper class</a></h1>
+<p>The <cite>pgobject</cite> methods are wrapped in the class <cite>DB</cite>.
+The preferred way to use this module is as follows:</p>
+<pre class="literal-block">
+import pg
+
+db = pg.DB(...) # see below
+
+for r in db.query( # just for example
+ """SELECT foo,bar
+ FROM foo_bar_table
+ WHERE foo !~ bar"""
+ ).dictresult():
+
+ print '%(foo)s %(bar)s' % r
+</pre>
+<p>This class can be subclassed as in this example:</p>
+<pre class="literal-block">
+import pg
+
+class DB_ride(pg.DB):
+ """This class encapsulates the database functions and the specific
+ methods for the ride database."""
+
+ def __init__(self):
+ """Opens a database connection to the rides database"""
+
+ pg.DB.__init__(self, dbname = 'ride')
+ self.query("""SET DATESTYLE TO 'ISO'""")
+
+ [Add or override methods here]
+</pre>
+<p>The following describes the methods and variables of this class.</p>
+<div class="section">
+<h2><a class="toc-backref" href="#id34" id="initialization" name="initialization">4.1 Initialization</a></h2>
+<p>The DB class is initialized with the same arguments as the connect
+function described in section 2. It also initializes a few
+internal variables. The statement <cite>db = DB()</cite> will open the
+local database with the name of the user just like connect() does.</p>
+<p>You can also initialize the DB class with an existing <cite>_pg</cite> or <cite>pgdb</cite>
+connection. Pass this connection as a single unnamed parameter, or as a
+single parameter named <cite>db</cite>. This allows you to use all of the methods
+of the DB class with a DB-API 2 compliant connection. Note that the
+<cite>close()</cite> and <cite>reopen()</cite> methods are inoperative in this case.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id35" id="pkey-return-the-primary-key-of-a-table" name="pkey-return-the-primary-key-of-a-table">4.2 pkey - return the primary key of a table</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+pkey(table)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string:</th><td class="field-body">Name of the field which is the primary key of the table</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the primary key of a table. For composite primary
+keys, the return value will be a frozenset. Note that this raises an
+exception if the table does not have a primary key.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id36" id="get-databases-get-list-of-databases-in-the-system" name="get-databases-get-list-of-databases-in-the-system">4.3 get_databases - get list of databases in the system</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_databases()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">list:</th><td class="field-body">all databases in the system</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Although you can do this with a simple select, it is added here for
+convenience.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id37" id="get-relations-get-list-of-relations-in-connected-database" name="get-relations-get-list-of-relations-in-connected-database">4.4 get_relations - get list of relations in connected database</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_relations(kinds)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">kinds:</th><td class="field-body">a string or sequence of type letters</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>The type letters are <cite>r</cite> = ordinary table, <cite>i</cite> = index, <cite>S</cite> = sequence,
+<cite>v</cite> = view, <cite>c</cite> = composite type, <cite>s</cite> = special, <cite>t</cite> = TOAST table.
+If <cite>kinds</cite> is None or an empty string, all relations are returned (this is
+also the default). Although you can do this with a simple select, it is
+added here for convenience.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id38" id="get-tables-get-list-of-tables-in-connected-database" name="get-tables-get-list-of-tables-in-connected-database">4.5 get_tables - get list of tables in connected database</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_tables()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Returns:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">list:</th><td class="field-body">all tables in connected database</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Although you can do this with a simple select, it is added here for
+convenience.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id39" id="get-attnames-get-the-attribute-names-of-a-table" name="get-attnames-get-the-attribute-names-of-a-table">4.6 get_attnames - get the attribute names of a table</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get_attnames(table)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Returns:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">dictionary:</th><td class="field-body">The keys are the attribute names,
+the values are the type names of the attributes.</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Given the name of a table, digs out the set of attribute names.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id40" id="has-table-privilege-check-whether-current-user-has-specified-table-privilege" name="has-table-privilege-check-whether-current-user-has-specified-table-privilege">4.7 has_table_privilege - check whether current user has specified table privilege</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+has_table_privilege(table, privilege)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table</td>
+</tr>
+<tr class="field"><th class="field-name">privilege:</th><td class="field-body">privilege to be checked - default is 'select'</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Returns True if the current user has the specified privilege for the table.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id41" id="get-get-a-row-from-a-database-table-or-view" name="get-get-a-row-from-a-database-table-or-view">4.8 get - get a row from a database table or view</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+get(table, arg, [keyname])
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table or view</td>
+</tr>
+<tr class="field"><th class="field-name">arg:</th><td class="field-body">either a dictionary or the value to be looked up</td>
+</tr>
+<tr class="field"><th class="field-name">keyname:</th><td class="field-body">name of field to use as key (optional)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">dictionary:</th><td class="field-body">The keys are the attribute names,
+the values are the row values.</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method is the basic mechanism to get a single row. It assumes
+that the key specifies a unique row. If <cite>keyname</cite> is not specified
+then the primary key for the table is used. If <cite>arg</cite> is a dictionary
+then the value for the key is taken from it and it is modified to
+include the new values, replacing existing values where necessary.
+For a composite key, <cite>keyname</cite> can also be a sequence of key names.
+The OID is also put into the dictionary if the table has one, but in
+order to allow the caller to work with multiple tables, it is munged
+as <cite>oid(schema.table)</cite>.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id42" id="insert-insert-a-row-into-a-database-table" name="insert-insert-a-row-into-a-database-table">4.9 insert - insert a row into a database table</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+insert(table, [d,] [return_changes,] [key = val, ...])
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table</td>
+</tr>
+<tr class="field"><th class="field-name">d:</th><td class="field-body">optional dictionary of values</td>
+</tr>
+<tr class="field"><th class="field-name">return_changes:</th><td class="field-body">Return values in new row - default True</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">dictionary:</th><td class="field-body">The dictionary of values inserted</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd><p class="first">This method inserts a row into a table. If the optional dictionary is
+not supplied then the required values must be included as keyword/value
+pairs. If a dictionary is supplied then any keywords provided will be
+added to or replace the entry in the dictionary.</p>
+<p>The dictionary is then, if possible, reloaded with the values actually
+inserted in order to pick up values modified by rules, triggers, etc.</p>
+<p>Due to the way that this function works in PostgreSQL versions below
+8.2, you may find inserts taking longer and longer as your table gets
+bigger. If this happens and it is a table with OID but no primary key
+you can overcome this problem by simply adding an index onto the OID of
+any table that you think may get large over time. You may also consider
+using the inserttable() method described in section 3.</p>
+<p>Note: With PostgreSQL versions before 8.2 the table being inserted to
+must have a primary key or an OID to use this method properly. If not
+then the dictionary will not be filled in as described. Also, if this
+method is called within a transaction, the transaction will abort.</p>
+<p class="last">Note: The method currently doesn't support insert into views
+although PostgreSQL does.</p>
+</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id43" id="update-update-a-row-in-a-database-table" name="update-update-a-row-in-a-database-table">4.10 update - update a row in a database table</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+update(table, [d,] [key = val, ...])
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table</td>
+</tr>
+<tr class="field"><th class="field-name">d:</th><td class="field-body">optional dictionary of values</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">dictionary:</th><td class="field-body">the new row</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd><p class="first">Similar to insert but updates an existing row. The update is based on the
+OID value as munged by get or passed as keyword, or on the primary key of
+the table. The dictionary is modified, if possible, to reflect any changes
+caused by the update due to triggers, rules, default values, etc.</p>
+<p class="last">Like insert, the dictionary is optional and updates will be performed
+on the fields in the keywords. There must be an OID or primary key
+either in the dictionary where the OID must be munged, or in the keywords
+where it can be simply the string "oid".</p>
+</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id44" id="clear-clears-row-values-in-memory" name="clear-clears-row-values-in-memory">4.11 clear - clears row values in memory</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+clear(table, [a])
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table</td>
+</tr>
+<tr class="field"><th class="field-name">a:</th><td class="field-body">optional dictionary of values</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">dictionary:</th><td class="field-body">an empty row</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd><p class="first">This method clears all the attributes to values determined by the types.
+Numeric types are set to 0, Booleans are set to 'f', dates are set
+to 'now()' and everything else is set to the empty string.
+If the array argument is present, it is used as the array and any entries
+matching attribute names are cleared with everything else left unchanged.</p>
+<p class="last">If the dictionary is not supplied a new one is created.</p>
+</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id45" id="delete-delete-a-row-from-a-database-table" name="delete-delete-a-row-from-a-database-table">4.12 delete - delete a row from a database table</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+delete(table, [d,] [key = val, ...])
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">table:</th><td class="field-body">name of table</td>
+</tr>
+<tr class="field"><th class="field-name">d:</th><td class="field-body">optional dictionary of values</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Returns:</dt>
+<dd>None</dd>
+<dt>Description:</dt>
+<dd>This method deletes the row from a table. It deletes based on the OID value
+as munged by get or passed as keyword, or on the primary key of the table.
+The return value is the number of deleted rows (i.e. 0 if the row did not
+exist and 1 if the row was deleted).</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id46" id="id1" name="id1">4.13 escape_string - escape a string for use within SQL</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+escape_string(string)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string:</th><td class="field-body">the string that is to be escaped</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">str:</th><td class="field-body">the escaped string</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Similar to the module function with the same name, but the
+behavior of this method is adjusted depending on the connection properties
+(such as character encoding).</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id47" id="id2" name="id2">4.14 escape_bytea - escape binary data for use within SQL as type <cite>bytea</cite></a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+escape_bytea(datastring)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">datastring:</th><td class="field-body">string containing the binary data that is to be escaped</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">str:</th><td class="field-body">the escaped string</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>Similar to the module function with the same name, but the
+behavior of this method is adjusted depending on the connection properties
+(in particular, whether standard-conforming strings are enabled).</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id48" id="id3" name="id3">4.15 unescape_bytea -- unescape <cite>bytea</cite> data that has been retrieved as text</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+unescape_bytea(string)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">datastring:</th><td class="field-body">the <cite>bytea</cite> data string that has been retrieved as text</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">str:</th><td class="field-body">string containing the binary data</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>See the module function with the same name.</dd>
+</dl>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id49" id="pgqueryobject-methods" name="pgqueryobject-methods">5 pgqueryobject methods</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id50" id="getresult-get-query-values-as-list-of-tuples" name="getresult-get-query-values-as-list-of-tuples">5.1 getresult - get query values as list of tuples</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+getresult()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">list:</th><td class="field-body">result values as a list of tuples</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.InternalError:</th></tr>
+<tr><td> </td><td class="field-body">invalid previous result</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the list of the values returned by the query.
+More information about this result may be accessed using listfields(),
+fieldname() and fieldnum() methods.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id51" id="dictresult-get-query-values-as-list-of-dictionaries" name="dictresult-get-query-values-as-list-of-dictionaries">5.2 dictresult - get query values as list of dictionaries</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+dictresult()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">list:</th><td class="field-body">result values as a list of dictionaries</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.InternalError:</th></tr>
+<tr><td> </td><td class="field-body">invalid previous result</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the list of the values returned by the query
+with each tuple returned as a dictionary with the field names
+used as the dictionary index.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id52" id="listfields-lists-fields-names-of-previous-query-result" name="listfields-lists-fields-names-of-previous-query-result">5.3 listfields - lists fields names of previous query result</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+listfields()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">list:</th><td class="field-body">field names</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.InternalError:</th></tr>
+<tr><td> </td><td class="field-body">invalid previous result, or lost connection</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the list of names of the fields defined for the
+query result. The fields are in the same order as the result values.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id53" id="fieldname-fieldnum-field-name-number-conversion" name="fieldname-fieldnum-field-name-number-conversion">5.4 fieldname, fieldnum - field name/number conversion</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+fieldname(i)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">i:</th><td class="field-body">field number (integer)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">string:</th><td class="field-body">field name</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection, bad parameter type, or too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name">ValueError:</th><td class="field-body">invalid field number</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.InternalError:</th></tr>
+<tr><td> </td><td class="field-body">invalid previous result, or lost connection</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method allows to find a field name from its rank number. It can be
+useful for displaying a result. The fields are in the same order as the
+result values.</dd>
+</dl>
+<p>Syntax:</p>
+<pre class="literal-block">
+fieldnum(name)
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">name:</th><td class="field-body">field name (string)</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">integer:</th><td class="field-body">field number</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">invalid connection, bad parameter type, or too many parameters</td>
+</tr>
+<tr class="field"><th class="field-name">ValueError:</th><td class="field-body">unknown field name</td>
+</tr>
+<tr class="field"><th class="field-name" colspan="2">pg.InternalError:</th></tr>
+<tr><td> </td><td class="field-body">invalid previous result, or lost connection</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns a field number from its name. It can be used to
+build a function that converts result list strings to their correct
+type, using a hardcoded table definition. The number returned is the
+field rank in the result values list.</dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id54" id="ntuples-return-number-of-tuples-in-query-object" name="ntuples-return-number-of-tuples-in-query-object">5.5 ntuples - return number of tuples in query object</a></h2>
+<p>Syntax:</p>
+<pre class="literal-block">
+ntuples()
+</pre>
+<dl class="docutils">
+<dt>Parameters:</dt>
+<dd>None</dd>
+<dt>Return type:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">integer:</th><td class="field-body">number of tuples in <cite>pgqueryobject</cite></td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Exceptions raised:</dt>
+<dd><table class="first last docutils field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">TypeError:</th><td class="field-body">Too many arguments.</td>
+</tr>
+</tbody>
+</table>
+</dd>
+<dt>Description:</dt>
+<dd>This method returns the number of tuples found in a query.</dd>
+</dl>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id55" i
<TRUNCATED>
[5/9] incubator-hawq git commit: HAWQ-672. Add python module pygresql
back into hawq workspace
Posted by od...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.txt
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.txt b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.txt
new file mode 100644
index 0000000..ce98629
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.txt
@@ -0,0 +1,1382 @@
+================================
+PyGreSQL Programming Information
+================================
+
+------------------------------------------
+The classic PyGreSQL interface (pg module)
+------------------------------------------
+
+.. meta::
+ :description: The classic PyGreSQL interface (pg module)
+ :keywords: PyGreSQL, pg, PostGreSQL, Python
+
+.. sectnum::
+.. contents:: Contents
+
+
+Introduction
+============
+You may either choose to use the
+`"classic" PyGreSQL interface <pg.html>`_
+provided by the `pg` module or else the
+`DB-API 2.0 compliant interface <pgdb.html>`_
+provided by the `pgdb` module.
+
+The following documentation covers only the older `pg` API.
+
+The `pg` module handles three types of objects,
+
+- the `pgobject`, which handles the connection
+ and all the requests to the database,
+- the `pglarge` object, which handles
+ all the accesses to PostgreSQL large objects,
+- the `pgqueryobject` that handles query results
+
+and it provides a convenient wrapper class `DB` for the `pgobject`.
+
+If you want to see a simple example of the use of some of these functions,
+see http://ontario.bikerides.ca where you can find a link at the bottom to the
+actual Python code for the page.
+
+
+Module functions and constants
+==============================
+The `pg` module defines a few functions that allow to connect
+to a database and to define "default variables" that override
+the environment variables used by PostgreSQL.
+
+These "default variables" were designed to allow you to handle general
+connection parameters without heavy code in your programs. You can prompt the
+user for a value, put it in the default variable, and forget it, without
+having to modify your environment. The support for default variables can be
+disabled by setting the -DNO_DEF_VAR option in the Python setup file. Methods
+relative to this are specified by the tag [DV].
+
+All variables are set to `None` at module initialization, specifying that
+standard environment variables should be used.
+
+connect - opens a pg connection
+-------------------------------
+Syntax::
+
+ connect([dbname], [host], [port], [opt], [tty], [user], [passwd])
+
+Parameters:
+ :dbname: name of connected database (string/None)
+ :host: name of the server host (string/None)
+ :port: port used by the database server (integer/-1)
+ :opt: connection options (string/None)
+ :tty: debug terminal (string/None)
+ :user: PostgreSQL user (string/None)
+ :passwd: password for user (string/None)
+
+Return type:
+ :pgobject: If successful, the `pgobject` handling the connection
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+ :SyntaxError: duplicate argument definition
+ :pg.InternalError: some error occurred during pg connection definition
+
+ (plus all exceptions relative to object allocation)
+
+Description:
+ This function opens a connection to a specified database on a given
+ PostgreSQL server. You can use keywords here, as described in the
+ Python tutorial. The names of the keywords are the name of the
+ parameters given in the syntax line. For a precise description
+ of the parameters, please refer to the PostgreSQL user manual.
+
+Examples::
+
+ import pg
+
+ con1 = pg.connect('testdb', 'myhost', 5432, None, None, 'bob', None)
+ con2 = pg.connect(dbname='testdb', host='localhost', user='bob')
+
+get_defhost, set_defhost - default server host [DV]
+---------------------------------------------------
+Syntax::
+
+ get_defhost()
+
+Parameters:
+ None
+
+Return type:
+ :string, None: default host specification
+
+Exceptions raised:
+ :TypeError: too many arguments
+
+Description:
+ This method returns the current default host specification,
+ or `None` if the environment variables should be used.
+ Environment variables won't be looked up.
+
+Syntax::
+
+ set_defhost(host)
+
+Parameters:
+ :host: new default host (string/None)
+
+Return type:
+ :string, None: previous default host specification
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+
+Description:
+ This methods sets the default host value for new connections.
+ If `None` is supplied as parameter, environment variables will
+ be used in future connections. It returns the previous setting
+ for default host.
+
+get_defport, set_defport - default server port [DV]
+---------------------------------------------------
+Syntax::
+
+ get_defport()
+
+Parameters:
+ None
+
+Return type:
+ :integer, None: default port specification
+
+Exceptions raised:
+ :TypeError: too many arguments
+
+Description:
+ This method returns the current default port specification,
+ or `None` if the environment variables should be used.
+ Environment variables won't be looked up.
+
+Syntax::
+
+ set_defport(port)
+
+Parameters:
+ :port: new default port (integer/-1)
+
+Return type:
+ :integer, None: previous default port specification
+
+Description:
+ This methods sets the default port value for new connections. If -1 is
+ supplied as parameter, environment variables will be used in future
+ connections. It returns the previous setting for default port.
+
+get_defopt, set_defopt - default connection options [DV]
+--------------------------------------------------------
+Syntax::
+
+ get_defopt()
+
+Parameters:
+ None
+
+Return type:
+ :string, None: default options specification
+
+Exceptions raised:
+ :TypeError: too many arguments
+
+Description:
+ This method returns the current default connection options specification,
+ or `None` if the environment variables should be used. Environment variables
+ won't be looked up.
+
+Syntax::
+
+ set_defopt(options)
+
+Parameters:
+ :options: new default connection options (string/None)
+
+Return type:
+ :string, None: previous default options specification
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+
+Description:
+ This methods sets the default connection options value for new connections.
+ If `None` is supplied as parameter, environment variables will be used in
+ future connections. It returns the previous setting for default options.
+
+get_deftty, set_deftty - default debug tty [DV]
+-----------------------------------------------
+Syntax::
+
+ get_deftty()
+
+Parameters:
+ None
+
+Return type:
+ :string, None: default debug terminal specification
+
+Exceptions raised:
+ :TypeError: too many arguments
+
+Description:
+ This method returns the current default debug terminal specification, or
+ `None` if the environment variables should be used. Environment variables
+ won't be looked up.
+
+Syntax::
+
+ set_deftty(terminal)
+
+Parameters:
+ :terminal: new default debug terminal (string/None)
+
+Return type:
+ :string, None: previous default debug terminal specification
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+
+Description:
+ This methods sets the default debug terminal value for new connections. If
+ `None` is supplied as parameter, environment variables will be used in future
+ connections. It returns the previous setting for default terminal.
+
+get_defbase, set_defbase - default database name [DV]
+-----------------------------------------------------
+Syntax::
+
+ get_defbase()
+
+Parameters:
+ None
+
+Return type:
+ :string, None: default database name specification
+
+Exceptions raised:
+ :TypeError: too many arguments
+
+Description:
+ This method returns the current default database name specification, or
+ `None` if the environment variables should be used. Environment variables
+ won't be looked up.
+
+Syntax::
+
+ set_defbase(base)
+
+Parameters:
+ :base: new default base name (string/None)
+
+Return type:
+ :string, None: previous default database name specification
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+
+Description:
+ This method sets the default database name value for new connections. If
+ `None` is supplied as parameter, environment variables will be used in
+ future connections. It returns the previous setting for default host.
+
+escape_string - escape a string for use within SQL
+--------------------------------------------------
+Syntax::
+
+ escape_string(string)
+
+Parameters:
+ :string: the string that is to be escaped
+
+Return type:
+ :str: the escaped string
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+
+Description:
+ This function escapes a string for use within an SQL command.
+ This is useful when inserting data values as literal constants
+ in SQL commands. Certain characters (such as quotes and backslashes)
+ must be escaped to prevent them from being interpreted specially
+ by the SQL parser. `escape_string` performs this operation.
+ Note that there is also a `pgobject` method with the same name
+ which takes connection properties into account.
+
+.. caution:: It is especially important to do proper escaping when
+ handling strings that were received from an untrustworthy source.
+ Otherwise there is a security risk: you are vulnerable to "SQL injection"
+ attacks wherein unwanted SQL commands are fed to your database.
+
+Example::
+
+ name = raw_input("Name? ")
+ phone = con.query("select phone from employees"
+ " where name='%s'" % escape_string(name)).getresult()
+
+escape_bytea - escape binary data for use within SQL as type `bytea`
+--------------------------------------------------------------------
+Syntax::
+
+ escape_bytea(datastring)
+
+Parameters:
+ :datastring: string containing the binary data that is to be escaped
+
+Return type:
+ :str: the escaped string
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+
+Description:
+ Escapes binary data for use within an SQL command with the type `bytea`.
+ As with `escape_string`, this is only used when inserting data directly
+ into an SQL command string.
+ Note that there is also a `pgobject` method with the same name
+ which takes connection properties into account.
+
+Example::
+
+ picture = file('garfield.gif', 'rb').read()
+ con.query("update pictures set img='%s' where name='Garfield'"
+ % escape_bytea(picture))
+
+unescape_bytea -- unescape `bytea` data that has been retrieved as text
+-----------------------------------------------------------------------
+Syntax::
+
+ unescape_bytea(string)
+
+Parameters:
+ :datastring: the `bytea` data string that has been retrieved as text
+
+Return type:
+ :str: string containing the binary data
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+
+Description:
+ Converts an escaped string representation of binary data into binary
+ data - the reverse of `escape_bytea`. This is needed when retrieving
+ `bytea` data with the `getresult()` or `dictresult()` method.
+
+Example::
+
+ picture = unescape_bytea(con.query(
+ "select img from pictures where name='Garfield'").getresult[0][0])
+ file('garfield.gif', 'wb').write(picture)
+
+set_decimal -- set a decimal type to be used for numeric values
+---------------------------------------------------------------
+Syntax::
+
+ set_decimal(cls)
+
+Parameters:
+ :cls: the Python class to be used for PostgreSQL numeric values
+
+Description:
+ This function can be used to specify the Python class that shall be
+ used by PyGreSQL to hold PostgreSQL numeric values. The default class
+ is decimal.Decimal if available, otherwise the float type is used.
+
+Module constants
+----------------
+Some constants are defined in the module dictionary.
+They are intended to be used as parameters for methods calls.
+You should refer to the libpq description in the PostgreSQL user manual
+for more information about them. These constants are:
+
+:version, __version__: constants that give the current version.
+:INV_READ, INV_WRITE: large objects access modes,
+ used by `(pgobject.)locreate` and `(pglarge.)open`
+:SEEK_SET, SEEK_CUR, SEEK_END: positional flags,
+ used by `(pglarge.)seek`
+
+
+Connection objects: pgobject
+============================
+This object handles a connection to a PostgreSQL database. It embeds and
+hides all the parameters that define this connection, thus just leaving really
+significant parameters in function calls.
+
+.. caution:: Some methods give direct access to the connection socket.
+ *Do not use them unless you really know what you are doing.*
+ If you prefer disabling them,
+ set the -DNO_DIRECT option in the Python setup file.
+
+ **These methods are specified by the tag [DA].**
+
+.. note:: Some other methods give access to large objects
+ (refer to PostgreSQL user manual for more information about these).
+ If you want to forbid access to these from the module,
+ set the -DNO_LARGE option in the Python setup file.
+
+ **These methods are specified by the tag [LO].**
+
+query - executes a SQL command string
+-------------------------------------
+Syntax::
+
+ query(command)
+
+Parameters:
+ :command: SQL command (string)
+
+Return type:
+ :pgqueryobject, None: result values
+
+Exceptions raised:
+ :TypeError: bad argument type, or too many arguments
+ :ValueError: empty SQL query or lost connection
+ :pg.ProgrammingError: error in query
+ :pg.InternalError': error during query processing
+
+Description:
+ This method simply sends a SQL query to the database. If the query is an
+ insert statement that inserted exactly one row into a table that has OIDs, the
+ return value is the OID of the newly inserted row. If the query is an update
+ or delete statement, or an insert statement that did not insert exactly one
+ row in a table with OIDs, then the numer of rows affected is returned as a
+ string. If it is a statement that returns rows as a result (usually a select
+ statement, but maybe also an "insert/update ... returning" statement), this
+ method returns a `pgqueryobject` that can be accessed via the `getresult()`
+ or `dictresult()` method or simply printed. Otherwise, it returns `None`.
+
+reset - resets the connection
+-----------------------------
+Syntax::
+
+ reset()
+
+Parameters:
+ None
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: too many (any) arguments
+
+Description:
+ This method resets the current database connection.
+
+cancel - abandon processing of current SQL command
+--------------------------------------------------
+Syntax::
+
+ cancel()
+
+Parameters:
+ None
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: too many (any) arguments
+
+Description:
+ This method requests that the server abandon processing
+ of the current SQL command.
+
+close - close the database connection
+-------------------------------------
+Syntax::
+
+ close()
+
+Parameters:
+ None
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: too many (any) arguments
+
+Description:
+ This method closes the database connection. The connection will
+ be closed in any case when the connection is deleted but this
+ allows you to explicitly close it. It is mainly here to allow
+ the DB-SIG API wrapper to implement a close function.
+
+fileno - returns the socket used to connect to the database
+-----------------------------------------------------------
+Syntax::
+
+ fileno()
+
+Parameters:
+ None
+
+Exceptions raised:
+ :TypeError: too many (any) arguments
+
+Description:
+ This method returns the underlying socket id used to connect
+ to the database. This is useful for use in select calls, etc.
+
+getnotify - gets the last notify from the server
+------------------------------------------------
+Syntax::
+
+ getnotify()
+
+Parameters:
+ None
+
+Return type:
+ :tuple, None: last notify from server
+
+Exceptions raised:
+ :TypeError: too many parameters
+ :TypeError: invalid connection
+
+Description:
+ This methods try to get a notify from the server (from the SQL statement
+ NOTIFY). If the server returns no notify, the methods returns None.
+ Otherwise, it returns a tuple (couple) `(relname, pid)`, where `relname`
+ is the name of the notify and `pid` the process id of the connection that
+ triggered the notify. Remember to do a listen query first otherwise
+ getnotify() will always return `None`.
+
+inserttable - insert a list into a table
+----------------------------------------
+Syntax::
+
+ inserttable(table, values)
+
+Parameters:
+ :table: the table name (string)
+ :values: list of rows values (list)
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection, bad argument type, or too many arguments
+ :MemoryError: insert buffer could not be allocated
+ :ValueError: unsupported values
+
+Description:
+ This method allow to *quickly* insert large blocks of data in a table:
+ It inserts the whole values list into the given table. Internally, it
+ uses the COPY command of the PostgreSQL database. The list is a list
+ of tuples/lists that define the values for each inserted row. The rows
+ values may contain string, integer, long or double (real) values.
+
+.. caution:: *Be very careful*:
+ This method doesn't typecheck the fields according to the table definition;
+ it just look whether or not it knows how to handle such types.
+
+putline - writes a line to the server socket [DA]
+-------------------------------------------------
+Syntax::
+
+ putline(line)
+
+Parameters:
+ :line: line to be written (string)
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection, bad parameter type, or too many parameters
+
+Description:
+ This method allows to directly write a string to the server socket.
+
+getline - gets a line from server socket [DA]
+---------------------------------------------
+Syntax::
+
+ getline()
+
+Parameters:
+ None
+
+Return type:
+ :string: the line read
+
+Exceptions raised:
+ :TypeError: invalid connection
+ :TypeError: too many parameters
+ :MemoryError: buffer overflow
+
+Description:
+ This method allows to directly read a string from the server socket.
+
+endcopy - synchronizes client and server [DA]
+---------------------------------------------
+Syntax::
+
+ endcopy()
+
+Parameters:
+ None
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection
+ :TypeError: too many parameters
+
+Description:
+ The use of direct access methods may desynchonize client and server.
+ This method ensure that client and server will be synchronized.
+
+locreate - create a large object in the database [LO]
+-----------------------------------------------------
+Syntax::
+
+ locreate(mode)
+
+Parameters:
+ :mode: large object create mode
+
+Return type:
+ :pglarge: object handling the PostGreSQL large object
+
+Exceptions raised:
+
+ :TypeError: invalid connection, bad parameter type, or too many parameters
+ :pg.OperationalError: creation error
+
+Description:
+ This method creates a large object in the database. The mode can be defined
+ by OR-ing the constants defined in the pg module (INV_READ, INV_WRITE and
+ INV_ARCHIVE). Please refer to PostgreSQL user manual for a description of
+ the mode values.
+
+getlo - build a large object from given oid [LO]
+------------------------------------------------
+Syntax::
+
+ getlo(oid)
+
+Parameters:
+ :oid: OID of the existing large object (integer)
+
+Return type:
+ :pglarge: object handling the PostGreSQL large object
+
+Exceptions raised:
+ :TypeError: invalid connection, bad parameter type, or too many parameters
+ :ValueError: bad OID value (0 is invalid_oid)
+
+Description:
+ This method allows to reuse a formerly created large object through the
+ `pglarge` interface, providing the user have its OID.
+
+loimport - import a file to a large object [LO]
+-----------------------------------------------
+Syntax::
+
+ loimport(name)
+
+Parameters:
+ :name: the name of the file to be imported (string)
+
+Return type:
+ :pglarge: object handling the PostGreSQL large object
+
+Exceptions raised:
+ :TypeError: invalid connection, bad argument type, or too many arguments
+ :pg.OperationalError: error during file import
+
+Description:
+ This methods allows to create large objects in a very simple way. You just
+ give the name of a file containing the data to be use.
+
+Object attributes
+-----------------
+Every `pgobject` defines a set of read-only attributes that describe the
+connection and its status. These attributes are:
+
+ :host: the host name of the server (string)
+ :port: the port of the server (integer)
+ :db: the selected database (string)
+ :options: the connection options (string)
+ :tty: the connection debug terminal (string)
+ :user: user name on the database system (string)
+ :protocol_version: the frontend/backend protocol being used (integer)
+ :server_version: the backend version (integer, e.g. 80305 for 8.3.5)
+ :status: the status of the connection (integer: 1 - OK, 0 - bad)
+ :error: the last warning/error message from the server (string)
+
+
+The DB wrapper class
+====================
+The `pgobject` methods are wrapped in the class `DB`.
+The preferred way to use this module is as follows::
+
+ import pg
+
+ db = pg.DB(...) # see below
+
+ for r in db.query( # just for example
+ """SELECT foo,bar
+ FROM foo_bar_table
+ WHERE foo !~ bar"""
+ ).dictresult():
+
+ print '%(foo)s %(bar)s' % r
+
+This class can be subclassed as in this example::
+
+ import pg
+
+ class DB_ride(pg.DB):
+ """This class encapsulates the database functions and the specific
+ methods for the ride database."""
+
+ def __init__(self):
+ """Opens a database connection to the rides database"""
+
+ pg.DB.__init__(self, dbname = 'ride')
+ self.query("""SET DATESTYLE TO 'ISO'""")
+
+ [Add or override methods here]
+
+The following describes the methods and variables of this class.
+
+Initialization
+--------------
+The DB class is initialized with the same arguments as the connect
+function described in section 2. It also initializes a few
+internal variables. The statement `db = DB()` will open the
+local database with the name of the user just like connect() does.
+
+You can also initialize the DB class with an existing `_pg` or `pgdb`
+connection. Pass this connection as a single unnamed parameter, or as a
+single parameter named `db`. This allows you to use all of the methods
+of the DB class with a DB-API 2 compliant connection. Note that the
+`close()` and `reopen()` methods are inoperative in this case.
+
+
+
+pkey - return the primary key of a table
+----------------------------------------
+Syntax::
+
+ pkey(table)
+
+Parameters:
+ :table: name of table
+
+Return type:
+ :string: Name of the field which is the primary key of the table
+
+Description:
+ This method returns the primary key of a table. For composite primary
+ keys, the return value will be a frozenset. Note that this raises an
+ exception if the table does not have a primary key.
+
+get_databases - get list of databases in the system
+---------------------------------------------------
+Syntax::
+
+ get_databases()
+
+Parameters:
+ None
+
+Return type:
+ :list: all databases in the system
+
+Description:
+ Although you can do this with a simple select, it is added here for
+ convenience.
+
+get_relations - get list of relations in connected database
+-----------------------------------------------------------
+Syntax::
+
+ get_relations(kinds)
+
+Parameters:
+ :kinds: a string or sequence of type letters
+
+Description:
+ The type letters are `r` = ordinary table, `i` = index, `S` = sequence,
+ `v` = view, `c` = composite type, `s` = special, `t` = TOAST table.
+ If `kinds` is None or an empty string, all relations are returned (this is
+ also the default). Although you can do this with a simple select, it is
+ added here for convenience.
+
+get_tables - get list of tables in connected database
+-----------------------------------------------------
+Syntax::
+
+ get_tables()
+
+Parameters:
+ None
+
+Returns:
+ :list: all tables in connected database
+
+Description:
+ Although you can do this with a simple select, it is added here for
+ convenience.
+
+get_attnames - get the attribute names of a table
+-------------------------------------------------
+Syntax::
+
+ get_attnames(table)
+
+Parameters:
+ :table: name of table
+
+Returns:
+ :dictionary: The keys are the attribute names,
+ the values are the type names of the attributes.
+
+Description:
+ Given the name of a table, digs out the set of attribute names.
+
+has_table_privilege - check whether current user has specified table privilege
+------------------------------------------------------------------------------
+Syntax::
+
+ has_table_privilege(table, privilege)
+
+Parameters:
+ :table: name of table
+ :privilege: privilege to be checked - default is 'select'
+
+Description:
+ Returns True if the current user has the specified privilege for the table.
+
+get - get a row from a database table or view
+---------------------------------------------
+Syntax::
+
+ get(table, arg, [keyname])
+
+Parameters:
+ :table: name of table or view
+ :arg: either a dictionary or the value to be looked up
+ :keyname: name of field to use as key (optional)
+
+Return type:
+ :dictionary: The keys are the attribute names,
+ the values are the row values.
+
+Description:
+ This method is the basic mechanism to get a single row. It assumes
+ that the key specifies a unique row. If `keyname` is not specified
+ then the primary key for the table is used. If `arg` is a dictionary
+ then the value for the key is taken from it and it is modified to
+ include the new values, replacing existing values where necessary.
+ For a composite key, `keyname` can also be a sequence of key names.
+ The OID is also put into the dictionary if the table has one, but in
+ order to allow the caller to work with multiple tables, it is munged
+ as `oid(schema.table)`.
+
+insert - insert a row into a database table
+-------------------------------------------
+Syntax::
+
+ insert(table, [d,] [return_changes,] [key = val, ...])
+
+Parameters:
+ :table: name of table
+ :d: optional dictionary of values
+ :return_changes: Return values in new row - default True
+
+Return type:
+ :dictionary: The dictionary of values inserted
+
+Description:
+ This method inserts a row into a table. If the optional dictionary is
+ not supplied then the required values must be included as keyword/value
+ pairs. If a dictionary is supplied then any keywords provided will be
+ added to or replace the entry in the dictionary.
+
+ The dictionary is then, if possible, reloaded with the values actually
+ inserted in order to pick up values modified by rules, triggers, etc.
+
+ Due to the way that this function works in PostgreSQL versions below
+ 8.2, you may find inserts taking longer and longer as your table gets
+ bigger. If this happens and it is a table with OID but no primary key
+ you can overcome this problem by simply adding an index onto the OID of
+ any table that you think may get large over time. You may also consider
+ using the inserttable() method described in section 3.
+
+ Note: With PostgreSQL versions before 8.2 the table being inserted to
+ must have a primary key or an OID to use this method properly. If not
+ then the dictionary will not be filled in as described. Also, if this
+ method is called within a transaction, the transaction will abort.
+
+ Note: The method currently doesn't support insert into views
+ although PostgreSQL does.
+
+update - update a row in a database table
+-----------------------------------------
+Syntax::
+
+ update(table, [d,] [key = val, ...])
+
+Parameters:
+ :table: name of table
+ :d: optional dictionary of values
+
+Return type:
+ :dictionary: the new row
+
+Description:
+ Similar to insert but updates an existing row. The update is based on the
+ OID value as munged by get or passed as keyword, or on the primary key of
+ the table. The dictionary is modified, if possible, to reflect any changes
+ caused by the update due to triggers, rules, default values, etc.
+
+ Like insert, the dictionary is optional and updates will be performed
+ on the fields in the keywords. There must be an OID or primary key
+ either in the dictionary where the OID must be munged, or in the keywords
+ where it can be simply the string "oid".
+
+clear - clears row values in memory
+-----------------------------------
+Syntax::
+
+ clear(table, [a])
+
+Parameters:
+ :table: name of table
+ :a: optional dictionary of values
+
+Return type:
+ :dictionary: an empty row
+
+Description:
+ This method clears all the attributes to values determined by the types.
+ Numeric types are set to 0, Booleans are set to 'f', dates are set
+ to 'now()' and everything else is set to the empty string.
+ If the array argument is present, it is used as the array and any entries
+ matching attribute names are cleared with everything else left unchanged.
+
+ If the dictionary is not supplied a new one is created.
+
+delete - delete a row from a database table
+-------------------------------------------
+Syntax::
+
+ delete(table, [d,] [key = val, ...])
+
+Parameters:
+ :table: name of table
+ :d: optional dictionary of values
+
+Returns:
+ None
+
+Description:
+ This method deletes the row from a table. It deletes based on the OID value
+ as munged by get or passed as keyword, or on the primary key of the table.
+ The return value is the number of deleted rows (i.e. 0 if the row did not
+ exist and 1 if the row was deleted).
+
+escape_string - escape a string for use within SQL
+--------------------------------------------------
+Syntax::
+
+ escape_string(string)
+
+Parameters:
+ :string: the string that is to be escaped
+
+Return type:
+ :str: the escaped string
+
+Description:
+ Similar to the module function with the same name, but the
+ behavior of this method is adjusted depending on the connection properties
+ (such as character encoding).
+
+escape_bytea - escape binary data for use within SQL as type `bytea`
+--------------------------------------------------------------------
+Syntax::
+
+ escape_bytea(datastring)
+
+Parameters:
+ :datastring: string containing the binary data that is to be escaped
+
+Return type:
+ :str: the escaped string
+
+Description:
+ Similar to the module function with the same name, but the
+ behavior of this method is adjusted depending on the connection properties
+ (in particular, whether standard-conforming strings are enabled).
+
+unescape_bytea -- unescape `bytea` data that has been retrieved as text
+-----------------------------------------------------------------------
+Syntax::
+
+ unescape_bytea(string)
+
+Parameters:
+ :datastring: the `bytea` data string that has been retrieved as text
+
+Return type:
+ :str: string containing the binary data
+
+Description:
+ See the module function with the same name.
+
+
+pgqueryobject methods
+=====================
+
+getresult - get query values as list of tuples
+-----------------------------------------------
+Syntax::
+
+ getresult()
+
+Parameters:
+ None
+
+Return type:
+ :list: result values as a list of tuples
+
+Exceptions raised:
+ :TypeError: too many parameters
+ :pg.InternalError: invalid previous result
+
+Description:
+ This method returns the list of the values returned by the query.
+ More information about this result may be accessed using listfields(),
+ fieldname() and fieldnum() methods.
+
+dictresult - get query values as list of dictionaries
+-----------------------------------------------------
+Syntax::
+
+ dictresult()
+
+Parameters:
+ None
+
+Return type:
+ :list: result values as a list of dictionaries
+
+Exceptions raised:
+ :TypeError: too many parameters
+ :pg.InternalError: invalid previous result
+
+Description:
+ This method returns the list of the values returned by the query
+ with each tuple returned as a dictionary with the field names
+ used as the dictionary index.
+
+
+listfields - lists fields names of previous query result
+--------------------------------------------------------
+Syntax::
+
+ listfields()
+
+Parameters:
+ None
+
+Return type:
+ :list: field names
+
+Exceptions raised:
+ :TypeError: too many parameters
+ :pg.InternalError: invalid previous result, or lost connection
+
+Description:
+ This method returns the list of names of the fields defined for the
+ query result. The fields are in the same order as the result values.
+
+fieldname, fieldnum - field name/number conversion
+--------------------------------------------------
+Syntax::
+
+ fieldname(i)
+
+Parameters:
+ :i: field number (integer)
+
+Return type:
+ :string: field name
+
+Exceptions raised:
+ :TypeError: invalid connection, bad parameter type, or too many parameters
+ :ValueError: invalid field number
+ :pg.InternalError: invalid previous result, or lost connection
+
+Description:
+ This method allows to find a field name from its rank number. It can be
+ useful for displaying a result. The fields are in the same order as the
+ result values.
+
+Syntax::
+
+ fieldnum(name)
+
+Parameters:
+ :name: field name (string)
+
+Return type:
+ :integer: field number
+
+Exceptions raised:
+ :TypeError: invalid connection, bad parameter type, or too many parameters
+ :ValueError: unknown field name
+ :pg.InternalError: invalid previous result, or lost connection
+
+Description:
+ This method returns a field number from its name. It can be used to
+ build a function that converts result list strings to their correct
+ type, using a hardcoded table definition. The number returned is the
+ field rank in the result values list.
+
+ntuples - return number of tuples in query object
+-------------------------------------------------
+Syntax::
+
+ ntuples()
+
+Parameters:
+ None
+
+Return type:
+ :integer: number of tuples in `pgqueryobject`
+
+Exceptions raised:
+ :TypeError: Too many arguments.
+
+Description:
+ This method returns the number of tuples found in a query.
+
+
+Large objects: pglarge
+======================
+This object handles all the request concerning a PostgreSQL large object. It
+embeds and hides all the "recurrent" variables (object OID and connection),
+exactly in the same way `pgobjects` do, thus only keeping significant
+parameters in function calls. It keeps a reference to the `pgobject` used for
+its creation, sending requests though with its parameters. Any modification but
+dereferencing the `pgobject` will thus affect the `pglarge` object.
+Dereferencing the initial `pgobject` is not a problem since Python won't
+deallocate it before the `pglarge` object dereference it.
+All functions return a generic error message on call error, whatever the
+exact error was. The `error` attribute of the object allow to get the exact
+error message.
+
+See also the PostgreSQL programmer's guide for more information about the
+large object interface.
+
+open - opens a large object
+---------------------------
+Syntax::
+
+ open(mode)
+
+Parameters:
+ :mode: open mode definition (integer)
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection, bad parameter type, or too many parameters
+ :IOError: already opened object, or open error
+
+Description:
+ This method opens a large object for reading/writing, in the same way than
+ the Unix open() function. The mode value can be obtained by OR-ing the
+ constants defined in the pgmodule (INV_READ, INV_WRITE).
+
+close - closes a large object
+-----------------------------
+Syntax::
+
+ close()
+
+Parameters:
+ None
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection
+ :TypeError: too many parameters
+ :IOError: object is not opened, or close error
+
+Description:
+ This method closes a previously opened large object, in the same way than
+ the Unix close() function.
+
+read, write, tell, seek, unlink - file like large object handling
+-----------------------------------------------------------------
+Syntax::
+
+ read(size)
+
+Parameters:
+ :size: maximal size of the buffer to be read
+
+Return type:
+ :sized string: the read buffer
+
+Exceptions raised:
+ :TypeError: invalid connection, invalid object,
+ bad parameter type, or too many parameters
+ :ValueError: if `size` is negative
+ :IOError: object is not opened, or read error
+
+Description:
+ This function allows to read data from a large object, starting at current
+ position.
+
+Syntax::
+
+ write(string)
+
+Parameters:
+ (sized) string - buffer to be written
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection, bad parameter type, or too many parameters
+ :IOError: object is not opened, or write error
+
+Description:
+ This function allows to write data to a large object, starting at current
+ position.
+
+Syntax::
+
+ seek(offset, whence)
+
+Parameters:
+ :offset: position offset
+ :whence: positional parameter
+
+Return type:
+ :integer: new position in object
+
+Exceptions raised:
+ :TypeError: binvalid connection or invalid object,
+ bad parameter type, or too many parameters
+ :IOError: object is not opened, or seek error
+
+Description:
+ This method allows to move the position cursor in the large object. The
+ whence parameter can be obtained by OR-ing the constants defined in the
+ `pg` module (`SEEK_SET`, `SEEK_CUR`, `SEEK_END`).
+
+Syntax::
+
+ tell()
+
+Parameters:
+ None
+
+Return type:
+ :integer: current position in large object
+
+Exceptions raised:
+ :TypeError: invalid connection or invalid object
+ :TypeError: too many parameters
+ :IOError: object is not opened, or seek error
+
+Description:
+ This method allows to get the current position in the large object.
+
+Syntax::
+
+ unlink()
+
+Parameter:
+ None
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection or invalid object
+ :TypeError: too many parameters
+ :IOError: object is not closed, or unlink error
+
+Description:
+ This methods unlinks (deletes) the PostgreSQL large object.
+
+size - gives the large object size
+----------------------------------
+
+Syntax::
+
+ size()
+
+Parameters:
+ None
+
+Return type:
+ :integer: the large object size
+
+Exceptions raised:
+ :TypeError: invalid connection or invalid object
+ :TypeError: too many parameters
+ :IOError: object is not opened, or seek/tell error
+
+Description:
+ This (composite) method allows to get the size of a large object. It was
+ implemented because this function is very useful for a web interfaced
+ database. Currently, the large object needs to be opened first.
+
+export - saves a large object to a file
+---------------------------------------
+Syntax::
+
+ export(name)
+
+Parameters:
+ :name: file to be created
+
+Return type:
+ None
+
+Exceptions raised:
+ :TypeError: invalid connection or invalid object,
+ bad parameter type, or too many parameters
+ :IOError: object is not closed, or export error
+
+Description:
+ This methods allows to dump the content of a large object in a very simple
+ way. The exported file is created on the host of the program, not the
+ server host.
+
+Object attributes
+-----------------
+`pglarge` objects define a read-only set of attributes that allow to get
+some information about it. These attributes are:
+
+ :oid: the OID associated with the object
+ :pgcnx: the `pgobject` associated with the object
+ :error: the last warning/error message of the connection
+
+.. caution:: *Be careful*:
+ In multithreaded environments, `error` may be modified by another thread
+ using the same pgobject. Remember these object are shared, not duplicated.
+ You should provide some locking to be able if you want to check this.
+ The `oid` attribute is very interesting because it allow you reuse the OID
+ later, creating the `pglarge` object with a `pgobject` getlo() method call.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.html
new file mode 100644
index 0000000..84962f4
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>PyGreSQL Programming Information</title>
+<meta content="The DB-API compliant interface (pgdb module)" name="description" />
+<meta content="PyGreSQL, pgdb, DB-API, PostGreSQL, Python" name="keywords" />
+<link rel="stylesheet" href="docs.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="pygresql-programming-information">
+<h1 class="title">PyGreSQL Programming Information</h1>
+<h2 class="subtitle" id="the-db-api-compliant-interface-pgdb-module">The DB-API compliant interface (pgdb module)</h2>
+<div class="contents topic">
+<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
+<ul class="auto-toc simple">
+<li><a class="reference" href="#introduction" id="id1" name="id1">1 Introduction</a></li>
+<li><a class="reference" href="#the-pgdb-module" id="id2" name="id2">2 The pgdb module</a></li>
+</ul>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id1" id="introduction" name="introduction">1 Introduction</a></h1>
+<p>You may either choose to use the
+<a class="reference" href="pg.html">"classic" PyGreSQL interface</a>
+provided by the <cite>pg</cite> module or else the
+<a class="reference" href="pgdb.html">DB-API 2.0 compliant interface</a>
+provided by the <cite>pgdb</cite> module.</p>
+<p><a class="reference" href="http://www.python.org/dev/peps/pep-0249/">DB-API 2.0</a>
+(Python Database API Specification v2.0)
+is a specification for connecting to databases (not only PostGreSQL)
+from Python that has been developed by the Python DB-SIG in 1999.</p>
+<p>The following documentation covers only the newer <cite>pgdb</cite> API.</p>
+<dl class="docutils">
+<dt>The authoritative programming information for the DB-API is availabe at</dt>
+<dd><a class="reference" href="http://www.python.org/dev/peps/pep-0249/">http://www.python.org/dev/peps/pep-0249/</a></dd>
+<dt>A tutorial-like introduction to the DB-API can be found at</dt>
+<dd><a class="reference" href="http://www2.linuxjournal.com/lj-issues/issue49/2605.html">http://www2.linuxjournal.com/lj-issues/issue49/2605.html</a></dd>
+</dl>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id2" id="the-pgdb-module" name="the-pgdb-module">2 The pgdb module</a></h1>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">This section of the documentation still needs to be written.</p>
+</div>
+</div>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.txt
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.txt b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.txt
new file mode 100644
index 0000000..b333c01
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.txt
@@ -0,0 +1,42 @@
+================================
+PyGreSQL Programming Information
+================================
+
+--------------------------------------------
+The DB-API compliant interface (pgdb module)
+--------------------------------------------
+
+.. meta::
+ :description: The DB-API compliant interface (pgdb module)
+ :keywords: PyGreSQL, pgdb, DB-API, PostGreSQL, Python
+
+.. sectnum::
+.. contents:: Contents
+
+
+Introduction
+============
+You may either choose to use the
+`"classic" PyGreSQL interface <pg.html>`_
+provided by the `pg` module or else the
+`DB-API 2.0 compliant interface <pgdb.html>`_
+provided by the `pgdb` module.
+
+`DB-API 2.0 <http://www.python.org/dev/peps/pep-0249/>`_
+(Python Database API Specification v2.0)
+is a specification for connecting to databases (not only PostGreSQL)
+from Python that has been developed by the Python DB-SIG in 1999.
+
+The following documentation covers only the newer `pgdb` API.
+
+The authoritative programming information for the DB-API is availabe at
+ http://www.python.org/dev/peps/pep-0249/
+
+A tutorial-like introduction to the DB-API can be found at
+ http://www2.linuxjournal.com/lj-issues/issue49/2605.html
+
+
+The pgdb module
+===============
+.. note:: This section of the documentation still needs to be written.
+
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.html
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.html b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.html
new file mode 100644
index 0000000..656f8cd
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.html
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
+<title>PyGreSQL - Python interface for PostgreSQL</title>
+<meta content="PyGreSQL - Python interface for PostgreSQL" name="description" />
+<meta content="PyGreSQL, PostGreSQL, Python" name="keywords" />
+<link rel="stylesheet" href="docs.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="pygresql-python-interface-for-postgresql">
+<h1 class="title">PyGreSQL - Python interface for PostgreSQL</h1>
+<h2 class="subtitle" id="pygresql-version-4-0">PyGreSQL version 4.0</h2>
+<div class="contents topic">
+<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
+<ul class="simple">
+<li><a class="reference" href="#copyright-notice" id="id1" name="id1">Copyright notice</a></li>
+<li><a class="reference" href="#introduction" id="id2" name="id2">Introduction</a></li>
+<li><a class="reference" href="#where-to-get" id="id3" name="id3">Where to get ... ?</a><ul>
+<li><a class="reference" href="#home-sites-of-the-different-packages" id="id4" name="id4">Home sites of the different packages</a></li>
+<li><a class="reference" href="#download-pygresql-here" id="id5" name="id5">Download PyGreSQL here</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#distribution-files" id="id6" name="id6">Distribution files</a></li>
+<li><a class="reference" href="#installation" id="id7" name="id7">Installation</a></li>
+<li><a class="reference" href="#information-and-support" id="id8" name="id8">Information and support</a><ul>
+<li><a class="reference" href="#for-general-information" id="id9" name="id9">For general information</a></li>
+<li><a class="reference" href="#for-support" id="id10" name="id10">For support</a></li>
+<li><a class="reference" href="#pygresql-programming-information" id="id11" name="id11">PyGreSQL programming information</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#changelog-and-future" id="id12" name="id12">ChangeLog and Future</a></li>
+</ul>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id1" id="copyright-notice" name="copyright-notice">Copyright notice</a></h1>
+<p>Written by D'Arcy J.M. Cain (<a class="reference" href="mailto:darcy@druid.net">darcy@druid.net</a>)</p>
+<p>Based heavily on code written by Pascal Andre (<a class="reference" href="mailto:andre@chimay.via.ecp.fr">andre@chimay.via.ecp.fr</a>)</p>
+<p>Copyright (c) 1995, Pascal Andre</p>
+<p>Further modifications copyright (c) 1997-2008 by D'Arcy J.M. Cain
+(<a class="reference" href="mailto:darcy@druid.net">darcy@druid.net</a>)</p>
+<p>Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies or in any
+new file that contains a substantial portion of this file.</p>
+<p>IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
+<p>THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
+AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id2" id="introduction" name="introduction">Introduction</a></h1>
+<p><strong>PostgreSQL</strong> is a highly scalable, SQL compliant, open source
+object-relational database management system. With more than 15 years
+of development history, it is quickly becoming the de facto database
+for enterprise level open source solutions.
+Best of all, PostgreSQL's source code is available under the most liberal
+open source license: the BSD license.</p>
+<p><strong>Python</strong> Python is an interpreted, interactive, object-oriented
+programming language. It is often compared to Tcl, Perl, Scheme or Java.
+Python combines remarkable power with very clear syntax. It has modules,
+classes, exceptions, very high level dynamic data types, and dynamic typing.
+There are interfaces to many system calls and libraries, as well as to
+various windowing systems (X11, Motif, Tk, Mac, MFC). New built-in modules
+are easily written in C or C++. Python is also usable as an extension
+language for applications that need a programmable interface.
+The Python implementation is copyrighted but freely usable and distributable,
+even for commercial use.</p>
+<p><strong>PyGreSQL</strong> is a Python module that interfaces to a PostgreSQL database.
+It embeds the PostgreSQL query library to allow easy use of the powerful
+PostgreSQL features from a Python script.</p>
+<p>PyGreSQL is developed and tested on a NetBSD system, but it should also
+run on most other platforms where PostgreSQL and Python is running.
+It is based on the PyGres95 code written by Pascal Andre (<a class="reference" href="mailto:andre@chimay.via.ecp.fr">andre@chimay.via.ecp.fr</a>).
+D'Arcy (<a class="reference" href="mailto:darcy@druid.net">darcy@druid.net</a>) renamed it to PyGreSQL starting with
+version 2.0 and serves as the "BDFL" of PyGreSQL.</p>
+<p>The current version PyGreSQL 4.0 needs PostgreSQL 7.2 and Python 2.3 or above.</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id3" id="where-to-get" name="where-to-get">Where to get ... ?</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id4" id="home-sites-of-the-different-packages" name="home-sites-of-the-different-packages">Home sites of the different packages</a></h2>
+<dl class="docutils">
+<dt><strong>Python</strong>:</dt>
+<dd><a class="reference" href="http://www.python.org">http://www.python.org</a></dd>
+<dt><strong>PostgreSQL</strong>:</dt>
+<dd><a class="reference" href="http://www.postgresql.org">http://www.postgresql.org</a></dd>
+<dt><strong>PyGreSQL</strong>:</dt>
+<dd><a class="reference" href="http://www.pygresql.org">http://www.pygresql.org</a></dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id5" id="download-pygresql-here" name="download-pygresql-here">Download PyGreSQL here</a></h2>
+<dl class="docutils">
+<dt>The <strong>released version of the source code</strong> is available at</dt>
+<dd><ul class="first last simple">
+<li><a class="reference" href="ftp://ftp.pygresql.org/pub/distrib/PyGreSQL.tgz">ftp://ftp.pygresql.org/pub/distrib/PyGreSQL.tgz</a></li>
+</ul>
+</dd>
+<dt>You can also check the latest <strong>pre-release version</strong> at</dt>
+<dd><ul class="first last simple">
+<li><a class="reference" href="ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-beta.tgz">ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-beta.tgz</a></li>
+</ul>
+</dd>
+<dt>A <strong>Linux RPM</strong> can be picked up from</dt>
+<dd><ul class="first last simple">
+<li><a class="reference" href="ftp://ftp.pygresql.org/pub/distrib/pygresql.i386.rpm">ftp://ftp.pygresql.org/pub/distrib/pygresql.i386.rpm</a></li>
+</ul>
+</dd>
+<dt>A <strong>NetBSD package</strong> is available in their pkgsrc collection</dt>
+<dd><ul class="first last simple">
+<li><a class="reference" href="ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/databases/py-postgresql/README.html">ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/databases/py-postgresql/README.html</a></li>
+</ul>
+</dd>
+<dt>A <strong>FreeBSD package</strong> is available in their ports collection</dt>
+<dd><ul class="first last simple">
+<li><a class="reference" href="http://www.freebsd.org/cgi/cvsweb.cgi/ports/databases/py-PyGreSQL/">http://www.freebsd.org/cgi/cvsweb.cgi/ports/databases/py-PyGreSQL/</a></li>
+</ul>
+</dd>
+<dt>A <strong>Win32 package</strong> for various Python versions is available at</dt>
+<dd><ul class="first last simple">
+<li><a class="reference" href="ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.3.exe">ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.3.exe</a></li>
+<li><a class="reference" href="ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.4.exe">ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.4.exe</a></li>
+<li><a class="reference" href="ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.5.exe">ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.5.exe</a></li>
+<li><a class="reference" href="ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.6.exe">ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.6.exe</a></li>
+</ul>
+</dd>
+<dt>You can also find PyGreSQL on the <strong>Python Package Index</strong> at</dt>
+<dd><ul class="first last simple">
+<li><a class="reference" href="http://pypi.python.org/pypi/PyGreSQL/">http://pypi.python.org/pypi/PyGreSQL/</a></li>
+</ul>
+</dd>
+</dl>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id6" id="distribution-files" name="distribution-files">Distribution files</a></h1>
+<table border="1" class="docutils">
+<colgroup>
+<col width="15%" />
+<col width="85%" />
+</colgroup>
+<tbody valign="top">
+<tr><td>pgmodule.c</td>
+<td>the C Python module (_pg)</td>
+</tr>
+<tr><td>pg.py</td>
+<td>the "classic" PyGreSQL module</td>
+</tr>
+<tr><td>pgdb.py</td>
+<td>DB-SIG DB-API 2.0 compliant API wrapper for PygreSQL</td>
+</tr>
+<tr><td>docs/</td>
+<td><p class="first">documentation directory</p>
+<p>Contains: readme.txt, announce.txt, install.txt,
+changelog.txt, future.txt, pg.txt and pgdb.txt.</p>
+<p class="last">All text files are in ReST format, so HTML versions
+can be easily created with buildhtml.py from docutils.</p>
+</td>
+</tr>
+<tr><td>tutorial/</td>
+<td><p class="first">demos directory</p>
+<p>Contains: basics.py, syscat.py, advanced.py and func.py.</p>
+<p class="last">The samples here have been taken from the
+PostgreSQL manual and were used for module testing.
+They demonstrate some PostgreSQL features.</p>
+</td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id7" id="installation" name="installation">Installation</a></h1>
+<p>You will find the installing instructions in
+<a class="reference" href="install.html">install.txt</a>.</p>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id8" id="information-and-support" name="information-and-support">Information and support</a></h1>
+<div class="section">
+<h2><a class="toc-backref" href="#id9" id="for-general-information" name="for-general-information">For general information</a></h2>
+<dl class="docutils">
+<dt><strong>Python</strong>:</dt>
+<dd><a class="reference" href="http://www.python.org">http://www.python.org</a></dd>
+<dt><strong>PostgreSQL</strong>:</dt>
+<dd><a class="reference" href="http://www.postgresql.org">http://www.postgresql.org</a></dd>
+<dt><strong>PyGreSQL</strong>:</dt>
+<dd><a class="reference" href="http://www.pygresql.org">http://www.pygresql.org</a></dd>
+</dl>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id10" id="for-support" name="for-support">For support</a></h2>
+<dl class="docutils">
+<dt><strong>Python</strong>:</dt>
+<dd>see <a class="reference" href="http://www.python.org/community/">http://www.python.org/community/</a></dd>
+<dt><strong>PostgreSQL</strong>:</dt>
+<dd>see <a class="reference" href="http://www.postgresql.org/support/">http://www.postgresql.org/support/</a></dd>
+<dt><strong>PyGreSQL</strong>:</dt>
+<dd><p class="first">Contact the PyGreSQL mailing list
+concerning PyGreSQL 2.0 and up.</p>
+<p>If you would like to proposes changes, please join the
+PyGreSQL mailing list and send context diffs there.</p>
+<p class="last">See <a class="reference" href="http://mailman.vex.net/mailman/listinfo/pygresql">http://mailman.vex.net/mailman/listinfo/pygresql</a>
+to join the mailing list.</p>
+</dd>
+</dl>
+<p>Please note that messages to individual developers will generally not be
+answered directly. All questions, comments and code changes must be
+submitted to the mailing list for peer review and archiving.</p>
+</div>
+<div class="section">
+<h2><a class="toc-backref" href="#id11" id="pygresql-programming-information" name="pygresql-programming-information">PyGreSQL programming information</a></h2>
+<p>You may either choose to use the "classic" PyGreSQL interface
+provided by the <cite>pg</cite> module or else the newer DB-API 2.0
+compliant interface provided by the <cite>pgdb</cite> module.</p>
+<p><a class="reference" href="http://www.python.org/dev/peps/pep-0249/">DB-API 2.0</a>
+(Python Database API Specification v2.0)
+is a specification for connecting to databases (not only PostGreSQL)
+from Python that has been developed by the Python DB-SIG in 1999.</p>
+<p>The programming information is available in the files
+<a class="reference" href="pg.html">pg.txt</a> and <a class="reference" href="pgdb.html">pgdb.txt</a>.</p>
+<p>Note that PyGreSQL is not thread-safe on the connection level. Therefore
+we recommend using <cite>DBUtils <http://www.webwareforpython.org/DBUtils></cite>
+for multi-threaded environments, which supports both PyGreSQL interfaces.</p>
+</div>
+</div>
+<div class="section">
+<h1><a class="toc-backref" href="#id12" id="changelog-and-future" name="changelog-and-future">ChangeLog and Future</a></h1>
+<p>The ChangeLog with past changes is in the file
+<a class="reference" href="changelog.html">changelog.txt</a>.</p>
+<p>A to do list and wish list is in the file
+<a class="reference" href="future.html">future.txt</a>.</p>
+</div>
+</div>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.txt
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.txt b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.txt
new file mode 100644
index 0000000..77ed8ef
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/docs/readme.txt
@@ -0,0 +1,206 @@
+==========================================
+PyGreSQL - Python interface for PostgreSQL
+==========================================
+
+--------------------
+PyGreSQL version 4.0
+--------------------
+
+.. meta::
+ :description: PyGreSQL - Python interface for PostgreSQL
+ :keywords: PyGreSQL, PostGreSQL, Python
+
+.. contents:: Contents
+
+
+Copyright notice
+================
+
+Written by D'Arcy J.M. Cain (darcy@druid.net)
+
+Based heavily on code written by Pascal Andre (andre@chimay.via.ecp.fr)
+
+Copyright (c) 1995, Pascal Andre
+
+Further modifications copyright (c) 1997-2008 by D'Arcy J.M. Cain
+(darcy@druid.net)
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies or in any
+new file that contains a substantial portion of this file.
+
+IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
+AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+
+Introduction
+============
+
+**PostgreSQL** is a highly scalable, SQL compliant, open source
+object-relational database management system. With more than 15 years
+of development history, it is quickly becoming the de facto database
+for enterprise level open source solutions.
+Best of all, PostgreSQL's source code is available under the most liberal
+open source license: the BSD license.
+
+**Python** Python is an interpreted, interactive, object-oriented
+programming language. It is often compared to Tcl, Perl, Scheme or Java.
+Python combines remarkable power with very clear syntax. It has modules,
+classes, exceptions, very high level dynamic data types, and dynamic typing.
+There are interfaces to many system calls and libraries, as well as to
+various windowing systems (X11, Motif, Tk, Mac, MFC). New built-in modules
+are easily written in C or C++. Python is also usable as an extension
+language for applications that need a programmable interface.
+The Python implementation is copyrighted but freely usable and distributable,
+even for commercial use.
+
+**PyGreSQL** is a Python module that interfaces to a PostgreSQL database.
+It embeds the PostgreSQL query library to allow easy use of the powerful
+PostgreSQL features from a Python script.
+
+PyGreSQL is developed and tested on a NetBSD system, but it should also
+run on most other platforms where PostgreSQL and Python is running.
+It is based on the PyGres95 code written by Pascal Andre (andre@chimay.via.ecp.fr).
+D'Arcy (darcy@druid.net) renamed it to PyGreSQL starting with
+version 2.0 and serves as the "BDFL" of PyGreSQL.
+
+The current version PyGreSQL 4.0 needs PostgreSQL 7.2 and Python 2.3 or above.
+
+
+Where to get ... ?
+==================
+
+Home sites of the different packages
+------------------------------------
+**Python**:
+ http://www.python.org
+
+**PostgreSQL**:
+ http://www.postgresql.org
+
+**PyGreSQL**:
+ http://www.pygresql.org
+
+Download PyGreSQL here
+----------------------
+The **released version of the source code** is available at
+ * ftp://ftp.pygresql.org/pub/distrib/PyGreSQL.tgz
+You can also check the latest **pre-release version** at
+ * ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-beta.tgz
+A **Linux RPM** can be picked up from
+ * ftp://ftp.pygresql.org/pub/distrib/pygresql.i386.rpm
+A **NetBSD package** is available in their pkgsrc collection
+ * ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/databases/py-postgresql/README.html
+A **FreeBSD package** is available in their ports collection
+ * http://www.freebsd.org/cgi/cvsweb.cgi/ports/databases/py-PyGreSQL/
+A **Win32 package** for various Python versions is available at
+ * ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.3.exe
+ * ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.4.exe
+ * ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.5.exe
+ * ftp://ftp.pygresql.org/pub/distrib/PyGreSQL-4.0.win32-py2.6.exe
+You can also find PyGreSQL on the **Python Package Index** at
+ * http://pypi.python.org/pypi/PyGreSQL/
+
+
+Distribution files
+==================
+
+========== =
+pgmodule.c the C Python module (_pg)
+pg.py the "classic" PyGreSQL module
+pgdb.py DB-SIG DB-API 2.0 compliant API wrapper for PygreSQL
+docs/ documentation directory
+
+ Contains: readme.txt, announce.txt, install.txt,
+ changelog.txt, future.txt, pg.txt and pgdb.txt.
+
+ All text files are in ReST format, so HTML versions
+ can be easily created with buildhtml.py from docutils.
+tutorial/ demos directory
+
+ Contains: basics.py, syscat.py, advanced.py and func.py.
+
+ The samples here have been taken from the
+ PostgreSQL manual and were used for module testing.
+ They demonstrate some PostgreSQL features.
+========== =
+
+
+Installation
+============
+You will find the installing instructions in
+`install.txt <install.html>`_.
+
+
+Information and support
+=======================
+
+For general information
+-----------------------
+**Python**:
+ http://www.python.org
+
+**PostgreSQL**:
+ http://www.postgresql.org
+
+**PyGreSQL**:
+ http://www.pygresql.org
+
+For support
+-----------
+**Python**:
+ see http://www.python.org/community/
+
+**PostgreSQL**:
+ see http://www.postgresql.org/support/
+
+**PyGreSQL**:
+ Contact the PyGreSQL mailing list
+ concerning PyGreSQL 2.0 and up.
+
+ If you would like to proposes changes, please join the
+ PyGreSQL mailing list and send context diffs there.
+
+ See http://mailman.vex.net/mailman/listinfo/pygresql
+ to join the mailing list.
+
+Please note that messages to individual developers will generally not be
+answered directly. All questions, comments and code changes must be
+submitted to the mailing list for peer review and archiving.
+
+PyGreSQL programming information
+--------------------------------
+You may either choose to use the "classic" PyGreSQL interface
+provided by the `pg` module or else the newer DB-API 2.0
+compliant interface provided by the `pgdb` module.
+
+`DB-API 2.0 <http://www.python.org/dev/peps/pep-0249/>`_
+(Python Database API Specification v2.0)
+is a specification for connecting to databases (not only PostGreSQL)
+from Python that has been developed by the Python DB-SIG in 1999.
+
+The programming information is available in the files
+`pg.txt <pg.html>`_ and `pgdb.txt <pgdb.html>`_.
+
+Note that PyGreSQL is not thread-safe on the connection level. Therefore
+we recommend using `DBUtils <http://www.webwareforpython.org/DBUtils>`
+for multi-threaded environments, which supports both PyGreSQL interfaces.
+
+
+ChangeLog and Future
+====================
+The ChangeLog with past changes is in the file
+`changelog.txt <changelog.html>`_.
+
+A to do list and wish list is in the file
+`future.txt <future.html>`_.
[9/9] incubator-hawq git commit: Merge branch 'master' into HAWQ-703
Posted by od...@apache.org.
Merge branch 'master' into HAWQ-703
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/6917914a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/6917914a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/6917914a
Branch: refs/heads/HAWQ-703
Commit: 6917914a1885bf0a1c2ca56e7f4444a4fc12fc23
Parents: a042001 192cff1
Author: Oleksandr Diachenko <od...@pivotal.io>
Authored: Thu May 5 16:07:00 2016 -0700
Committer: Oleksandr Diachenko <od...@pivotal.io>
Committed: Thu May 5 16:07:00 2016 -0700
----------------------------------------------------------------------
src/backend/utils/misc/guc.c | 14 +
src/backend/utils/misc/postgresql.conf.sample | 1 +
tools/bin/.gitignore | 1 -
tools/bin/Makefile | 26 +-
tools/bin/ext/Makefile | 27 +
tools/bin/ext/__init__.py | 0
tools/bin/ext/pygresql/__init__.py | 0
tools/bin/generate-greenplum-path.sh | 7 -
tools/bin/gpcheck | 4 +-
tools/bin/gpload.py | 2 +-
tools/bin/gppylib/commands/base.py | 2 +-
tools/bin/gppylib/commands/gp.py | 2 +-
tools/bin/gppylib/db/dbconn.py | 2 +-
tools/bin/gppylib/operations/gpMigratorUtil.py | 2 +-
.../bin/gppylib/operations/test_utils_helper.py | 2 +-
.../test/regress/test_regress_pygresql.py | 4 +-
tools/bin/hawq_ctl | 2 +-
tools/bin/hawqconfig | 2 +-
tools/bin/hawqextract | 4 +-
tools/bin/hawqfilespace | 2 +-
tools/bin/hawqstate | 2 +-
tools/bin/lib/gpcheckcat | 4 +-
tools/bin/pythonSrc/.gitignore | 1 +
.../pythonSrc/PyGreSQL-4.0/docs/announce.html | 28 +
.../pythonSrc/PyGreSQL-4.0/docs/announce.txt | 23 +
.../pythonSrc/PyGreSQL-4.0/docs/changelog.html | 333 ++
.../pythonSrc/PyGreSQL-4.0/docs/changelog.txt | 285 ++
.../bin/pythonSrc/PyGreSQL-4.0/docs/default.css | 279 ++
tools/bin/pythonSrc/PyGreSQL-4.0/docs/docs.css | 109 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/future.html | 62 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/future.txt | 48 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/index.html | 182 +
.../pythonSrc/PyGreSQL-4.0/docs/install.html | 198 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/install.txt | 188 +
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.html | 2429 +++++++++++
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pg.txt | 1382 +++++++
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.html | 51 +
tools/bin/pythonSrc/PyGreSQL-4.0/docs/pgdb.txt | 42 +
.../bin/pythonSrc/PyGreSQL-4.0/docs/readme.html | 243 ++
.../bin/pythonSrc/PyGreSQL-4.0/docs/readme.txt | 206 +
tools/bin/pythonSrc/PyGreSQL-4.0/pg.py | 711 ++++
tools/bin/pythonSrc/PyGreSQL-4.0/pgdb.py | 582 +++
tools/bin/pythonSrc/PyGreSQL-4.0/pgmodule.c | 3756 ++++++++++++++++++
tools/bin/pythonSrc/PyGreSQL-4.0/setup.py | 152 +
.../pythonSrc/PyGreSQL-4.0/tutorial/advanced.py | 198 +
.../pythonSrc/PyGreSQL-4.0/tutorial/basics.py | 296 ++
.../bin/pythonSrc/PyGreSQL-4.0/tutorial/func.py | 205 +
.../pythonSrc/PyGreSQL-4.0/tutorial/syscat.py | 149 +
48 files changed, 12213 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
[2/9] incubator-hawq git commit: HAWQ-672. Add python module pygresql
back into hawq workspace
Posted by od...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/setup.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/setup.py b/tools/bin/pythonSrc/PyGreSQL-4.0/setup.py
new file mode 100755
index 0000000..5d28b31
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/setup.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python
+# $Id: setup.py,v 1.27 2008/11/21 17:08:17 cito Exp $
+
+"""Setup script for PyGreSQL version 4.0
+
+Authors and history:
+* PyGreSQL written 1997 by D'Arcy J.M. Cain <da...@druid.net>
+* based on code written 1995 by Pascal Andre <an...@chimay.via.ecp.fr>
+* setup script created 2000/04 Mark Alexander <mw...@gate.net>
+* tweaked 2000/05 Jeremy Hylton <je...@cnri.reston.va.us>
+* win32 support 2001/01 by Gerhard Haering <ge...@bigfoot.de>
+* tweaked 2006/02 and 2008/11 by Christoph Zwerschke <ci...@online.de>
+
+Prerequisites to be installed:
+* Python including devel package (header files and distutils)
+* PostgreSQL libs and devel packages (header files of client and server)
+* PostgreSQL pg_config tool (usually included in the devel package)
+ (the Windows installer has it as part of the database server feature)
+
+Tested with Python 2.5.2 and PostGreSQL 8.3.5. Older version should work
+as well, but you will need at least Python 2.3 and PostgreSQL 7.4.
+
+Use as follows:
+python setup.py build # to build the module
+python setup.py install # to install it
+
+You should use MinGW (www.mingw.org) for building on Win32:
+python setup.py build -c mingw32 install # use MinGW
+Note that Python newer than version 2.3 is using msvcr71 instead of msvcrt
+as its common runtime library. So, if you are using MinGW to build PyGreSQL,
+you should edit the file "%MinGWpath%/lib/gcc/%MinGWversion%/specs"
+and change the entry that reads -lmsvcrt to -lmsvcr71.
+
+See docs.python.org/doc/install/ for more information on
+using distutils to install Python programs.
+
+"""
+
+version = "4.0"
+
+import sys
+
+if not (2, 2) < sys.version_info[:2] < (3, 0):
+ raise Exception("PyGreSQL %s requires a Python 2 version"
+ " newer than 2.2." % version)
+
+import os
+from distutils.core import setup
+from distutils.extension import Extension
+
+def pg_config(s):
+ """Retrieve information about installed version of PostgreSQL."""
+ if os.path.exists("../../../../src/bin/pg_config/pg_config"):
+ f = os.popen("../../../../src/bin/pg_config/pg_config --%s" % s)
+ else:
+ """If a VPATH build, it might not be there. Look other places"""
+ """It should be the one in the path, because the makefile includes greenplum_path.sh """
+ f = os.popen("pg_config --%s" % s)
+
+ d = f.readline().strip()
+ if f.close() is not None:
+ raise Exception("pg_config tool is not available.")
+ if not d:
+ raise Exception("Could not get %s information." % s)
+ return d
+
+def mk_include():
+ """Create a temporary local include directory.
+
+ The directory will contain a copy of the PostgreSQL server header files,
+ where all features which are not necessary for PyGreSQL are disabled.
+
+ """
+ os.mkdir('include')
+ for f in os.listdir(pg_include_dir_server):
+ if not f.endswith('.h'):
+ continue
+ d = open(os.path.join(pg_include_dir_server, f)).read()
+ if f == 'pg_config.h':
+ d += '\n'.join(('',
+ '#undef ENABLE_NLS',
+ '#undef USE_REPL_SNPRINTF',
+ '#undef USE_SSL',
+ '#undef USE_ZLIB',
+ '#undef HAVE_STDINT_H',
+ '#undef HAVE_SYS_TIME_H',
+ '#undef HAVE_UNISTD_H',
+ '#define _CRT_SECURE_NO_WARNINGS 1',
+ '#define _USE_32BIT_TIME_T 1',
+ ''))
+ open(os.path.join('include', f), 'w').write(d)
+
+def rm_include():
+ """Remove the temporary local include directory."""
+ if os.path.exists('include'):
+ for f in os.listdir('include'):
+ os.remove(os.path.join('include', f))
+ os.rmdir('include')
+
+pg_include_dir = pg_config('includedir')
+pg_include_dir_server = pg_config('includedir-server')
+
+rm_include()
+mk_include()
+
+include_dirs = ['include', pg_include_dir, pg_include_dir_server]
+
+pg_libdir = pg_config('libdir')
+library_dirs = [pg_libdir]
+
+libraries=['pq']
+
+if sys.platform == "win32":
+ include_dirs.append(os.path.join(pg_include_dir_server, 'port/win32'))
+
+setup(
+ name="PyGreSQL",
+ version=version,
+ description="Python PostgreSQL Interfaces",
+ long_description = ("PyGreSQL is an open-source Python module"
+ " that interfaces to a PostgreSQL database."
+ " It embeds the PostgreSQL query library to allow easy use"
+ " of the powerful PostgreSQL features from a Python script."),
+ keywords="postgresql database api dbapi",
+ author="D'Arcy J. M. Cain",
+ author_email="darcy@PyGreSQL.org",
+ url="http://www.pygresql.org",
+ download_url = "ftp://ftp.pygresql.org/pub/distrib/",
+ platforms = ["any"],
+ license="Python",
+ py_modules=['pg', 'pgdb'],
+ ext_modules=[Extension(
+ '_pg', ['pgmodule.c'],
+ include_dirs = include_dirs,
+ library_dirs = library_dirs,
+ libraries = libraries,
+ extra_compile_args = ['-O2']
+ )],
+ classifiers=[
+ "Development Status :: 6 - Mature",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: Python Software Foundation License",
+ "Operating System :: OS Independent",
+ "Programming Language :: C",
+ "Programming Language :: Python",
+ "Topic :: Database",
+ "Topic :: Database :: Front-Ends",
+ "Topic :: Software Development :: Libraries :: Python Modules"
+ ]
+)
+
+rm_include()
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/advanced.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/advanced.py b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/advanced.py
new file mode 100755
index 0000000..41a5bc4
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/advanced.py
@@ -0,0 +1,198 @@
+#! /usr/bin/env python
+# advanced.py - demo of advanced features of PostGres. Some may not be ANSI.
+# inspired from the Postgres tutorial
+# adapted to Python 1995 by Pascal Andre
+
+print """
+__________________________________________________________________
+MODULE ADVANCED.PY : ADVANCED POSTGRES SQL COMMANDS TUTORIAL
+
+This module is designed for being imported from python prompt
+
+In order to run the samples included here, first create a connection
+using : cnx = advanced.DB(...)
+
+The "..." should be replaced with whatever arguments you need to open an
+existing database. Usually all you need is the name of the database and,
+in fact, if it is the same as your login name, you can leave it empty.
+
+then start the demo with: advanced.demo(cnx)
+__________________________________________________________________
+"""
+
+from pg import DB
+import sys
+
+# waits for a key
+def wait_key():
+ print "Press <enter>"
+ sys.stdin.read(1)
+
+# inheritance features
+def inherit_demo(pgcnx):
+ print "-----------------------------"
+ print "-- Inheritance:"
+ print "-- a table can inherit from zero or more tables. A query"
+ print "-- can reference either all rows of a table or all rows "
+ print "-- of a table plus all of its descendants."
+ print "-----------------------------"
+ print
+ print "-- For example, the capitals table inherits from cities table."
+ print "-- (It inherits all data fields from cities.)"
+ print
+ print "CREATE TABLE cities ("
+ print " name text,"
+ print " population float8,"
+ print " altitude int"
+ print ")"
+ print
+ print "CREATE TABLE capitals ("
+ print " state varchar(2)"
+ print ") INHERITS (cities)"
+ pgcnx.query("""CREATE TABLE cities (
+ name text,
+ population float8,
+ altitude int)""")
+ pgcnx.query("""CREATE TABLE capitals (
+ state varchar(2)) INHERITS (cities)""")
+ wait_key()
+ print
+ print "-- now, let's populate the tables"
+ print
+ print "INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)"
+ print "INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)"
+ print "INSERT INTO cities VALUES ('Mariposa', 1200, 1953)"
+ print
+ print "INSERT INTO capitals VALUES ('Sacramento', 3.694E+5, 30, 'CA')"
+ print "INSERT INTO capitals VALUES ('Madison', 1.913E+5, 845, 'WI')"
+ print
+ pgcnx.query("INSERT INTO cities VALUES ('San Francisco', 7.24E+5, 63)")
+ pgcnx.query("INSERT INTO cities VALUES ('Las Vegas', 2.583E+5, 2174)")
+ pgcnx.query("INSERT INTO cities VALUES ('Mariposa', 1200, 1953)")
+ pgcnx.query("INSERT INTO capitals VALUES ('Sacramento',3.694E+5,30,'CA')")
+ pgcnx.query("INSERT INTO capitals VALUES ('Madison', 1.913E+5, 845, 'WI')")
+ print
+ print "SELECT * FROM cities"
+ print pgcnx.query("SELECT * FROM cities")
+ print "SELECT * FROM capitals"
+ print pgcnx.query("SELECT * FROM capitals")
+ print
+ print "-- like before, a regular query references rows of the base"
+ print "-- table only"
+ print
+ print "SELECT name, altitude"
+ print "FROM cities"
+ print "WHERE altitude > 500;"
+ print pgcnx.query("""SELECT name, altitude
+ FROM cities
+ WHERE altitude > 500""")
+ print
+ print "-- on the other hand, you can find all cities, including "
+ print "-- capitals, that are located at an altitude of 500 'ft "
+ print "-- or higher by:"
+ print
+ print "SELECT c.name, c.altitude"
+ print "FROM cities* c"
+ print "WHERE c.altitude > 500"
+ print pgcnx.query("""SELECT c.name, c.altitude
+ FROM cities* c
+ WHERE c.altitude > 500""")
+
+# arrays attributes
+def array_demo(pgcnx):
+ print "----------------------"
+ print "-- Arrays:"
+ print "-- attributes can be arrays of base types or user-defined "
+ print "-- types"
+ print "----------------------"
+ print
+ print "CREATE TABLE sal_emp ("
+ print " name text,"
+ print " pay_by_quarter int4[],"
+ print " pay_by_extra_quarter int8[],"
+ print " schedule text[][]"
+ print ")"
+ pgcnx.query("""CREATE TABLE sal_emp (
+ name text,
+ pay_by_quarter int4[],
+ pay_by_extra_quarter int8[],
+ schedule text[][])""")
+ wait_key()
+ print
+ print "-- insert instances with array attributes. "
+ print " Note the use of braces"
+ print
+ print "INSERT INTO sal_emp VALUES ("
+ print " 'Bill',"
+ print " '{10000,10000,10000,10000}',"
+ print " '{9223372036854775800,9223372036854775800,9223372036854775800}',"
+ print " '{{\"meeting\", \"lunch\"}, {}}')"
+ print
+ print "INSERT INTO sal_emp VALUES ("
+ print " 'Carol',"
+ print " '{20000,25000,25000,25000}',"
+ print " '{9223372036854775807,9223372036854775807,9223372036854775807}',"
+ print " '{{\"talk\", \"consult\"}, {\"meeting\"}}')"
+ print
+ pgcnx.query("""INSERT INTO sal_emp VALUES (
+ 'Bill', '{10000,10000,10000,10000}',
+ '{9223372036854775800,9223372036854775800,9223372036854775800}',
+ '{{\"meeting\", \"lunch\"}, {}}')""")
+ pgcnx.query("""INSERT INTO sal_emp VALUES (
+ 'Carol', '{20000,25000,25000,25000}',
+ '{9223372036854775807,9223372036854775807,9223372036854775807}',
+ '{{\"talk\", \"consult\"}, {\"meeting\"}}')""")
+ wait_key()
+ print
+ print "----------------------"
+ print "-- queries on array attributes"
+ print "----------------------"
+ print
+ print "SELECT name FROM sal_emp WHERE"
+ print " sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]"
+ print
+ print pgcnx.query("""SELECT name FROM sal_emp WHERE
+ sal_emp.pay_by_quarter[1] <> sal_emp.pay_by_quarter[2]""")
+ print
+ print pgcnx.query("""SELECT name FROM sal_emp WHERE
+ sal_emp.pay_by_extra_quarter[1] <> sal_emp.pay_by_extra_quarter[2]""")
+ print
+ print "-- retrieve third quarter pay of all employees"
+ print
+ print "SELECT sal_emp.pay_by_quarter[3] FROM sal_emp"
+ print
+ print pgcnx.query("SELECT sal_emp.pay_by_quarter[3] FROM sal_emp")
+ print
+ print "-- retrieve third quarter extra pay of all employees"
+ print
+ print "SELECT sal_emp.pay_by_extra_quarter[3] FROM sal_emp"
+ print pgcnx.query("SELECT sal_emp.pay_by_extra_quarter[3] FROM sal_emp")
+ print
+ print "-- retrieve first two quarters of extra quarter pay of all employees"
+ print
+ print "SELECT sal_emp.pay_by_extra_quarter[1:2] FROM sal_emp"
+ print
+ print pgcnx.query("SELECT sal_emp.pay_by_extra_quarter[1:2] FROM sal_emp")
+ print
+ print "-- select subarrays"
+ print
+ print "SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE"
+ print " sal_emp.name = 'Bill'"
+ print pgcnx.query("SELECT sal_emp.schedule[1:2][1:1] FROM sal_emp WHERE " \
+ "sal_emp.name = 'Bill'")
+
+# base cleanup
+def demo_cleanup(pgcnx):
+ print "-- clean up (you must remove the children first)"
+ print "DROP TABLE sal_emp"
+ print "DROP TABLE capitals"
+ print "DROP TABLE cities;"
+ pgcnx.query("DROP TABLE sal_emp")
+ pgcnx.query("DROP TABLE capitals")
+ pgcnx.query("DROP TABLE cities")
+
+# main demo function
+def demo(pgcnx):
+ inherit_demo(pgcnx)
+ array_demo(pgcnx)
+ demo_cleanup(pgcnx)
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/basics.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/basics.py b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/basics.py
new file mode 100755
index 0000000..98a7f86
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/basics.py
@@ -0,0 +1,296 @@
+#! /usr/bin/env python
+# basics.py - basic SQL commands tutorial
+# inspired from the Postgres95 tutorial
+# adapted to Python 1995 by Pascal ANDRE
+
+print """
+__________________________________________________________________
+MODULE BASICS.PY : BASIC POSTGRES SQL COMMANDS TUTORIAL
+
+This module is designed for being imported from python prompt
+
+In order to run the samples included here, first create a connection
+using : cnx = basics.DB(...)
+
+The "..." should be replaced with whatever arguments you need to open an
+existing database. Usually all you need is the name of the database and,
+in fact, if it is the same as your login name, you can leave it empty.
+
+then start the demo with: basics.demo(cnx)
+__________________________________________________________________
+"""
+
+from pg import DB
+import sys
+
+# waits for a key
+def wait_key():
+ print "Press <enter>"
+ sys.stdin.read(1)
+
+# table creation commands
+def create_table(pgcnx):
+ print "-----------------------------"
+ print "-- Creating a table:"
+ print "-- a CREATE TABLE is used to create base tables. POSTGRES"
+ print "-- SQL has its own set of built-in types. (Note that"
+ print "-- keywords are case-insensitive but identifiers are "
+ print "-- case-sensitive.)"
+ print "-----------------------------"
+ print
+ print "Sending query :"
+ print "CREATE TABLE weather ("
+ print " city varchar(80),"
+ print " temp_lo int,"
+ print " temp_hi int,"
+ print " prcp float8,"
+ print " date date"
+ print ")"
+ pgcnx.query("""CREATE TABLE weather (city varchar(80), temp_lo int,
+ temp_hi int, prcp float8, date date)""")
+ print
+ print "Sending query :"
+ print "CREATE TABLE cities ("
+ print " name varchar(80),"
+ print " location point"
+ print ")"
+ pgcnx.query("""CREATE TABLE cities (
+ name varchar(80),
+ location point)""")
+
+# data insertion commands
+def insert_data(pgcnx):
+ print "-----------------------------"
+ print "-- Inserting data:"
+ print "-- an INSERT statement is used to insert a new row into"
+ print "-- a table. There are several ways you can specify what"
+ print "-- columns the data should go to."
+ print "-----------------------------"
+ print
+ print "-- 1. the simplest case is when the list of value correspond to"
+ print "-- the order of the columns specified in CREATE TABLE."
+ print
+ print "Sending query :"
+ print "INSERT INTO weather "
+ print " VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')"
+ pgcnx.query("""INSERT INTO weather
+ VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')""")
+ print
+ print "Sending query :"
+ print "INSERT INTO cities "
+ print " VALUES ('San Francisco', '(-194.0, 53.0)')"
+ pgcnx.query("""INSERT INTO cities
+ VALUES ('San Francisco', '(-194.0, 53.0)')""")
+ print
+ wait_key()
+ print "-- 2. you can also specify what column the values correspond "
+ print " to. (The columns can be specified in any order. You may "
+ print " also omit any number of columns. eg. unknown precipitation"
+ print " below)"
+ print "Sending query :"
+ print "INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)"
+ print " VALUES ('San Francisco', 43, 57, 0.0, '11/29/1994')"
+ pgcnx.query("INSERT INTO weather (date, city, temp_hi, temp_lo)" \
+ "VALUES ('11/29/1994', 'Hayward', 54, 37)")
+
+# direct selection commands
+def select_data1(pgcnx):
+ print "-----------------------------"
+ print "-- Retrieving data:"
+ print "-- a SELECT statement is used for retrieving data. The "
+ print "-- basic syntax is:"
+ print "-- SELECT columns FROM tables WHERE predicates"
+ print "-----------------------------"
+ print
+ print "-- a simple one would be the query:"
+ print "SELECT * FROM weather"
+ print
+ print "The result is :"
+ q = pgcnx.query("SELECT * FROM weather")
+ print q
+ print
+ print "-- you may also specify expressions in the target list (the "
+ print "-- 'AS column' specifies the column name of the result. It is "
+ print "-- optional.)"
+ print "The query :"
+ print " SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date "
+ print " FROM weather"
+ print "Gives :"
+ print pgcnx.query("""SELECT city, (temp_hi+temp_lo)/2
+ AS temp_avg, date FROM weather""")
+ print
+ print "-- if you want to retrieve rows that satisfy certain condition"
+ print "-- (ie. a restriction), specify the condition in WHERE. The "
+ print "-- following retrieves the weather of San Francisco on rainy "
+ print "-- days."
+ print "SELECT *"
+ print "FROM weather"
+ print "WHERE city = 'San Francisco' "
+ print " and prcp > 0.0"
+ print pgcnx.query("""SELECT * FROM weather WHERE city = 'San Francisco'
+ AND prcp > 0.0""")
+ print
+ print "-- here is a more complicated one. Duplicates are removed when "
+ print "-- DISTINCT is specified. ORDER BY specifies the column to sort"
+ print "-- on. (Just to make sure the following won't confuse you, "
+ print "-- DISTINCT and ORDER BY can be used separately.)"
+ print "SELECT DISTINCT city"
+ print "FROM weather"
+ print "ORDER BY city;"
+ print pgcnx.query("SELECT DISTINCT city FROM weather ORDER BY city")
+
+# selection to a temporary table
+def select_data2(pgcnx):
+ print "-----------------------------"
+ print "-- Retrieving data into other classes:"
+ print "-- a SELECT ... INTO statement can be used to retrieve "
+ print "-- data into another class."
+ print "-----------------------------"
+ print
+ print "The query :"
+ print "SELECT * INTO TABLE temptab "
+ print "FROM weather"
+ print "WHERE city = 'San Francisco' "
+ print " and prcp > 0.0"
+ pgcnx.query("""SELECT * INTO TABLE temptab FROM weather
+ WHERE city = 'San Francisco' and prcp > 0.0""")
+ print "Fills the table temptab, that can be listed with :"
+ print "SELECT * from temptab"
+ print pgcnx.query("SELECT * from temptab")
+
+# aggregate creation commands
+def create_aggregate(pgcnx):
+ print "-----------------------------"
+ print "-- Aggregates"
+ print "-----------------------------"
+ print
+ print "Let's consider the query :"
+ print "SELECT max(temp_lo)"
+ print "FROM weather;"
+ print pgcnx.query("SELECT max(temp_lo) FROM weather")
+ print
+ print "-- Aggregate with GROUP BY"
+ print "SELECT city, max(temp_lo)"
+ print "FROM weather "
+ print "GROUP BY city;"
+ print pgcnx.query( """SELECT city, max(temp_lo)
+ FROM weather GROUP BY city""")
+
+# table join commands
+def join_table(pgcnx):
+ print "-----------------------------"
+ print "-- Joining tables:"
+ print "-- queries can access multiple tables at once or access"
+ print "-- the same table in such a way that multiple instances"
+ print "-- of the table are being processed at the same time."
+ print "-----------------------------"
+ print
+ print "-- suppose we want to find all the records that are in the "
+ print "-- temperature range of other records. W1 and W2 are aliases "
+ print "--for weather."
+ print
+ print "SELECT W1.city, W1.temp_lo, W1.temp_hi, "
+ print " W2.city, W2.temp_lo, W2.temp_hi"
+ print "FROM weather W1, weather W2"
+ print "WHERE W1.temp_lo < W2.temp_lo "
+ print " and W1.temp_hi > W2.temp_hi"
+ print
+ print pgcnx.query("""SELECT W1.city, W1.temp_lo, W1.temp_hi,
+ W2.city, W2.temp_lo, W2.temp_hi FROM weather W1, weather W2
+ WHERE W1.temp_lo < W2.temp_lo and W1.temp_hi > W2.temp_hi""")
+ print
+ print "-- let's join two tables. The following joins the weather table"
+ print "-- and the cities table."
+ print
+ print "SELECT city, location, prcp, date"
+ print "FROM weather, cities"
+ print "WHERE name = city"
+ print
+ print pgcnx.query("""SELECT city, location, prcp, date FROM weather, cities
+ WHERE name = city""")
+ print
+ print "-- since the column names are all different, we don't have to "
+ print "-- specify the table name. If you want to be clear, you can do "
+ print "-- the following. They give identical results, of course."
+ print
+ print "SELECT w.city, c.location, w.prcp, w.date"
+ print "FROM weather w, cities c"
+ print "WHERE c.name = w.city;"
+ print
+ print pgcnx.query("""SELECT w.city, c.location, w.prcp, w.date
+ FROM weather w, cities c WHERE c.name = w.city""")
+
+# data updating commands
+def update_data(pgcnx):
+ print "-----------------------------"
+ print "-- Updating data:"
+ print "-- an UPDATE statement is used for updating data. "
+ print "-----------------------------"
+ print
+ print "-- suppose you discover the temperature readings are all off by"
+ print "-- 2 degrees as of Nov 28, you may update the data as follow:"
+ print
+ print "UPDATE weather"
+ print " SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2"
+ print " WHERE date > '11/28/1994'"
+ print
+ pgcnx.query("""UPDATE weather
+ SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
+ WHERE date > '11/28/1994'""")
+ print
+ print "SELECT * from weather"
+ print pgcnx.query("SELECT * from weather")
+
+# data deletion commands
+def delete_data(pgcnx):
+ print "-----------------------------"
+ print "-- Deleting data:"
+ print "-- a DELETE statement is used for deleting rows from a "
+ print "-- table."
+ print "-----------------------------"
+ print
+ print "-- suppose you are no longer interested in the weather of "
+ print "-- Hayward, you can do the following to delete those rows from"
+ print "-- the table"
+ print
+ print "DELETE FROM weather WHERE city = 'Hayward'"
+ pgcnx.query("DELETE FROM weather WHERE city = 'Hayward'")
+ print
+ print "SELECT * from weather"
+ print
+ print pgcnx.query("SELECT * from weather")
+ print
+ print "-- you can also delete all the rows in a table by doing the "
+ print "-- following. (This is different from DROP TABLE which removes "
+ print "-- the table in addition to the removing the rows.)"
+ print
+ print "DELETE FROM weather"
+ pgcnx.query("DELETE FROM weather")
+ print
+ print "SELECT * from weather"
+ print pgcnx.query("SELECT * from weather")
+
+# table removal commands
+def remove_table(pgcnx):
+ print "-----------------------------"
+ print "-- Removing the tables:"
+ print "-- DROP TABLE is used to remove tables. After you have"
+ print "-- done this, you can no longer use those tables."
+ print "-----------------------------"
+ print
+ print "DROP TABLE weather, cities, temptab"
+ pgcnx.query("DROP TABLE weather, cities, temptab")
+
+# main demo function
+def demo(pgcnx):
+ create_table(pgcnx)
+ wait_key()
+ insert_data(pgcnx)
+ wait_key()
+ select_data1(pgcnx)
+ select_data2(pgcnx)
+ create_aggregate(pgcnx)
+ join_table(pgcnx)
+ update_data(pgcnx)
+ delete_data(pgcnx)
+ remove_table(pgcnx)
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/func.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/func.py b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/func.py
new file mode 100755
index 0000000..af2b412
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/func.py
@@ -0,0 +1,205 @@
+# func.py - demonstrate the use of SQL functions
+# inspired from the PostgreSQL tutorial
+# adapted to Python 1995 by Pascal ANDRE
+
+print """
+__________________________________________________________________
+MODULE FUNC.PY : SQL FUNCTION DEFINITION TUTORIAL
+
+This module is designed for being imported from python prompt
+
+In order to run the samples included here, first create a connection
+using : cnx = func.DB(...)
+
+The "..." should be replaced with whatever arguments you need to open an
+existing database. Usually all you need is the name of the database and,
+in fact, if it is the same as your login name, you can leave it empty.
+
+then start the demo with: func.demo(cnx)
+__________________________________________________________________
+"""
+
+from pg import DB
+import sys
+
+# waits for a key
+def wait_key():
+ print "Press <enter>"
+ sys.stdin.read(1)
+
+# basic functions declaration
+def base_func(pgcnx):
+ print "-----------------------------"
+ print "-- Creating SQL Functions on Base Types"
+ print "-- a CREATE FUNCTION statement lets you create a new "
+ print "-- function that can be used in expressions (in SELECT, "
+ print "-- INSERT, etc.). We will start with functions that "
+ print "-- return values of base types."
+ print "-----------------------------"
+ print
+ print "--"
+ print "-- let's create a simple SQL function that takes no arguments"
+ print "-- and returns 1"
+ print
+ print "CREATE FUNCTION one() RETURNS int4"
+ print " AS 'SELECT 1 as ONE' LANGUAGE 'sql'"
+ pgcnx.query("""CREATE FUNCTION one() RETURNS int4
+ AS 'SELECT 1 as ONE' LANGUAGE 'sql'""")
+ wait_key()
+ print
+ print "--"
+ print "-- functions can be used in any expressions (eg. in the target"
+ print "-- list or qualifications)"
+ print
+ print "SELECT one() AS answer"
+ print pgcnx.query("SELECT one() AS answer")
+ print
+ print "--"
+ print "-- here's how you create a function that takes arguments. The"
+ print "-- following function returns the sum of its two arguments:"
+ print
+ print "CREATE FUNCTION add_em(int4, int4) RETURNS int4"
+ print " AS 'SELECT $1 + $2' LANGUAGE 'sql'"
+ pgcnx.query("""CREATE FUNCTION add_em(int4, int4) RETURNS int4
+ AS 'SELECT $1 + $2' LANGUAGE 'sql'""")
+ print
+ print "SELECT add_em(1, 2) AS answer"
+ print pgcnx.query("SELECT add_em(1, 2) AS answer")
+
+# functions on composite types
+def comp_func(pgcnx):
+ print "-----------------------------"
+ print "-- Creating SQL Functions on Composite Types"
+ print "-- it is also possible to create functions that return"
+ print "-- values of composite types."
+ print "-----------------------------"
+ print
+ print "-- before we create more sophisticated functions, let's "
+ print "-- populate an EMP table"
+ print
+ print "CREATE TABLE EMP ("
+ print " name text,"
+ print " salary int4,"
+ print " age int4,"
+ print " dept varchar(16)"
+ print ")"
+ pgcnx.query("""CREATE TABLE EMP (
+ name text,
+ salary int4,
+ age int4,
+ dept varchar(16))""")
+ print
+ print "INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')"
+ print "INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')"
+ print "INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')"
+ print "INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')"
+ print "INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')"
+ pgcnx.query("INSERT INTO EMP VALUES ('Sam', 1200, 16, 'toy')")
+ pgcnx.query("INSERT INTO EMP VALUES ('Claire', 5000, 32, 'shoe')")
+ pgcnx.query("INSERT INTO EMP VALUES ('Andy', -1000, 2, 'candy')")
+ pgcnx.query("INSERT INTO EMP VALUES ('Bill', 4200, 36, 'shoe')")
+ pgcnx.query("INSERT INTO EMP VALUES ('Ginger', 4800, 30, 'candy')")
+ wait_key()
+ print
+ print "-- the argument of a function can also be a tuple. For "
+ print "-- instance, double_salary takes a tuple of the EMP table"
+ print
+ print "CREATE FUNCTION double_salary(EMP) RETURNS int4"
+ print " AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'"
+ pgcnx.query("""CREATE FUNCTION double_salary(EMP) RETURNS int4
+ AS 'SELECT $1.salary * 2 AS salary' LANGUAGE 'sql'""")
+ print
+ print "SELECT name, double_salary(EMP) AS dream"
+ print "FROM EMP"
+ print "WHERE EMP.dept = 'toy'"
+ print pgcnx.query("""SELECT name, double_salary(EMP) AS dream
+ FROM EMP WHERE EMP.dept = 'toy'""")
+ print
+ print "-- the return value of a function can also be a tuple. However,"
+ print "-- make sure that the expressions in the target list is in the "
+ print "-- same order as the columns of EMP."
+ print
+ print "CREATE FUNCTION new_emp() RETURNS EMP"
+ print " AS 'SELECT \'None\'::text AS name,"
+ print " 1000 AS salary,"
+ print " 25 AS age,"
+ print " \'none\'::varchar(16) AS dept'"
+ print " LANGUAGE 'sql'"
+ pgcnx.query("""CREATE FUNCTION new_emp() RETURNS EMP
+ AS 'SELECT \\\'None\\\'::text AS name,
+ 1000 AS salary,
+ 25 AS age,
+ \\\'none\\\'::varchar(16) AS dept'
+ LANGUAGE 'sql'""")
+ wait_key()
+ print
+ print "-- you can then project a column out of resulting the tuple by"
+ print "-- using the \"function notation\" for projection columns. "
+ print "-- (ie. bar(foo) is equivalent to foo.bar) Note that we don't"
+ print "-- support new_emp().name at this moment."
+ print
+ print "SELECT name(new_emp()) AS nobody"
+ print pgcnx.query("SELECT name(new_emp()) AS nobody")
+ print
+ print "-- let's try one more function that returns tuples"
+ print "CREATE FUNCTION high_pay() RETURNS setof EMP"
+ print " AS 'SELECT * FROM EMP where salary > 1500'"
+ print " LANGUAGE 'sql'"
+ pgcnx.query("""CREATE FUNCTION high_pay() RETURNS setof EMP
+ AS 'SELECT * FROM EMP where salary > 1500'
+ LANGUAGE 'sql'""")
+ print
+ print "SELECT name(high_pay()) AS overpaid"
+ print pgcnx.query("SELECT name(high_pay()) AS overpaid")
+
+# function with multiple SQL commands
+def mult_func(pgcnx):
+ print "-----------------------------"
+ print "-- Creating SQL Functions with multiple SQL statements"
+ print "-- you can also create functions that do more than just a"
+ print "-- SELECT."
+ print "-----------------------------"
+ print
+ print "-- you may have noticed that Andy has a negative salary. We'll"
+ print "-- create a function that removes employees with negative "
+ print "-- salaries."
+ print
+ print "SELECT * FROM EMP"
+ print pgcnx.query("SELECT * FROM EMP")
+ print
+ print "CREATE FUNCTION clean_EMP () RETURNS int4"
+ print " AS 'DELETE FROM EMP WHERE EMP.salary <= 0"
+ print " SELECT 1 AS ignore_this'"
+ print " LANGUAGE 'sql'"
+ pgcnx.query("CREATE FUNCTION clean_EMP () RETURNS int4 AS 'DELETE FROM EMP WHERE EMP.salary <= 0; SELECT 1 AS ignore_this' LANGUAGE 'sql'")
+ print
+ print "SELECT clean_EMP()"
+ print pgcnx.query("SELECT clean_EMP()")
+ print
+ print "SELECT * FROM EMP"
+ print pgcnx.query("SELECT * FROM EMP")
+
+# base cleanup
+def demo_cleanup(pgcnx):
+ print "-- remove functions that were created in this file"
+ print
+ print "DROP FUNCTION clean_EMP()"
+ print "DROP FUNCTION high_pay()"
+ print "DROP FUNCTION new_emp()"
+ print "DROP FUNCTION add_em(int4, int4)"
+ print "DROP FUNCTION one()"
+ print
+ print "DROP TABLE EMP CASCADE"
+ pgcnx.query("DROP FUNCTION clean_EMP()")
+ pgcnx.query("DROP FUNCTION high_pay()")
+ pgcnx.query("DROP FUNCTION new_emp()")
+ pgcnx.query("DROP FUNCTION add_em(int4, int4)")
+ pgcnx.query("DROP FUNCTION one()")
+ pgcnx.query("DROP TABLE EMP CASCADE")
+
+# main demo function
+def demo(pgcnx):
+ base_func(pgcnx)
+ comp_func(pgcnx)
+ mult_func(pgcnx)
+ demo_cleanup(pgcnx)
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/syscat.py
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/syscat.py b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/syscat.py
new file mode 100755
index 0000000..1ab1d58
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/tutorial/syscat.py
@@ -0,0 +1,149 @@
+# syscat.py - parses some system catalogs
+# inspired from the PostgreSQL tutorial
+# adapted to Python 1995 by Pascal ANDRE
+
+print """
+__________________________________________________________________
+MODULE SYSCAT.PY : PARSES SOME POSTGRESQL SYSTEM CATALOGS
+
+This module is designed for being imported from python prompt
+
+In order to run the samples included here, first create a connection
+using : cnx = syscat.DB(...)
+
+The "..." should be replaced with whatever arguments you need to open an
+existing database. Usually all you need is the name of the database and,
+in fact, if it is the same as your login name, you can leave it empty.
+
+then start the demo with: syscat.demo(cnx)
+
+Some results may be empty, depending on your base status."
+
+__________________________________________________________________
+"""
+
+from pg import DB
+import sys
+
+# waits for a key
+def wait_key():
+ print "Press <enter>"
+ sys.stdin.read(1)
+
+# lists all simple indices
+def list_simple_ind(pgcnx):
+ result = pgcnx.query("""SELECT bc.relname AS class_name,
+ ic.relname AS index_name, a.attname
+ FROM pg_class bc, pg_class ic, pg_index i, pg_attribute a
+ WHERE i.indrelid = bc.oid AND i.indexrelid = bc.oid
+ AND i.indkey[0] = a.attnum AND a.attrelid = bc.oid
+ AND i.indproc = '0'::oid AND a.attisdropped = 'f'
+ ORDER BY class_name, index_name, attname""")
+ return result
+
+# list all user defined attributes and their type in user-defined classes
+def list_all_attr(pgcnx):
+ result = pgcnx.query("""SELECT c.relname, a.attname, t.typname
+ FROM pg_class c, pg_attribute a, pg_type t
+ WHERE c.relkind = 'r' and c.relname !~ '^pg_'
+ AND c.relname !~ '^Inv' and a.attnum > 0
+ AND a.attrelid = c.oid and a.atttypid = t.oid
+ AND a.attisdropped = 'f'
+ ORDER BY relname, attname""")
+ return result
+
+# list all user defined base type
+def list_user_base_type(pgcnx):
+ result = pgcnx.query("""SELECT u.usename, t.typname
+ FROM pg_type t, pg_user u
+ WHERE u.usesysid = int2in(int4out(t.typowner))
+ AND t.typrelid = '0'::oid and t.typelem = '0'::oid
+ AND u.usename <> 'postgres' order by usename, typname""")
+ return result
+
+# list all right-unary operators
+def list_right_unary_operator(pgcnx):
+ result = pgcnx.query("""SELECT o.oprname AS right_unary,
+ lt.typname AS operand, result.typname AS return_type
+ FROM pg_operator o, pg_type lt, pg_type result
+ WHERE o.oprkind='r' and o.oprleft = lt.oid
+ AND o.oprresult = result.oid
+ ORDER BY operand""")
+ return result
+
+# list all left-unary operators
+def list_left_unary_operator(pgcnx):
+ result = pgcnx.query("""SELECT o.oprname AS left_unary,
+ rt.typname AS operand, result.typname AS return_type
+ FROM pg_operator o, pg_type rt, pg_type result
+ WHERE o.oprkind='l' AND o.oprright = rt.oid
+ AND o.oprresult = result.oid
+ ORDER BY operand""")
+ return result
+
+# list all binary operators
+def list_binary_operator(pgcnx):
+ result = pgcnx.query("""SELECT o.oprname AS binary_op,
+ rt.typname AS right_opr, lt.typname AS left_opr,
+ result.typname AS return_type
+ FROM pg_operator o, pg_type rt, pg_type lt, pg_type result
+ WHERE o.oprkind = 'b' AND o.oprright = rt.oid
+ AND o.oprleft = lt.oid AND o.oprresult = result.oid""")
+ return result
+
+# returns the name, args and return type from all function of lang l
+def list_lang_func(pgcnx, l):
+ result = pgcnx.query("""SELECT p.proname, p.pronargs, t.typname
+ FROM pg_proc p, pg_language l, pg_type t
+ WHERE p.prolang = l.oid AND p.prorettype = t.oid
+ AND l.lanname = '%s'
+ ORDER BY proname""" % l)
+ return result
+
+# lists all the aggregate functions and the type to which they can be applied
+def list_agg_func(pgcnx):
+ result = pgcnx.query("""SELECT p.proname, t.typname
+ FROM pg_aggregate a, pg_proc p, pg_type t
+ WHERE a.aggfnoid = p.oid
+ and p.proargtypes[0] = t.oid
+ ORDER BY proname, typname""")
+ return result
+
+# lists all the operator classes that can be used with each access method as
+# well as the operators that can be used with the respective operator classes
+def list_op_class(pgcnx):
+ result = pgcnx.query("""SELECT am.amname, opc.opcname, opr.oprname
+ FROM pg_am am, pg_amop amop, pg_opclass opc, pg_operator opr
+ WHERE amop.amopid = am.oid and amop.amopclaid = opc.oid
+ AND amop.amopopr = opr.oid order by amname, opcname, oprname""")
+ return result
+
+# demo function - runs all examples
+def demo(pgcnx):
+ import sys, os
+ save_stdout = sys.stdout
+ sys.stdout = os.popen("more", "w")
+ print "Listing simple indices ..."
+ print list_simple_ind(pgcnx)
+ print "Listing all attributes ..."
+ print list_all_attr(pgcnx)
+ print "Listing all user-defined base types ..."
+ print list_user_base_type(pgcnx)
+ print "Listing all left-unary operators defined ..."
+ print list_left_unary_operator(pgcnx)
+ print "Listing all right-unary operators defined ..."
+ print list_right_unary_operator(pgcnx)
+ print "Listing all binary operators ..."
+ print list_binary_operator(pgcnx)
+ print "Listing C external function linked ..."
+ print list_lang_func(pgcnx, 'C')
+ print "Listing C internal functions ..."
+ print list_lang_func(pgcnx, 'internal')
+ print "Listing SQL functions defined ..."
+ print list_lang_func(pgcnx, 'sql')
+ print "Listing 'aggregate functions' ..."
+ print list_agg_func(pgcnx)
+ print "Listing 'operator classes' ..."
+ print list_op_class(pgcnx)
+ del sys.stdout
+ sys.stdout = save_stdout
[3/9] incubator-hawq git commit: HAWQ-672. Add python module pygresql
back into hawq workspace
Posted by od...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/192cff1f/tools/bin/pythonSrc/PyGreSQL-4.0/pgmodule.c
----------------------------------------------------------------------
diff --git a/tools/bin/pythonSrc/PyGreSQL-4.0/pgmodule.c b/tools/bin/pythonSrc/PyGreSQL-4.0/pgmodule.c
new file mode 100644
index 0000000..fbff317
--- /dev/null
+++ b/tools/bin/pythonSrc/PyGreSQL-4.0/pgmodule.c
@@ -0,0 +1,3756 @@
+/*
+ * $Id: pgmodule.c,v 1.90 2008/12/03 00:17:15 cito Exp $
+ * PyGres, version 2.2 A Python interface for PostgreSQL database. Written by
+ * D'Arcy J.M. Cain, (darcy@druid.net). Based heavily on code written by
+ * Pascal Andre, andre@chimay.via.ecp.fr. Copyright (c) 1995, Pascal Andre
+ * (andre@via.ecp.fr).
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without a written
+ * agreement is hereby granted, provided that the above copyright notice and
+ * this paragraph and the following two paragraphs appear in all copies or in
+ * any new file that contains a substantial portion of this file.
+ *
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+ * AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE
+ * AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ * ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Further modifications copyright 1997, 1998, 1999 by D'Arcy J.M. Cain
+ * (darcy@druid.net) subject to the same terms and conditions as above.
+ *
+ */
+
+/* Note: This should be linked against the same C runtime lib as Python */
+
+#include "postgres.h"
+#include "libpq-fe.h"
+#include "libpq/libpq-fs.h"
+#include "catalog/pg_type.h"
+
+/* these will be defined in Python.h again: */
+#undef _POSIX_C_SOURCE
+#undef HAVE_STRERROR
+#undef snprintf
+#undef vsnprintf
+
+#include <Python.h>
+
+static PyObject *Error, *Warning, *InterfaceError,
+ *DatabaseError, *InternalError, *OperationalError, *ProgrammingError,
+ *IntegrityError, *DataError, *NotSupportedError;
+
+static const char *PyPgVersion = "4.0";
+
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+/* taken from fileobject.c */
+#define BUF(v) PyString_AS_STRING((PyStringObject *)(v))
+
+/* default values */
+#define MODULE_NAME "pgsql"
+#define PG_ARRAYSIZE 1
+
+/* flags for object validity checks */
+#define CHECK_OPEN 1
+#define CHECK_CLOSE 2
+#define CHECK_CNX 4
+#define CHECK_RESULT 8
+#define CHECK_DQL 16
+
+/* query result types */
+#define RESULT_EMPTY 1
+#define RESULT_DML 2
+#define RESULT_DDL 3
+#define RESULT_DQL 4
+
+/* flags for move methods */
+#define QUERY_MOVEFIRST 1
+#define QUERY_MOVELAST 2
+#define QUERY_MOVENEXT 3
+#define QUERY_MOVEPREV 4
+
+/* moves names for errors */
+const char *__movename[5] =
+{"", "movefirst", "movelast", "movenext", "moveprev"};
+
+#define MAX_BUFFER_SIZE 8192 /* maximum transaction size */
+
+#ifndef NO_DIRECT
+#define DIRECT_ACCESS 1 /* enables direct access functions */
+#endif
+
+#ifndef NO_LARGE
+#define LARGE_OBJECTS 1 /* enables large objects support */
+#endif
+
+#ifndef NO_DEF_VAR
+#define DEFAULT_VARS 1 /* enables default variables use */
+#endif
+
+#ifndef NO_NOTICES
+#define HANDLE_NOTICES 1 /* enables notices handling */
+#endif /* NO_NOTICES */
+
+#ifndef PG_VERSION_NUM
+#ifdef PQnoPasswordSupplied
+#define PG_VERSION_NUM 80000
+#else
+#define PG_VERSION_NUM 70400
+#endif
+#endif
+
+/* Before 8.0, PQsetdbLogin was not thread-safe with kerberos. */
+#if PG_VERSION_NUM >= 80000 || !(defined(KRB4) || defined(KRB5))
+#define PQsetdbLoginIsThreadSafe 1
+#endif
+
+/* --------------------------------------------------------------------- */
+
+/* MODULE GLOBAL VARIABLES */
+
+#ifdef DEFAULT_VARS
+
+static PyObject *pg_default_host; /* default database host */
+static PyObject *pg_default_base; /* default database name */
+static PyObject *pg_default_opt; /* default connection options */
+static PyObject *pg_default_tty; /* default debug tty */
+static PyObject *pg_default_port; /* default connection port */
+static PyObject *pg_default_user; /* default username */
+static PyObject *pg_default_passwd; /* default password */
+#endif /* DEFAULT_VARS */
+
+#ifdef HANDLE_NOTICES
+#define MAX_BUFFERED_NOTICES 101 /* max notices (+1) to keep for each connection */
+static void notice_processor(void * arg, const char * message);
+#endif /* HANDLE_NOTICES */
+
+DL_EXPORT(void) init_pg(void);
+int *get_type_array(PGresult *result, int nfields);
+
+static PyObject *decimal = NULL; /* decimal type */
+
+/* --------------------------------------------------------------------- */
+/* OBJECTS DECLARATION */
+
+/* pg connection object */
+
+typedef struct
+{
+ PyObject_HEAD
+ int valid; /* validity flag */
+ PGconn *cnx; /* PostGres connection handle */
+ PGresult *last_result; /* last result content */
+#ifdef HANDLE_NOTICES
+ char **notices; /* dynamically allocated circular buffer for notices */
+ int notices_first; /* index of first filled index in notices */
+ int notices_next; /* index of first free index in notices */
+#endif /* HANDLE_NOTICES */
+} pgobject;
+
+staticforward PyTypeObject PgType;
+
+#define is_pgobject(v) ((v)->ob_type == &PgType)
+
+static PyObject *
+pgobject_New(void)
+{
+ pgobject *pgobj;
+
+ if ((pgobj = PyObject_NEW(pgobject, &PgType)) == NULL)
+ return NULL;
+
+ pgobj->valid = 1;
+ pgobj->last_result = NULL;
+ pgobj->cnx = NULL;
+ pgobj->notices = malloc(sizeof(char*) * MAX_BUFFERED_NOTICES);
+ pgobj->notices_first = 0;
+ pgobj->notices_next = 0;
+ return (PyObject *) pgobj;
+}
+
+/* pg query object */
+
+typedef struct
+{
+ PyObject_HEAD
+ PGresult *last_result; /* last result content */
+ int result_type; /* type of previous result */
+ long current_pos; /* current position in last result */
+ long num_rows; /* number of (affected) rows */
+} pgqueryobject;
+
+staticforward PyTypeObject PgQueryType;
+
+#define is_pgqueryobject(v) ((v)->ob_type == &PgQueryType)
+
+/* pg source object */
+
+typedef struct
+{
+ PyObject_HEAD
+ int valid; /* validity flag */
+ pgobject *pgcnx; /* parent connection object */
+ PGresult *last_result; /* last result content */
+ int result_type; /* result type (DDL/DML/DQL) */
+ long arraysize; /* array size for fetch method */
+ int current_row; /* current selected row */
+ int max_row; /* number of rows in the result */
+ int num_fields; /* number of fields in each row */
+} pgsourceobject;
+
+staticforward PyTypeObject PgSourceType;
+
+#define is_pgsourceobject(v) ((v)->ob_type == &PgSourceType)
+
+
+#ifdef LARGE_OBJECTS
+/* pg large object */
+
+typedef struct
+{
+ PyObject_HEAD
+ pgobject *pgcnx; /* parent connection object */
+ Oid lo_oid; /* large object oid */
+ int lo_fd; /* large object fd */
+} pglargeobject;
+
+staticforward PyTypeObject PglargeType;
+
+#define is_pglargeobject(v) ((v)->ob_type == &PglargeType)
+#endif /* LARGE_OBJECTS */
+
+/* --------------------------------------------------------------------- */
+/* INTERNAL FUNCTIONS */
+
+
+/* prints result (mostly useful for debugging) */
+/* Note: This is a simplified version of the Postgres function PQprint().
+ * PQprint() is not used because handing over a stream from Python to
+ * Postgres can be problematic if they use different libs for streams.
+ * Also, PQprint() is considered obsolete and may be removed sometime.
+ */
+static void
+print_result(FILE *fout, const PGresult *res)
+{
+ int n = PQnfields(res);
+ if (n > 0)
+ {
+ int i, j;
+ int *fieldMax = NULL;
+ char **fields = NULL;
+ const char **fieldNames;
+ int m = PQntuples(res);
+ if (!(fieldNames = (const char **) calloc(n, sizeof(char *))))
+ {
+ fprintf(stderr, "out of memory\n"); exit(1);
+ }
+ if (!(fieldMax = (int *) calloc(n, sizeof(int))))
+ {
+ fprintf(stderr, "out of memory\n"); exit(1);
+ }
+ for (j = 0; j < n; j++)
+ {
+ const char *s = PQfname(res, j);
+ fieldNames[j] = s;
+ fieldMax[j] = s ? strlen(s) : 0;
+ }
+ if (!(fields = (char **) calloc(n * (m + 1), sizeof(char *))))
+ {
+ fprintf(stderr, "out of memory\n"); exit(1);
+ }
+ for (i = 0; i < m; i++)
+ {
+ for (j = 0; j < n; j++)
+ {
+ const char *val;
+ int len;
+ len = PQgetlength(res, i, j);
+ val = PQgetvalue(res, i, j);
+ if (len >= 1 && val && *val)
+ {
+ if (len > fieldMax[j])
+ fieldMax[j] = len;
+ if (!(fields[i * n + j] = (char *) malloc(len + 1)))
+ {
+ fprintf(stderr, "out of memory\n"); exit(1);
+ }
+ strcpy(fields[i * n + j], val);
+ }
+ }
+ }
+ for (j = 0; j < n; j++)
+ {
+ const char *s = PQfname(res, j);
+ int len = strlen(s);
+ if (len > fieldMax[j])
+ fieldMax[j] = len;
+ fprintf(fout, "%-*s", fieldMax[j], s);
+ if (j + 1 < n)
+ fputc('|', fout);
+ }
+ fputc('\n', fout);
+ for (j = 0; j < n; j++)
+ {
+ for (i = fieldMax[j]; i--; fputc('-', fout));
+ if (j + 1 < n)
+ fputc('+', fout);
+ }
+ fputc('\n', fout);
+ for (i = 0; i < m; i++)
+ {
+ for (j = 0; j < n; j++)
+ {
+ char *s = fields[i * n + j];
+ fprintf(fout, "%-*s", fieldMax[j], s ? s : "");
+ if (j + 1 < n)
+ fputc('|', fout);
+ if (s)
+ free(s);
+ }
+ fputc('\n', fout);
+ }
+ free(fields);
+ fprintf(fout, "(%d row%s)\n\n", m, m == 1 ? "" : "s");
+ free(fieldMax);
+ free((void *) fieldNames);
+ }
+}
+
+/* checks connection validity */
+static int
+check_cnx_obj(pgobject * self)
+{
+ if (!self->valid)
+ {
+ PyErr_SetString(IntegrityError, "connection has been closed.");
+ return 0;
+ }
+ return 1;
+}
+
+#ifdef LARGE_OBJECTS
+/* checks large object validity */
+static int
+check_lo_obj(pglargeobject * self, int level)
+{
+ if (!check_cnx_obj(self->pgcnx))
+ return 0;
+
+ if (!self->lo_oid)
+ {
+ PyErr_SetString(IntegrityError, "object is not valid (null oid).");
+ return 0;
+ }
+
+ if (level & CHECK_OPEN)
+ {
+ if (self->lo_fd < 0)
+ {
+ PyErr_SetString(PyExc_IOError, "object is not opened.");
+ return 0;
+ }
+ }
+
+ if (level & CHECK_CLOSE)
+ {
+ if (self->lo_fd >= 0)
+ {
+ PyErr_SetString(PyExc_IOError, "object is already opened.");
+ return 0;
+ }
+ }
+
+ return 1;
+}
+#endif /* LARGE_OBJECTS */
+
+/* checks source object validity */
+static int
+check_source_obj(pgsourceobject * self, int level)
+{
+ if (!self->valid)
+ {
+ PyErr_SetString(IntegrityError, "object has been closed");
+ return 0;
+ }
+
+ if ((level & CHECK_RESULT) && self->last_result == NULL)
+ {
+ PyErr_SetString(DatabaseError, "no result.");
+ return 0;
+ }
+
+ if ((level & CHECK_DQL) && self->result_type != RESULT_DQL)
+ {
+ PyErr_SetString(DatabaseError, "last query did not return tuples.");
+ return 0;
+ }
+
+ if ((level & CHECK_CNX) && !check_cnx_obj(self->pgcnx))
+ return 0;
+
+ return 1;
+}
+
+/* shared functions for converting PG types to Python types */
+int *
+get_type_array(PGresult *result, int nfields)
+{
+ int *typ;
+ int j;
+
+ if ((typ = malloc(sizeof(int) * nfields)) == NULL)
+ {
+ PyErr_SetString(PyExc_MemoryError, "memory error in getresult().");
+ return NULL;
+ }
+
+ for (j = 0; j < nfields; j++)
+ {
+ switch (PQftype(result, j))
+ {
+ case INT2OID:
+ case INT4OID:
+ case OIDOID:
+ typ[j] = 1;
+ break;
+
+ case INT8OID:
+ typ[j] = 2;
+ break;
+
+ case FLOAT4OID:
+ case FLOAT8OID:
+ typ[j] = 3;
+ break;
+
+ case NUMERICOID:
+ typ[j] = 4;
+ break;
+
+ case CASHOID:
+ typ[j] = 5;
+ break;
+
+ default:
+ typ[j] = 6;
+ break;
+ }
+ }
+
+ return typ;
+}
+
+
+/* prototypes for constructors */
+static pgsourceobject *pgsource_new(pgobject * pgcnx);
+
+/* --------------------------------------------------------------------- */
+/* PG SOURCE OBJECT IMPLEMENTATION */
+
+/* constructor (internal use only) */
+static pgsourceobject *
+pgsource_new(pgobject * pgcnx)
+{
+ pgsourceobject *npgobj;
+
+ /* allocates new query object */
+ if ((npgobj = PyObject_NEW(pgsourceobject, &PgSourceType)) == NULL)
+ return NULL;
+
+ /* initializes internal parameters */
+ Py_XINCREF(pgcnx);
+ npgobj->pgcnx = pgcnx;
+ npgobj->last_result = NULL;
+ npgobj->valid = 1;
+ npgobj->arraysize = PG_ARRAYSIZE;
+
+ return npgobj;
+}
+
+/* destructor */
+static void
+pgsource_dealloc(pgsourceobject * self)
+{
+ if (self->last_result)
+ PQclear(self->last_result);
+
+ Py_XDECREF(self->pgcnx);
+ PyObject_Del(self);
+}
+
+/* closes object */
+static char pgsource_close__doc__[] =
+"close() -- close query object without deleting it. "
+"All instances of the query object can no longer be used after this call.";
+
+static PyObject *
+pgsource_close(pgsourceobject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError, "method close() takes no parameter.");
+ return NULL;
+ }
+
+ /* frees result if necessary and invalidates object */
+ if (self->last_result)
+ {
+ PQclear(self->last_result);
+ self->result_type = RESULT_EMPTY;
+ self->last_result = NULL;
+ }
+
+ self->valid = 0;
+
+ /* return None */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* database query */
+static char pgsource_execute__doc__[] =
+"execute(sql) -- execute a SQL statement (string).\n "
+"On success, this call returns the number of affected rows, "
+"or None for DQL (SELECT, ...) statements.\n"
+"The fetch (fetch(), fetchone() and fetchall()) methods can be used "
+"to get result rows.";
+
+static PyObject *
+pgsource_execute(pgsourceobject * self, PyObject * args)
+{
+ char *query;
+
+ /* checks validity */
+ if (!check_source_obj(self, CHECK_CNX))
+ return NULL;
+
+ /* make sure that the connection object is valid */
+ if (!self->pgcnx->cnx)
+ return NULL;
+
+ /* get query args */
+ if (!PyArg_ParseTuple(args, "s", &query))
+ {
+ PyErr_SetString(PyExc_TypeError, "execute(sql), with sql (string).");
+ return NULL;
+ }
+
+ /* frees previous result */
+ if (self->last_result)
+ {
+ PQclear(self->last_result);
+ self->last_result = NULL;
+ }
+ self->max_row = 0;
+ self->current_row = 0;
+ self->num_fields = 0;
+
+ /* gets result */
+ Py_BEGIN_ALLOW_THREADS
+ self->last_result = PQexec(self->pgcnx->cnx, query);
+ Py_END_ALLOW_THREADS
+
+ /* checks result validity */
+ if (!self->last_result)
+ {
+ PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->pgcnx->cnx));
+ return NULL;
+ }
+
+ /* checks result status */
+ switch (PQresultStatus(self->last_result))
+ {
+ long num_rows;
+ char *temp;
+
+ /* query succeeded */
+ case PGRES_TUPLES_OK: /* DQL: returns None (DB-SIG compliant) */
+ self->result_type = RESULT_DQL;
+ self->max_row = PQntuples(self->last_result);
+ self->num_fields = PQnfields(self->last_result);
+ Py_INCREF(Py_None);
+ return Py_None;
+ case PGRES_COMMAND_OK: /* other requests */
+ case PGRES_COPY_OUT:
+ case PGRES_COPY_IN:
+ self->result_type = RESULT_DDL;
+ temp = PQcmdTuples(self->last_result);
+ num_rows = -1;
+ if (temp[0])
+ {
+ self->result_type = RESULT_DML;
+ num_rows = atol(temp);
+ }
+ return PyInt_FromLong(num_rows);
+
+ /* query failed */
+ case PGRES_EMPTY_QUERY:
+ PyErr_SetString(PyExc_ValueError, "empty query.");
+ break;
+ case PGRES_BAD_RESPONSE:
+ case PGRES_FATAL_ERROR:
+ case PGRES_NONFATAL_ERROR:
+ PyErr_SetString(ProgrammingError, PQerrorMessage(self->pgcnx->cnx));
+ break;
+ default:
+ PyErr_SetString(InternalError, "internal error: "
+ "unknown result status.");
+ break;
+ }
+
+ /* frees result and returns error */
+ PQclear(self->last_result);
+ self->last_result = NULL;
+ self->result_type = RESULT_EMPTY;
+ return NULL;
+}
+
+/* gets oid status for last query (valid for INSERTs, 0 for other) */
+static char pgsource_oidstatus__doc__[] =
+"oidstatus() -- return oid of last inserted row (if available).";
+
+static PyObject *
+pgsource_oidstatus(pgsourceobject * self, PyObject * args)
+{
+ Oid oid;
+
+ /* checks validity */
+ if (!check_source_obj(self, CHECK_RESULT))
+ return NULL;
+
+ /* checks args */
+ if ((args != NULL) && (!PyArg_ParseTuple(args, "")))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method oidstatus() takes no parameters.");
+ return NULL;
+ }
+
+ /* retrieves oid status */
+ if ((oid = PQoidValue(self->last_result)) == InvalidOid)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ return PyInt_FromLong(oid);
+}
+
+/* fetches rows from last result */
+static char pgsource_fetch__doc__[] =
+"fetch(num) -- return the next num rows from the last result in a list. "
+"If num parameter is omitted arraysize attribute value is used. "
+"If size equals -1, all rows are fetched.";
+
+static PyObject *
+pgsource_fetch(pgsourceobject * self, PyObject * args)
+{
+ PyObject *rowtuple,
+ *reslist,
+ *str;
+ int i,
+ j;
+ long size;
+
+ /* checks validity */
+ if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
+ return NULL;
+
+ /* checks args */
+ size = self->arraysize;
+ if (!PyArg_ParseTuple(args, "|l", &size))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "fetch(num), with num (integer, optional).");
+ return NULL;
+ }
+
+ /* seeks last line */
+ /* limit size to be within the amount of data we actually have */
+ if (size == -1 || (self->max_row - self->current_row) < size)
+ size = self->max_row - self->current_row;
+
+ /* allocate list for result */
+ if ((reslist = PyList_New(0)) == NULL)
+ return NULL;
+
+ /* builds result */
+ for (i = 0; i < size; ++i)
+ {
+ if ((rowtuple = PyTuple_New(self->num_fields)) == NULL)
+ {
+ Py_DECREF(reslist);
+ return NULL;
+ }
+
+ for (j = 0; j < self->num_fields; j++)
+ {
+ if (PQgetisnull(self->last_result, self->current_row, j))
+ {
+ Py_INCREF(Py_None);
+ str = Py_None;
+ }
+ else
+ str = PyString_FromString(PQgetvalue(self->last_result, self->current_row, j));
+
+ PyTuple_SET_ITEM(rowtuple, j, str);
+ }
+
+ PyList_Append(reslist, rowtuple);
+ Py_DECREF(rowtuple);
+ self->current_row++;
+ }
+
+ return reslist;
+}
+
+/* changes current row (internal wrapper for all "move" methods) */
+static PyObject *
+pgsource_move(pgsourceobject * self, PyObject * args, int move)
+{
+ /* checks validity */
+ if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
+ return NULL;
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ char errbuf[256];
+ PyOS_snprintf(errbuf, sizeof(errbuf),
+ "method %s() takes no parameter.", __movename[move]);
+ PyErr_SetString(PyExc_TypeError, errbuf);
+ return NULL;
+ }
+
+ /* changes the current row */
+ switch (move)
+ {
+ case QUERY_MOVEFIRST:
+ self->current_row = 0;
+ break;
+ case QUERY_MOVELAST:
+ self->current_row = self->max_row - 1;
+ break;
+ case QUERY_MOVENEXT:
+ if (self->current_row != self->max_row)
+ self->current_row++;
+ break;
+ case QUERY_MOVEPREV:
+ if (self->current_row > 0)
+ self->current_row--;
+ break;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* move to first result row */
+static char pgsource_movefirst__doc__[] =
+"movefirst() -- move to first result row.";
+
+static PyObject *
+pgsource_movefirst(pgsourceobject * self, PyObject * args)
+{
+ return pgsource_move(self, args, QUERY_MOVEFIRST);
+}
+
+/* move to last result row */
+static char pgsource_movelast__doc__[] =
+"movelast() -- move to last valid result row.";
+
+static PyObject *
+pgsource_movelast(pgsourceobject * self, PyObject * args)
+{
+ return pgsource_move(self, args, QUERY_MOVELAST);
+}
+
+/* move to next result row */
+static char pgsource_movenext__doc__[] =
+"movenext() -- move to next result row.";
+
+static PyObject *
+pgsource_movenext(pgsourceobject * self, PyObject * args)
+{
+ return pgsource_move(self, args, QUERY_MOVENEXT);
+}
+
+/* move to previous result row */
+static char pgsource_moveprev__doc__[] =
+"moveprev() -- move to previous result row.";
+
+static PyObject *
+pgsource_moveprev(pgsourceobject * self, PyObject * args)
+{
+ return pgsource_move(self, args, QUERY_MOVEPREV);
+}
+
+/* finds field number from string/integer (internal use only) */
+static int
+pgsource_fieldindex(pgsourceobject * self, PyObject * param, const char *usage)
+{
+ int num;
+
+ /* checks validity */
+ if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
+ return -1;
+
+ /* gets field number */
+ if (PyString_Check(param))
+ num = PQfnumber(self->last_result, PyString_AsString(param));
+ else if (PyInt_Check(param))
+ num = PyInt_AsLong(param);
+ else
+ {
+ PyErr_SetString(PyExc_TypeError, usage);
+ return -1;
+ }
+
+ /* checks field validity */
+ if (num < 0 || num >= self->num_fields)
+ {
+ PyErr_SetString(PyExc_ValueError, "Unknown field.");
+ return -1;
+ }
+
+ return num;
+}
+
+/* builds field information from position (internal use only) */
+static PyObject *
+pgsource_buildinfo(pgsourceobject * self, int num)
+{
+ PyObject *result;
+
+ /* allocates tuple */
+ result = PyTuple_New(3);
+ if (!result)
+ return NULL;
+
+ /* affects field information */
+ PyTuple_SET_ITEM(result, 0, PyInt_FromLong(num));
+ PyTuple_SET_ITEM(result, 1,
+ PyString_FromString(PQfname(self->last_result, num)));
+ PyTuple_SET_ITEM(result, 2,
+ PyInt_FromLong(PQftype(self->last_result, num)));
+
+ return result;
+}
+
+/* lists fields info */
+static char pgsource_listinfo__doc__[] =
+"listinfo() -- return information for all fields "
+"(position, name, type oid).";
+
+static PyObject *
+pgsource_listinfo(pgsourceobject * self, PyObject * args)
+{
+ int i;
+ PyObject *result,
+ *info;
+
+ /* checks validity */
+ if (!check_source_obj(self, CHECK_RESULT | CHECK_DQL))
+ return NULL;
+
+ /* gets args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method listinfo() takes no parameter.");
+ return NULL;
+ }
+
+ /* builds result */
+ if ((result = PyTuple_New(self->num_fields)) == NULL)
+ return NULL;
+
+ for (i = 0; i < self->num_fields; i++)
+ {
+ info = pgsource_buildinfo(self, i);
+ if (!info)
+ {
+ Py_DECREF(result);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(result, i, info);
+ }
+
+ /* returns result */
+ return result;
+};
+
+/* list fields information for last result */
+static char pgsource_fieldinfo__doc__[] =
+"fieldinfo(string|integer) -- return specified field information "
+"(position, name, type oid).";
+
+static PyObject *
+pgsource_fieldinfo(pgsourceobject * self, PyObject * args)
+{
+ static const char short_usage[] =
+ "fieldinfo(desc), with desc (string|integer).";
+ int num;
+ PyObject *param;
+
+ /* gets args */
+ if (!PyArg_ParseTuple(args, "O", ¶m))
+ {
+ PyErr_SetString(PyExc_TypeError, short_usage);
+ return NULL;
+ }
+
+ /* checks args and validity */
+ if ((num = pgsource_fieldindex(self, param, short_usage)) == -1)
+ return NULL;
+
+ /* returns result */
+ return pgsource_buildinfo(self, num);
+};
+
+/* retrieve field value */
+static char pgsource_field__doc__[] =
+"field(string|integer) -- return specified field value.";
+
+static PyObject *
+pgsource_field(pgsourceobject * self, PyObject * args)
+{
+ static const char short_usage[] =
+ "field(desc), with desc (string|integer).";
+ int num;
+ PyObject *param;
+
+ /* gets args */
+ if (!PyArg_ParseTuple(args, "O", ¶m))
+ {
+ PyErr_SetString(PyExc_TypeError, short_usage);
+ return NULL;
+ }
+
+ /* checks args and validity */
+ if ((num = pgsource_fieldindex(self, param, short_usage)) == -1)
+ return NULL;
+
+ return PyString_FromString(PQgetvalue(self->last_result,
+ self->current_row, num));
+}
+
+/* query object methods */
+static PyMethodDef pgsource_methods[] = {
+ {"close", (PyCFunction) pgsource_close, METH_VARARGS,
+ pgsource_close__doc__},
+ {"execute", (PyCFunction) pgsource_execute, METH_VARARGS,
+ pgsource_execute__doc__},
+ {"oidstatus", (PyCFunction) pgsource_oidstatus, METH_VARARGS,
+ pgsource_oidstatus__doc__},
+ {"fetch", (PyCFunction) pgsource_fetch, METH_VARARGS,
+ pgsource_fetch__doc__},
+ {"movefirst", (PyCFunction) pgsource_movefirst, METH_VARARGS,
+ pgsource_movefirst__doc__},
+ {"movelast", (PyCFunction) pgsource_movelast, METH_VARARGS,
+ pgsource_movelast__doc__},
+ {"movenext", (PyCFunction) pgsource_movenext, METH_VARARGS,
+ pgsource_movenext__doc__},
+ {"moveprev", (PyCFunction) pgsource_moveprev, METH_VARARGS,
+ pgsource_moveprev__doc__},
+ {"field", (PyCFunction) pgsource_field, METH_VARARGS,
+ pgsource_field__doc__},
+ {"fieldinfo", (PyCFunction) pgsource_fieldinfo, METH_VARARGS,
+ pgsource_fieldinfo__doc__},
+ {"listinfo", (PyCFunction) pgsource_listinfo, METH_VARARGS,
+ pgsource_listinfo__doc__},
+ {NULL, NULL}
+};
+
+/* gets query object attributes */
+static PyObject *
+pgsource_getattr(pgsourceobject * self, char *name)
+{
+ /* pg connection object */
+ if (!strcmp(name, "pgcnx"))
+ {
+ if (check_source_obj(self, 0))
+ {
+ Py_INCREF(self->pgcnx);
+ return (PyObject *) (self->pgcnx);
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ /* arraysize */
+ if (!strcmp(name, "arraysize"))
+ return PyInt_FromLong(self->arraysize);
+
+ /* resulttype */
+ if (!strcmp(name, "resulttype"))
+ return PyInt_FromLong(self->result_type);
+
+ /* ntuples */
+ if (!strcmp(name, "ntuples"))
+ return PyInt_FromLong(self->max_row);
+
+ /* nfields */
+ if (!strcmp(name, "nfields"))
+ return PyInt_FromLong(self->num_fields);
+
+ /* attributes list */
+ if (!strcmp(name, "__members__"))
+ {
+ PyObject *list = PyList_New(5);
+
+ PyList_SET_ITEM(list, 0, PyString_FromString("pgcnx"));
+ PyList_SET_ITEM(list, 1, PyString_FromString("arraysize"));
+ PyList_SET_ITEM(list, 2, PyString_FromString("resulttype"));
+ PyList_SET_ITEM(list, 3, PyString_FromString("ntuples"));
+ PyList_SET_ITEM(list, 4, PyString_FromString("nfields"));
+
+ return list;
+ }
+
+ /* module name */
+ if (!strcmp(name, "__module__"))
+ return PyString_FromString(MODULE_NAME);
+
+ /* class name */
+ if (!strcmp(name, "__class__"))
+ return PyString_FromString("pgsource");
+
+ /* seeks name in methods (fallback) */
+ return Py_FindMethod(pgsource_methods, (PyObject *) self, name);
+}
+
+/* sets query object attributes */
+static int
+pgsource_setattr(pgsourceobject * self, char *name, PyObject * v)
+{
+ /* arraysize */
+ if (!strcmp(name, "arraysize"))
+ {
+ if (!PyInt_Check(v))
+ {
+ PyErr_SetString(PyExc_TypeError, "arraysize must be integer.");
+ return -1;
+ }
+
+ self->arraysize = PyInt_AsLong(v);
+ return 0;
+ }
+
+ /* unknown attribute */
+ PyErr_SetString(PyExc_TypeError, "not a writable attribute.");
+ return -1;
+}
+
+/* prints query object in human readable format */
+
+static int
+pgsource_print(pgsourceobject * self, FILE *fp, int flags)
+{
+ switch (self->result_type)
+ {
+ case RESULT_DQL:
+ print_result(fp, self->last_result);
+ break;
+ case RESULT_DDL:
+ case RESULT_DML:
+ fputs(PQcmdStatus(self->last_result), fp);
+ break;
+ case RESULT_EMPTY:
+ default:
+ fputs("Empty PostgreSQL source object.", fp);
+ break;
+ }
+
+ return 0;
+}
+
+/* query type definition */
+staticforward PyTypeObject PgSourceType = {
+ PyObject_HEAD_INIT(NULL)
+
+ 0, /* ob_size */
+ "pgsourceobject", /* tp_name */
+ sizeof(pgsourceobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor) pgsource_dealloc, /* tp_dealloc */
+ (printfunc) pgsource_print, /* tp_print */
+ (getattrfunc) pgsource_getattr, /* tp_getattr */
+ (setattrfunc) pgsource_setattr, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+};
+
+/* --------------------------------------------------------------------- */
+/* PG "LARGE" OBJECT IMPLEMENTATION */
+
+#ifdef LARGE_OBJECTS
+
+/* constructor (internal use only) */
+static pglargeobject *
+pglarge_new(pgobject * pgcnx, Oid oid)
+{
+ pglargeobject *npglo;
+
+ if ((npglo = PyObject_NEW(pglargeobject, &PglargeType)) == NULL)
+ return NULL;
+
+ Py_XINCREF(pgcnx);
+ npglo->pgcnx = pgcnx;
+ npglo->lo_fd = -1;
+ npglo->lo_oid = oid;
+
+ return npglo;
+}
+
+/* destructor */
+static void
+pglarge_dealloc(pglargeobject * self)
+{
+ if (self->lo_fd >= 0 && check_cnx_obj(self->pgcnx))
+ lo_close(self->pgcnx->cnx, self->lo_fd);
+
+ Py_XDECREF(self->pgcnx);
+ PyObject_Del(self);
+}
+
+/* opens large object */
+static char pglarge_open__doc__[] =
+"open(mode) -- open access to large object with specified mode "
+"(INV_READ, INV_WRITE constants defined by module).";
+
+static PyObject *
+pglarge_open(pglargeobject * self, PyObject * args)
+{
+ int mode,
+ fd;
+
+ /* check validity */
+ if (!check_lo_obj(self, CHECK_CLOSE))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "i", &mode))
+ {
+ PyErr_SetString(PyExc_TypeError, "open(mode), with mode(integer).");
+ return NULL;
+ }
+
+ /* opens large object */
+ if ((fd = lo_open(self->pgcnx->cnx, self->lo_oid, mode)) < 0)
+ {
+ PyErr_SetString(PyExc_IOError, "can't open large object.");
+ return NULL;
+ }
+ self->lo_fd = fd;
+
+ /* no error : returns Py_None */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* close large object */
+static char pglarge_close__doc__[] =
+"close() -- close access to large object data.";
+
+static PyObject *
+pglarge_close(pglargeobject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method close() takes no parameters.");
+ return NULL;
+ }
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_OPEN))
+ return NULL;
+
+ /* closes large object */
+ if (lo_close(self->pgcnx->cnx, self->lo_fd))
+ {
+ PyErr_SetString(PyExc_IOError, "error while closing large object fd.");
+ return NULL;
+ }
+ self->lo_fd = -1;
+
+ /* no error : returns Py_None */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* reads from large object */
+static char pglarge_read__doc__[] =
+"read(integer) -- read from large object to sized string. "
+"Object must be opened in read mode before calling this method.";
+
+static PyObject *
+pglarge_read(pglargeobject * self, PyObject * args)
+{
+ int size;
+ PyObject *buffer;
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_OPEN))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "i", &size))
+ {
+ PyErr_SetString(PyExc_TypeError, "read(size), wih size (integer).");
+ return NULL;
+ }
+
+ if (size <= 0)
+ {
+ PyErr_SetString(PyExc_ValueError, "size must be positive.");
+ return NULL;
+ }
+
+ /* allocate buffer and runs read */
+ buffer = PyString_FromStringAndSize((char *) NULL, size);
+
+ if ((size = lo_read(self->pgcnx->cnx, self->lo_fd, BUF(buffer), size)) < 0)
+ {
+ PyErr_SetString(PyExc_IOError, "error while reading.");
+ Py_XDECREF(buffer);
+ return NULL;
+ }
+
+ /* resize buffer and returns it */
+ _PyString_Resize(&buffer, size);
+ return buffer;
+}
+
+/* write to large object */
+static char pglarge_write__doc__[] =
+"write(string) -- write sized string to large object. "
+"Object must be opened in read mode before calling this method.";
+
+static PyObject *
+pglarge_write(pglargeobject * self, PyObject * args)
+{
+ char *buffer;
+ int size,
+ bufsize;
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_OPEN))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "s#", &buffer, &bufsize))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "write(buffer), with buffer (sized string).");
+ return NULL;
+ }
+
+ /* sends query */
+ if ((size = lo_write(self->pgcnx->cnx, self->lo_fd, buffer,
+ bufsize)) < bufsize)
+ {
+ PyErr_SetString(PyExc_IOError, "buffer truncated during write.");
+ return NULL;
+ }
+
+ /* no error : returns Py_None */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* go to position in large object */
+static char pglarge_seek__doc__[] =
+"seek(off, whence) -- move to specified position. Object must be opened "
+"before calling this method. whence can be SEEK_SET, SEEK_CUR or SEEK_END, "
+"constants defined by module.";
+
+static PyObject *
+pglarge_lseek(pglargeobject * self, PyObject * args)
+{
+ /* offset and whence are initialized to keep compiler happy */
+ int ret,
+ offset = 0,
+ whence = 0;
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_OPEN))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "ii", &offset, &whence))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "lseek(offset, whence), with offset and whence (integers).");
+ return NULL;
+ }
+
+ /* sends query */
+ if ((ret = lo_lseek(self->pgcnx->cnx, self->lo_fd, offset, whence)) == -1)
+ {
+ PyErr_SetString(PyExc_IOError, "error while moving cursor.");
+ return NULL;
+ }
+
+ /* returns position */
+ return PyInt_FromLong(ret);
+}
+
+/* gets large object size */
+static char pglarge_size__doc__[] =
+"size() -- return large object size. "
+"Object must be opened before calling this method.";
+
+static PyObject *
+pglarge_size(pglargeobject * self, PyObject * args)
+{
+ int start,
+ end;
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method size() takes no parameters.");
+ return NULL;
+ }
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_OPEN))
+ return NULL;
+
+ /* gets current position */
+ if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
+ {
+ PyErr_SetString(PyExc_IOError, "error while getting current position.");
+ return NULL;
+ }
+
+ /* gets end position */
+ if ((end = lo_lseek(self->pgcnx->cnx, self->lo_fd, 0, SEEK_END)) == -1)
+ {
+ PyErr_SetString(PyExc_IOError, "error while getting end position.");
+ return NULL;
+ }
+
+ /* move back to start position */
+ if ((start = lo_lseek(self->pgcnx->cnx, self->lo_fd, start, SEEK_SET)) == -1)
+ {
+ PyErr_SetString(PyExc_IOError,
+ "error while moving back to first position.");
+ return NULL;
+ }
+
+ /* returns size */
+ return PyInt_FromLong(end);
+}
+
+/* gets large object cursor position */
+static char pglarge_tell__doc__[] =
+"tell() -- give current position in large object. "
+"Object must be opened before calling this method.";
+
+static PyObject *
+pglarge_tell(pglargeobject * self, PyObject * args)
+{
+ int start;
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method tell() takes no parameters.");
+ return NULL;
+ }
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_OPEN))
+ return NULL;
+
+ /* gets current position */
+ if ((start = lo_tell(self->pgcnx->cnx, self->lo_fd)) == -1)
+ {
+ PyErr_SetString(PyExc_IOError, "error while getting position.");
+ return NULL;
+ }
+
+ /* returns size */
+ return PyInt_FromLong(start);
+}
+
+/* exports large object as unix file */
+static char pglarge_export__doc__[] =
+"export(string) -- export large object data to specified file. "
+"Object must be closed when calling this method.";
+
+static PyObject *
+pglarge_export(pglargeobject * self, PyObject * args)
+{
+ char *name;
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_CLOSE))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "s", &name))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "export(filename), with filename (string).");
+ return NULL;
+ }
+
+ /* runs command */
+ if (!lo_export(self->pgcnx->cnx, self->lo_oid, name))
+ {
+ PyErr_SetString(PyExc_IOError, "error while exporting large object.");
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* deletes a large object */
+static char pglarge_unlink__doc__[] =
+"unlink() -- destroy large object. "
+"Object must be closed when calling this method.";
+
+static PyObject *
+pglarge_unlink(pglargeobject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method unlink() takes no parameters.");
+ return NULL;
+ }
+
+ /* checks validity */
+ if (!check_lo_obj(self, CHECK_CLOSE))
+ return NULL;
+
+ /* deletes the object, invalidate it on success */
+ if (!lo_unlink(self->pgcnx->cnx, self->lo_oid))
+ {
+ PyErr_SetString(PyExc_IOError, "error while unlinking large object");
+ return NULL;
+ }
+ self->lo_oid = 0;
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* large object methods */
+static struct PyMethodDef pglarge_methods[] = {
+ {"open", (PyCFunction) pglarge_open, METH_VARARGS, pglarge_open__doc__},
+ {"close", (PyCFunction) pglarge_close, METH_VARARGS, pglarge_close__doc__},
+ {"read", (PyCFunction) pglarge_read, METH_VARARGS, pglarge_read__doc__},
+ {"write", (PyCFunction) pglarge_write, METH_VARARGS, pglarge_write__doc__},
+ {"seek", (PyCFunction) pglarge_lseek, METH_VARARGS, pglarge_seek__doc__},
+ {"size", (PyCFunction) pglarge_size, METH_VARARGS, pglarge_size__doc__},
+ {"tell", (PyCFunction) pglarge_tell, METH_VARARGS, pglarge_tell__doc__},
+ {"export",(PyCFunction) pglarge_export,METH_VARARGS,pglarge_export__doc__},
+ {"unlink",(PyCFunction) pglarge_unlink,METH_VARARGS,pglarge_unlink__doc__},
+ {NULL, NULL}
+};
+
+/* get attribute */
+static PyObject *
+pglarge_getattr(pglargeobject * self, char *name)
+{
+ /* list postgreSQL large object fields */
+
+ /* associated pg connection object */
+ if (!strcmp(name, "pgcnx"))
+ {
+ if (check_lo_obj(self, 0))
+ {
+ Py_INCREF(self->pgcnx);
+ return (PyObject *) (self->pgcnx);
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ /* large object oid */
+ if (!strcmp(name, "oid"))
+ {
+ if (check_lo_obj(self, 0))
+ return PyInt_FromLong(self->lo_oid);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ /* error (status) message */
+ if (!strcmp(name, "error"))
+ return PyString_FromString(PQerrorMessage(self->pgcnx->cnx));
+
+ /* attributes list */
+ if (!strcmp(name, "__members__"))
+ {
+ PyObject *list = PyList_New(3);
+
+ if (list)
+ {
+ PyList_SET_ITEM(list, 0, PyString_FromString("oid"));
+ PyList_SET_ITEM(list, 1, PyString_FromString("pgcnx"));
+ PyList_SET_ITEM(list, 2, PyString_FromString("error"));
+ }
+
+ return list;
+ }
+
+ /* module name */
+ if (!strcmp(name, "__module__"))
+ return PyString_FromString(MODULE_NAME);
+
+ /* class name */
+ if (!strcmp(name, "__class__"))
+ return PyString_FromString("pglarge");
+
+ /* seeks name in methods (fallback) */
+ return Py_FindMethod(pglarge_methods, (PyObject *) self, name);
+}
+
+/* prints query object in human readable format */
+static int
+pglarge_print(pglargeobject * self, FILE *fp, int flags)
+{
+ char print_buffer[128];
+ PyOS_snprintf(print_buffer, sizeof(print_buffer),
+ self->lo_fd >= 0 ?
+ "Opened large object, oid %ld" :
+ "Closed large object, oid %ld", (long) self->lo_oid);
+ fputs(print_buffer, fp);
+ return 0;
+}
+
+/* object type definition */
+staticforward PyTypeObject PglargeType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "pglarge", /* tp_name */
+ sizeof(pglargeobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+
+ /* methods */
+ (destructor) pglarge_dealloc, /* tp_dealloc */
+ (printfunc) pglarge_print, /* tp_print */
+ (getattrfunc) pglarge_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+};
+#endif /* LARGE_OBJECTS */
+
+
+/* --------------------------------------------------------------------- */
+/* PG QUERY OBJECT IMPLEMENTATION */
+
+/* connects to a database */
+static char connect__doc__[] =
+"connect(dbname, host, port, opt, tty) -- connect to a PostgreSQL database "
+"using specified parameters (optionals, keywords aware).";
+
+static PyObject *
+pgconnect(pgobject * self, PyObject * args, PyObject * dict)
+{
+ static const char *kwlist[] = {"dbname", "host", "port", "opt",
+ "tty", "user", "passwd", NULL};
+
+ char *pghost,
+ *pgopt,
+ *pgtty,
+ *pgdbname,
+ *pguser,
+ *pgpasswd;
+ int pgport;
+ char port_buffer[20];
+ pgobject *npgobj;
+
+ pghost = pgopt = pgtty = pgdbname = pguser = pgpasswd = NULL;
+ pgport = -1;
+
+ /*
+ * parses standard arguments With the right compiler warnings, this
+ * will issue a diagnostic. There is really no way around it. If I
+ * don't declare kwlist as const char *kwlist[] then it complains when
+ * I try to assign all those constant strings to it.
+ */
+ if (!PyArg_ParseTupleAndKeywords(args, dict, "|zzizzzz", (char **) kwlist,
+ &pgdbname, &pghost, &pgport, &pgopt, &pgtty, &pguser, &pgpasswd))
+ return NULL;
+
+#ifdef DEFAULT_VARS
+ /* handles defaults variables (for uninitialised vars) */
+ if ((!pghost) && (pg_default_host != Py_None))
+ pghost = PyString_AsString(pg_default_host);
+
+ if ((pgport == -1) && (pg_default_port != Py_None))
+ pgport = PyInt_AsLong(pg_default_port);
+
+ if ((!pgopt) && (pg_default_opt != Py_None))
+ pgopt = PyString_AsString(pg_default_opt);
+
+ if ((!pgtty) && (pg_default_tty != Py_None))
+ pgtty = PyString_AsString(pg_default_tty);
+
+ if ((!pgdbname) && (pg_default_base != Py_None))
+ pgdbname = PyString_AsString(pg_default_base);
+
+ if ((!pguser) && (pg_default_user != Py_None))
+ pguser = PyString_AsString(pg_default_user);
+
+ if ((!pgpasswd) && (pg_default_passwd != Py_None))
+ pgpasswd = PyString_AsString(pg_default_passwd);
+#endif /* DEFAULT_VARS */
+
+ if ((npgobj = (pgobject *) pgobject_New()) == NULL)
+ return NULL;
+
+ if (pgport != -1)
+ {
+ memset(port_buffer, 0, sizeof(port_buffer));
+ sprintf(port_buffer, "%d", pgport);
+ }
+
+#ifdef PQsetdbLoginIsThreadSafe
+ Py_BEGIN_ALLOW_THREADS
+#endif
+ npgobj->cnx = PQsetdbLogin(pghost, pgport == -1 ? NULL : port_buffer,
+ pgopt, pgtty, pgdbname, pguser, pgpasswd);
+#ifdef PQsetdbLoginIsThreadSafe
+ Py_END_ALLOW_THREADS
+#endif
+
+ if (PQstatus(npgobj->cnx) == CONNECTION_BAD)
+ {
+ PyErr_SetString(InternalError, PQerrorMessage(npgobj->cnx));
+ Py_XDECREF(npgobj);
+ return NULL;
+ }
+
+#ifdef HANDLE_NOTICES
+ PQsetNoticeProcessor(npgobj->cnx, notice_processor, npgobj);
+#endif /* HANDLE_NOTICES */
+
+ return (PyObject *) npgobj;
+}
+
+/* pgobject methods */
+
+/* destructor */
+static void
+pg_dealloc(pgobject * self)
+{
+#ifdef HANDLE_NOTICES
+ free(self->notices);
+#endif /* HANDLE_NOTICES */
+ if (self->cnx)
+ {
+ Py_BEGIN_ALLOW_THREADS
+ PQfinish(self->cnx);
+ Py_END_ALLOW_THREADS
+ }
+ PyObject_Del(self);
+}
+
+/* close without deleting */
+static char pg_close__doc__[] =
+"close() -- close connection. All instances of the connection object and "
+"derived objects (queries and large objects) can no longer be used after "
+"this call.";
+
+static PyObject *
+pg_close(pgobject * self, PyObject * args)
+{
+ /* gets args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError, "close().");
+ return NULL;
+ }
+
+ /* connection object cannot already be closed */
+ if (!self->cnx)
+ {
+ PyErr_SetString(InternalError, "Connection already closed");
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ PQfinish(self->cnx);
+ Py_END_ALLOW_THREADS
+
+ self->cnx = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static void
+pgquery_dealloc(pgqueryobject * self)
+{
+ if (self->last_result)
+ PQclear(self->last_result);
+
+ PyObject_Del(self);
+}
+
+/* resets connection */
+static char pg_reset__doc__[] =
+"reset() -- reset connection with current parameters. All derived queries "
+"and large objects derived from this connection will not be usable after "
+"this call.";
+
+static PyObject *
+pg_reset(pgobject * self, PyObject * args)
+{
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method reset() takes no parameters.");
+ return NULL;
+ }
+
+ /* resets the connection */
+ PQreset(self->cnx);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* cancels current command */
+static char pg_cancel__doc__[] =
+"cancel() -- abandon processing of the current command.";
+
+static PyObject *
+pg_cancel(pgobject * self, PyObject * args)
+{
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method cancel() takes no parameters.");
+ return NULL;
+ }
+
+ /* request that the server abandon processing of the current command */
+ return PyInt_FromLong((long) PQrequestCancel(self->cnx));
+}
+
+/* get connection socket */
+static char pg_fileno__doc__[] =
+"fileno() -- return database connection socket file handle.";
+
+static PyObject *
+pg_fileno(pgobject * self, PyObject * args)
+{
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method fileno() takes no parameters.");
+ return NULL;
+ }
+
+#ifdef NO_PQSOCKET
+ return PyInt_FromLong((long) self->cnx->sock);
+#else
+ return PyInt_FromLong((long) PQsocket(self->cnx));
+#endif
+}
+
+/* get number of rows */
+static char pgquery_ntuples__doc__[] =
+"ntuples() -- returns number of tuples returned by query.";
+
+static PyObject *
+pgquery_ntuples(pgqueryobject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method ntuples() takes no parameters.");
+ return NULL;
+ }
+
+ return PyInt_FromLong((long) PQntuples(self->last_result));
+}
+
+/* list fields names from query result */
+static char pgquery_listfields__doc__[] =
+"listfields() -- Lists field names from result.";
+
+static PyObject *
+pgquery_listfields(pgqueryobject * self, PyObject * args)
+{
+ int i,
+ n;
+ char *name;
+ PyObject *fieldstuple,
+ *str;
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method listfields() takes no parameters.");
+ return NULL;
+ }
+
+ /* builds tuple */
+ n = PQnfields(self->last_result);
+ fieldstuple = PyTuple_New(n);
+
+ for (i = 0; i < n; i++)
+ {
+ name = PQfname(self->last_result, i);
+ str = PyString_FromString(name);
+ PyTuple_SET_ITEM(fieldstuple, i, str);
+ }
+
+ return fieldstuple;
+}
+
+/* get field name from last result */
+static char pgquery_fieldname__doc__[] =
+"fieldname() -- returns name of field from result from its position.";
+
+static PyObject *
+pgquery_fieldname(pgqueryobject * self, PyObject * args)
+{
+ int i;
+ char *name;
+
+ /* gets args */
+ if (!PyArg_ParseTuple(args, "i", &i))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "fieldname(number), with number(integer).");
+ return NULL;
+ }
+
+ /* checks number validity */
+ if (i >= PQnfields(self->last_result))
+ {
+ PyErr_SetString(PyExc_ValueError, "invalid field number.");
+ return NULL;
+ }
+
+ /* gets fields name and builds object */
+ name = PQfname(self->last_result, i);
+ return PyString_FromString(name);
+}
+
+/* gets fields number from name in last result */
+static char pgquery_fieldnum__doc__[] =
+"fieldnum() -- returns position in query for field from its name.";
+
+static PyObject *
+pgquery_fieldnum(pgqueryobject * self, PyObject * args)
+{
+ int num;
+ char *name;
+
+ /* gets args */
+ if (!PyArg_ParseTuple(args, "s", &name))
+ {
+ PyErr_SetString(PyExc_TypeError, "fieldnum(name), with name (string).");
+ return NULL;
+ }
+
+ /* gets field number */
+ if ((num = PQfnumber(self->last_result, name)) == -1)
+ {
+ PyErr_SetString(PyExc_ValueError, "Unknown field.");
+ return NULL;
+ }
+
+ return PyInt_FromLong(num);
+}
+
+/* retrieves last result */
+static char pgquery_getresult__doc__[] =
+"getresult() -- Gets the result of a query. The result is returned "
+"as a list of rows, each one a list of fields in the order returned "
+"by the server.";
+
+static PyObject *
+pgquery_getresult(pgqueryobject * self, PyObject * args)
+{
+ PyObject *rowtuple,
+ *reslist,
+ *val;
+ int i,
+ j,
+ m,
+ n,
+ *typ;
+
+ /* checks args (args == NULL for an internal call) */
+ if ((args != NULL) && (!PyArg_ParseTuple(args, "")))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method getresult() takes no parameters.");
+ return NULL;
+ }
+
+ /* stores result in tuple */
+ m = PQntuples(self->last_result);
+ n = PQnfields(self->last_result);
+ reslist = PyList_New(m);
+
+ typ = get_type_array(self->last_result, n);
+
+ for (i = 0; i < m; i++)
+ {
+ if ((rowtuple = PyTuple_New(n)) == NULL)
+ {
+ Py_DECREF(reslist);
+ reslist = NULL;
+ goto exit;
+ }
+
+ for (j = 0; j < n; j++)
+ {
+ int k;
+ char *s = PQgetvalue(self->last_result, i, j);
+ char cashbuf[64];
+ PyObject *tmp_obj;
+
+ if (PQgetisnull(self->last_result, i, j))
+ {
+ Py_INCREF(Py_None);
+ val = Py_None;
+ }
+ else
+ switch (typ[j])
+ {
+ case 1:
+ val = PyInt_FromString(s, NULL, 10);
+ break;
+
+ case 2:
+ val = PyLong_FromString(s, NULL, 10);
+ break;
+
+ case 3:
+ tmp_obj = PyString_FromString(s);
+ val = PyFloat_FromString(tmp_obj, NULL);
+ Py_DECREF(tmp_obj);
+ break;
+
+ case 5:
+ for (k = 0;
+ *s && k < sizeof(cashbuf) / sizeof(cashbuf[0]) - 1;
+ s++)
+ {
+ if (isdigit(*s) || *s == '.')
+ cashbuf[k++] = *s;
+ else if (*s == '(' || *s == '-')
+ cashbuf[k++] = '-';
+ }
+ cashbuf[k] = 0;
+ s = cashbuf;
+
+ case 4:
+ if (decimal)
+ {
+ tmp_obj = Py_BuildValue("(s)", s);
+ val = PyEval_CallObject(decimal, tmp_obj);
+ }
+ else
+ {
+ tmp_obj = PyString_FromString(s);
+ val = PyFloat_FromString(tmp_obj, NULL);
+ }
+ Py_DECREF(tmp_obj);
+ break;
+
+ default:
+ val = PyString_FromString(s);
+ break;
+ }
+
+ if (val == NULL)
+ {
+ Py_DECREF(reslist);
+ Py_DECREF(rowtuple);
+ reslist = NULL;
+ goto exit;
+ }
+
+ PyTuple_SET_ITEM(rowtuple, j, val);
+ }
+
+ PyList_SET_ITEM(reslist, i, rowtuple);
+ }
+
+exit:
+ free(typ);
+
+ /* returns list */
+ return reslist;
+}
+
+/* retrieves last result as a list of dictionaries*/
+static char pgquery_dictresult__doc__[] =
+"dictresult() -- Gets the result of a query. The result is returned "
+"as a list of rows, each one a dictionary with the field names used "
+"as the labels.";
+
+static PyObject *
+pgquery_dictresult(pgqueryobject * self, PyObject * args)
+{
+ PyObject *dict,
+ *reslist,
+ *val;
+ int i,
+ j,
+ m,
+ n,
+ *typ;
+
+ /* checks args (args == NULL for an internal call) */
+ if ((args != NULL) && (!PyArg_ParseTuple(args, "")))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method getresult() takes no parameters.");
+ return NULL;
+ }
+
+ /* stores result in list */
+ m = PQntuples(self->last_result);
+ n = PQnfields(self->last_result);
+ reslist = PyList_New(m);
+
+ typ = get_type_array(self->last_result, n);
+
+ for (i = 0; i < m; i++)
+ {
+ if ((dict = PyDict_New()) == NULL)
+ {
+ Py_DECREF(reslist);
+ reslist = NULL;
+ goto exit;
+ }
+
+ for (j = 0; j < n; j++)
+ {
+ int k;
+ char *s = PQgetvalue(self->last_result, i, j);
+ char cashbuf[64];
+ PyObject *tmp_obj;
+
+ if (PQgetisnull(self->last_result, i, j))
+ {
+ Py_INCREF(Py_None);
+ val = Py_None;
+ }
+ else
+ switch (typ[j])
+ {
+ case 1:
+ val = PyInt_FromString(s, NULL, 10);
+ break;
+
+ case 2:
+ val = PyLong_FromString(s, NULL, 10);
+ break;
+
+ case 3:
+ tmp_obj = PyString_FromString(s);
+ val = PyFloat_FromString(tmp_obj, NULL);
+ Py_DECREF(tmp_obj);
+ break;
+
+ case 5:
+ for (k = 0;
+ *s && k < sizeof(cashbuf) / sizeof(cashbuf[0]) - 1;
+ s++)
+ {
+ if (isdigit(*s) || *s == '.')
+ cashbuf[k++] = *s;
+ else if (*s == '(' || *s == '-')
+ cashbuf[k++] = '-';
+ }
+ cashbuf[k] = 0;
+ s = cashbuf;
+
+ case 4:
+ if (decimal)
+ {
+ tmp_obj = Py_BuildValue("(s)", s);
+ val = PyEval_CallObject(decimal, tmp_obj);
+ }
+ else
+ {
+ tmp_obj = PyString_FromString(s);
+ val = PyFloat_FromString(tmp_obj, NULL);
+ }
+ Py_DECREF(tmp_obj);
+ break;
+
+ default:
+ val = PyString_FromString(s);
+ break;
+ }
+
+ if (val == NULL)
+ {
+ Py_DECREF(dict);
+ Py_DECREF(reslist);
+ reslist = NULL;
+ goto exit;
+ }
+
+ PyDict_SetItemString(dict, PQfname(self->last_result, j), val);
+ Py_DECREF(val);
+ }
+
+ PyList_SET_ITEM(reslist, i, dict);
+ }
+
+exit:
+ free(typ);
+
+ /* returns list */
+ return reslist;
+}
+
+/* gets asynchronous notify */
+static char pg_getnotify__doc__[] =
+"getnotify() -- get database notify for this connection.";
+
+static PyObject *
+pg_getnotify(pgobject * self, PyObject * args)
+{
+ PGnotify *notify;
+
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method getnotify() takes no parameters.");
+ return NULL;
+ }
+
+ /* checks for NOTIFY messages */
+ PQconsumeInput(self->cnx);
+
+ if ((notify = PQnotifies(self->cnx)) == NULL)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ else
+ {
+ PyObject *notify_result,
+ *temp;
+
+ if ((notify_result = PyTuple_New(2)) == NULL ||
+ (temp = PyString_FromString(notify->relname)) == NULL)
+ {
+ return NULL;
+ }
+
+ PyTuple_SET_ITEM(notify_result, 0, temp);
+
+ if ((temp = PyInt_FromLong(notify->be_pid)) == NULL)
+ {
+ Py_DECREF(notify_result);
+ return NULL;
+ }
+
+ PyTuple_SET_ITEM(notify_result, 1, temp);
+ PQfreemem(notify);
+ return notify_result;
+ }
+}
+
+/* source creation */
+static char pg_source__doc__[] =
+"source() -- creates a new source object for this connection";
+
+static PyObject *
+pg_source(pgobject * self, PyObject * args)
+{
+ /* checks validity */
+ if (!check_cnx_obj(self))
+ return NULL;
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError, "method source() takes no parameter.");
+ return NULL;
+ }
+
+ /* allocate new pg query object */
+ return (PyObject *) pgsource_new(self);
+}
+
+/* database query */
+static char pg_query__doc__[] =
+"query(sql) -- creates a new query object for this connection,"
+" using sql (string) request.";
+
+static PyObject *
+pg_query(pgobject * self, PyObject * args)
+{
+ char *query;
+ PGresult *result;
+ pgqueryobject *npgobj;
+ int status;
+
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* get query args */
+ if (!PyArg_ParseTuple(args, "s", &query))
+ {
+ PyErr_SetString(PyExc_TypeError, "query(sql), with sql (string).");
+ return NULL;
+ }
+
+ /* frees previous result */
+ if (self->last_result)
+ {
+ PQclear(self->last_result);
+ self->last_result = NULL;
+ }
+
+ /* gets result */
+ Py_BEGIN_ALLOW_THREADS
+ result = PQexec(self->cnx, query);
+ Py_END_ALLOW_THREADS
+
+ /* checks result validity */
+ if (!result)
+ {
+ PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
+ return NULL;
+ }
+
+ /* checks result status */
+ if ((status = PQresultStatus(result)) != PGRES_TUPLES_OK)
+ {
+ switch (status)
+ {
+ case PGRES_EMPTY_QUERY:
+ PyErr_SetString(PyExc_ValueError, "empty query.");
+ break;
+ case PGRES_BAD_RESPONSE:
+ case PGRES_FATAL_ERROR:
+ case PGRES_NONFATAL_ERROR:
+ PyErr_SetString(ProgrammingError, PQerrorMessage(self->cnx));
+ break;
+ case PGRES_COMMAND_OK:
+ { /* INSERT, UPDATE, DELETE */
+ Oid oid = PQoidValue(result);
+ if (oid == InvalidOid) /* not a single insert */
+ {
+ char *ret = PQcmdTuples(result);
+
+ PQclear(result);
+ if (ret[0]) /* return number of rows affected */
+ {
+ return PyString_FromString(ret);
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ /* for a single insert, return the oid */
+ PQclear(result);
+ return PyInt_FromLong(oid);
+ }
+ case PGRES_COPY_OUT: /* no data will be received */
+ case PGRES_COPY_IN:
+ PQclear(result);
+ Py_INCREF(Py_None);
+ return Py_None;
+ default:
+ PyErr_SetString(InternalError, "internal error: "
+ "unknown result status.");
+ break;
+ }
+
+ PQclear(result);
+ return NULL; /* error detected on query */
+ }
+
+ if ((npgobj = PyObject_NEW(pgqueryobject, &PgQueryType)) == NULL)
+ return NULL;
+
+ /* stores result and returns object */
+ npgobj->last_result = result;
+ return (PyObject *) npgobj;
+}
+
+#ifdef DIRECT_ACCESS
+static char pg_putline__doc__[] =
+"putline() -- sends a line directly to the backend";
+
+/* direct acces function : putline */
+static PyObject *
+pg_putline(pgobject * self, PyObject * args)
+{
+ char *line;
+
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* reads args */
+ if (!PyArg_ParseTuple(args, "s", &line))
+ {
+ PyErr_SetString(PyExc_TypeError, "putline(line), with line (string).");
+ return NULL;
+ }
+
+ /* sends line to backend */
+ if (PQputline(self->cnx, line))
+ {
+ PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* direct access function : getline */
+static char pg_getline__doc__[] =
+"getline() -- gets a line directly from the backend.";
+
+static PyObject *
+pg_getline(pgobject * self, PyObject * args)
+{
+ char line[MAX_BUFFER_SIZE];
+ PyObject *str = NULL; /* GCC */
+
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method getline() takes no parameters.");
+ return NULL;
+ }
+
+ /* gets line */
+ switch (PQgetline(self->cnx, line, MAX_BUFFER_SIZE))
+ {
+ case 0:
+ str = PyString_FromString(line);
+ break;
+ case 1:
+ PyErr_SetString(PyExc_MemoryError, "buffer overflow");
+ str = NULL;
+ break;
+ case EOF:
+ Py_INCREF(Py_None);
+ str = Py_None;
+ break;
+ }
+
+ return str;
+}
+
+/* direct access function : end copy */
+static char pg_endcopy__doc__[] =
+"endcopy() -- synchronizes client and server";
+
+static PyObject *
+pg_endcopy(pgobject * self, PyObject * args)
+{
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method endcopy() takes no parameters.");
+ return NULL;
+ }
+
+ /* ends direct copy */
+ if (PQendcopy(self->cnx))
+ {
+ PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+#endif /* DIRECT_ACCESS */
+
+
+static PyObject *
+pgquery_print(pgqueryobject * self, FILE *fp, int flags)
+{
+ print_result(fp, self->last_result);
+ return 0;
+}
+
+static PyObject *
+pgquery_repr(pgqueryobject * self)
+{
+ return PyString_FromString("<pg query result>");
+}
+
+/* insert table */
+static char pg_inserttable__doc__[] =
+"inserttable(string, list) -- insert list in table. The fields in the "
+"list must be in the same order as in the table.";
+
+static PyObject *
+pg_inserttable(pgobject * self, PyObject * args)
+{
+ PGresult *result;
+ char *table,
+ *buffer,
+ *bufpt;
+ size_t bufsiz;
+ PyObject *list,
+ *sublist,
+ *item;
+ PyObject *(*getitem) (PyObject *, Py_ssize_t);
+ PyObject *(*getsubitem) (PyObject *, Py_ssize_t);
+ int i,
+ j,
+ m,
+ n;
+
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "sO:filter", &table, &list))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "inserttable(table, content), with table (string) "
+ "and content (list).");
+ return NULL;
+ }
+
+ /* checks list type */
+ if (PyTuple_Check(list))
+ {
+ m = PyTuple_Size(list);
+ getitem = PyTuple_GetItem;
+ }
+ else if (PyList_Check(list))
+ {
+ m = PyList_Size(list);
+ getitem = PyList_GetItem;
+ }
+ else
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "second arg must be some kind of array.");
+ return NULL;
+ }
+
+ /* allocate buffer */
+ if (!(buffer = malloc(MAX_BUFFER_SIZE)))
+ {
+ PyErr_SetString(PyExc_MemoryError,
+ "can't allocate insert buffer.");
+ return NULL;
+ }
+
+ /* starts query */
+ sprintf(buffer, "copy %s from stdin", table);
+
+ Py_BEGIN_ALLOW_THREADS
+ result = PQexec(self->cnx, buffer);
+ Py_END_ALLOW_THREADS
+
+ if (!result)
+ {
+ free(buffer);
+ PyErr_SetString(PyExc_ValueError, PQerrorMessage(self->cnx));
+ return NULL;
+ }
+
+ PQclear(result);
+
+ n = 0; /* not strictly necessary but avoids warning */
+
+ /* feed table */
+ for (i = 0; i < m; i++)
+ {
+ sublist = getitem(list, i);
+ if (PyTuple_Check(sublist))
+ {
+ j = PyTuple_Size(sublist);
+ getsubitem = PyTuple_GetItem;
+ }
+ else if (PyList_Check(sublist))
+ {
+ j = PyList_Size(sublist);
+ getsubitem = PyList_GetItem;
+ }
+ else
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "second arg must contain some kind of arrays.");
+ return NULL;
+ }
+ if (i)
+ {
+ if (j != n)
+ {
+ free(buffer);
+ PyErr_SetString(PyExc_TypeError,
+ "arrays contained in second arg must have same size.");
+ return NULL;
+ }
+ }
+ else
+ {
+ n = j; /* never used before this assignment */
+ }
+
+ /* builds insert line */
+ bufpt = buffer;
+ bufsiz = MAX_BUFFER_SIZE - 1;
+
+ for (j = 0; j < n; j++)
+ {
+ if (j)
+ {
+ *bufpt++ = '\t'; --bufsiz;
+ }
+
+ item = getsubitem(sublist, j);
+
+ /* convert item to string and append to buffer */
+ if (item == Py_None)
+ {
+ if (bufsiz > 2)
+ {
+ *bufpt++ = '\\'; *bufpt++ = 'N';
+ bufsiz -= 2;
+ }
+ else
+ bufsiz = 0;
+ }
+ else if (PyString_Check(item))
+ {
+ const char* t = PyString_AS_STRING(item);
+ while (*t && bufsiz)
+ {
+ if (*t == '\\' || *t == '\t' || *t == '\n')
+ {
+ *bufpt++ = '\\'; --bufsiz;
+ if (!bufsiz) break;
+ }
+ *bufpt++ = *t++; --bufsiz;
+ }
+ }
+ else if (PyInt_Check(item) || PyLong_Check(item))
+ {
+ PyObject* s = PyObject_Str(item);
+ const char* t = PyString_AsString(s);
+ while (*t && bufsiz)
+ {
+ *bufpt++ = *t++; --bufsiz;
+ }
+ Py_DECREF(s);
+ }
+ else
+ {
+ PyObject* s = PyObject_Repr(item);
+ const char* t = PyString_AsString(s);
+ while (*t && bufsiz)
+ {
+ if (*t == '\\' || *t == '\t' || *t == '\n')
+ {
+ *bufpt++ = '\\'; --bufsiz;
+ if (!bufsiz) break;
+ }
+ *bufpt++ = *t++; --bufsiz;
+ }
+ Py_DECREF(s);
+ }
+
+ if (bufsiz <= 0)
+ {
+ free(buffer);
+ PyErr_SetString(PyExc_MemoryError,
+ "insert buffer overflow.");
+ return NULL;
+ }
+
+ }
+
+ *bufpt++ = '\n'; *bufpt = '\0';
+
+ /* sends data */
+ if (PQputline(self->cnx, buffer))
+ {
+ PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
+ PQendcopy(self->cnx);
+ free(buffer);
+ return NULL;
+ }
+ }
+
+ /* ends query */
+ if (PQputline(self->cnx, "\\.\n"))
+ {
+ PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
+ PQendcopy(self->cnx);
+ free(buffer);
+ return NULL;
+ }
+
+ if (PQendcopy(self->cnx))
+ {
+ PyErr_SetString(PyExc_IOError, PQerrorMessage(self->cnx));
+ free(buffer);
+ return NULL;
+ }
+
+ free(buffer);
+
+ /* no error : returns nothing */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* get transaction state */
+static char pg_transaction__doc__[] =
+"Returns the current transaction status.";
+
+static PyObject *
+pg_transaction(pgobject * self, PyObject * args)
+{
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method transaction() takes no parameters.");
+ return NULL;
+ }
+
+ return PyInt_FromLong(PQtransactionStatus(self->cnx));
+}
+
+/* get parameter setting */
+static char pg_parameter__doc__[] =
+"Looks up a current parameter setting.";
+
+static PyObject *
+pg_parameter(pgobject * self, PyObject * args)
+{
+ const char *name;
+
+ if (!self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* get query args */
+ if (!PyArg_ParseTuple(args, "s", &name))
+ {
+ PyErr_SetString(PyExc_TypeError, "parameter(name), with name (string).");
+ return NULL;
+ }
+
+ name = PQparameterStatus(self->cnx, name);
+
+ if (name)
+ return PyString_FromString(name);
+
+ /* unknown parameter, return None */
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* escape string */
+static char pg_escape_string__doc__[] =
+"pg_escape_string(str) -- escape a string for use within SQL.";
+
+static PyObject *
+pg_escape_string(pgobject *self, PyObject *args) {
+ char *from; /* our string argument */
+ char *to=NULL; /* the result */
+ int from_length; /* length of string */
+ int to_length; /* length of result */
+ PyObject *ret; /* string object to return */
+
+ if (!PyArg_ParseTuple(args, "s#", &from, &from_length))
+ return NULL;
+ to_length = 2*from_length + 1;
+ if (to_length < from_length) { /* overflow */
+ to_length = from_length;
+ from_length = (from_length - 1)/2;
+ }
+ to = (char *)malloc(to_length);
+ to_length = (int)PQescapeStringConn(self->cnx,
+ to, from, (size_t)from_length, NULL);
+ ret = Py_BuildValue("s#", to, to_length);
+ if (to)
+ free(to);
+ if (!ret) /* pass on exception */
+ return NULL;
+ return ret;
+}
+
+/* escape bytea */
+static char pg_escape_bytea__doc__[] =
+"pg_escape_bytea(data) -- escape binary data for use within SQL as type bytea.";
+
+static PyObject *
+pg_escape_bytea(pgobject *self, PyObject *args) {
+ unsigned char *from; /* our string argument */
+ unsigned char *to; /* the result */
+ int from_length; /* length of string */
+ size_t to_length; /* length of result */
+ PyObject *ret; /* string object to return */
+
+ if (!PyArg_ParseTuple(args, "s#", &from, &from_length))
+ return NULL;
+ to = PQescapeByteaConn(self->cnx, from, (int)from_length, &to_length);
+ ret = Py_BuildValue("s", to);
+ if (to)
+ PQfreemem((void *)to);
+ if (!ret) /* pass on exception */
+ return NULL;
+ return ret;
+}
+
+#ifdef LARGE_OBJECTS
+/* creates large object */
+static char pg_locreate__doc__[] =
+"locreate() -- creates a new large object in the database.";
+
+static PyObject *
+pg_locreate(pgobject * self, PyObject * args)
+{
+ int mode;
+ Oid lo_oid;
+
+ /* checks validity */
+ if (!check_cnx_obj(self))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "i", &mode))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "locreate(mode), with mode (integer).");
+ return NULL;
+ }
+
+ /* creates large object */
+ lo_oid = lo_creat(self->cnx, mode);
+ if (lo_oid == 0)
+ {
+ PyErr_SetString(OperationalError, "can't create large object.");
+ return NULL;
+ }
+
+ return (PyObject *) pglarge_new(self, lo_oid);
+}
+
+/* init from already known oid */
+static char pg_getlo__doc__[] =
+"getlo(long) -- create a large object instance for the specified oid.";
+
+static PyObject *
+pg_getlo(pgobject * self, PyObject * args)
+{
+ int lo_oid;
+
+ /* checks validity */
+ if (!check_cnx_obj(self))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "i", &lo_oid))
+ {
+ PyErr_SetString(PyExc_TypeError, "getlo(oid), with oid (integer).");
+ return NULL;
+ }
+
+ if (!lo_oid)
+ {
+ PyErr_SetString(PyExc_ValueError, "the object oid can't be null.");
+ return NULL;
+ }
+
+ /* creates object */
+ return (PyObject *) pglarge_new(self, lo_oid);
+}
+
+/* import unix file */
+static char pg_loimport__doc__[] =
+"loimport(string) -- create a new large object from specified file.";
+
+static PyObject *
+pg_loimport(pgobject * self, PyObject * args)
+{
+ char *name;
+ Oid lo_oid;
+
+ /* checks validity */
+ if (!check_cnx_obj(self))
+ return NULL;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "s", &name))
+ {
+ PyErr_SetString(PyExc_TypeError, "loimport(name), with name (string).");
+ return NULL;
+ }
+
+ /* imports file and checks result */
+ lo_oid = lo_import(self->cnx, name);
+ if (lo_oid == 0)
+ {
+ PyErr_SetString(OperationalError, "can't create large object.");
+ return NULL;
+ }
+
+ return (PyObject *) pglarge_new(self, lo_oid);
+}
+#endif /* LARGE_OBJECTS */
+
+#ifdef HANDLE_NOTICES
+
+/* fetch accumulated backend notices */
+static char pg_notices__doc__[] =
+ "notices() -- returns and clears the list of currently accumulated backend notices for the connection.";
+
+static void
+notice_processor(void * arg, const char * message)
+{
+
+ pgobject *pgobj = (pgobject *)arg;
+
+ /* skip if memory allocation failed */
+ if (pgobj->notices == NULL)
+ {
+ return;
+ }
+
+ pgobj->notices[pgobj->notices_next] = strdup(message);
+ pgobj->notices_next = (pgobj->notices_next + 1) % MAX_BUFFERED_NOTICES;
+ if (pgobj->notices_next == pgobj->notices_first)
+ {
+ free(pgobj->notices[pgobj->notices_first]);
+ pgobj->notices_first = (pgobj->notices_first + 1) % MAX_BUFFERED_NOTICES;
+ }
+
+ }
+
+static PyObject *
+ pg_notices(pgobject * self, PyObject * args)
+ {
+
+ PyObject *reslist,
+ *str;
+ int i;
+
+ /* allocate list for result */
+ if ((reslist = PyList_New(0)) == NULL)
+ return NULL;
+
+ /* skip if memory allocation failed */
+ if (self->notices == NULL)
+ {
+ return reslist;
+ }
+
+ /* builds result */
+ while (self->notices_first != self->notices_next)
+ {
+
+ if (self->notices[self->notices_first] != NULL) /* skip if memory allocation failed */
+ {
+
+ str = PyString_FromString(self->notices[self->notices_first]);
+ PyList_Append(reslist, str);
+ Py_DECREF(str);
+
+ free(self->notices[self->notices_first]);
+
+ }
+
+ self->notices_first = (self->notices_first + 1) % MAX_BUFFERED_NOTICES;
+
+ }
+
+ return reslist;
+
+ }
+
+#endif /* HANDLE_NOTICES */
+
+/* connection object methods */
+static struct PyMethodDef pgobj_methods[] = {
+ {"source", (PyCFunction) pg_source, METH_VARARGS, pg_source__doc__},
+ {"query", (PyCFunction) pg_query, METH_VARARGS, pg_query__doc__},
+ {"reset", (PyCFunction) pg_reset, METH_VARARGS, pg_reset__doc__},
+ {"cancel", (PyCFunction) pg_cancel, METH_VARARGS, pg_cancel__doc__},
+ {"close", (PyCFunction) pg_close, METH_VARARGS, pg_close__doc__},
+ {"fileno", (PyCFunction) pg_fileno, METH_VARARGS, pg_fileno__doc__},
+ {"getnotify", (PyCFunction) pg_getnotify, METH_VARARGS,
+ pg_getnotify__doc__},
+ {"inserttable", (PyCFunction) pg_inserttable, METH_VARARGS,
+ pg_inserttable__doc__},
+ {"transaction", (PyCFunction) pg_transaction, METH_VARARGS,
+ pg_transaction__doc__},
+ {"parameter", (PyCFunction) pg_parameter, METH_VARARGS,
+ pg_parameter__doc__},
+ {"escape_string", (PyCFunction) pg_escape_string, METH_VARARGS,
+ pg_escape_string__doc__},
+ {"escape_bytea", (PyCFunction) pg_escape_bytea, METH_VARARGS,
+ pg_escape_bytea__doc__},
+
+#ifdef DIRECT_ACCESS
+ {"putline", (PyCFunction) pg_putline, 1, pg_putline__doc__},
+ {"getline", (PyCFunction) pg_getline, 1, pg_getline__doc__},
+ {"endcopy", (PyCFunction) pg_endcopy, 1, pg_endcopy__doc__},
+#endif /* DIRECT_ACCESS */
+
+#ifdef LARGE_OBJECTS
+ {"locreate", (PyCFunction) pg_locreate, 1, pg_locreate__doc__},
+ {"getlo", (PyCFunction) pg_getlo, 1, pg_getlo__doc__},
+ {"loimport", (PyCFunction) pg_loimport, 1, pg_loimport__doc__},
+#endif /* LARGE_OBJECTS */
+
+#ifdef HANDLE_NOTICES
+ {"notices", (PyCFunction) pg_notices, 1, pg_notices__doc__},
+#endif /* HANDLE_NOTICES */
+
+ {NULL, NULL} /* sentinel */
+};
+
+/* get attribute */
+static PyObject *
+pg_getattr(pgobject * self, char *name)
+{
+ /*
+ * Although we could check individually, there are only a few
+ * attributes that don't require a live connection and unless someone
+ * has an urgent need, this will have to do
+ */
+
+ /* first exception - close which returns a different error */
+ if (strcmp(name, "close") && !self->cnx)
+ {
+ PyErr_SetString(PyExc_TypeError, "Connection is not valid.");
+ return NULL;
+ }
+
+ /* list postgreSQL connection fields */
+
+ /* postmaster host */
+ if (!strcmp(name, "host"))
+ {
+ char *r = PQhost(self->cnx);
+
+ return r ? PyString_FromString(r) : PyString_FromString("localhost");
+ }
+
+ /* postmaster port */
+ if (!strcmp(name, "port"))
+ return PyInt_FromLong(atol(PQport(self->cnx)));
+
+ /* selected database */
+ if (!strcmp(name, "db"))
+ return PyString_FromString(PQdb(self->cnx));
+
+ /* selected options */
+ if (!strcmp(name, "options"))
+ return PyString_FromString(PQoptions(self->cnx));
+
+ /* selected postgres tty */
+ if (!strcmp(name, "tty"))
+ return PyString_FromString(PQtty(self->cnx));
+
+ /* error (status) message */
+ if (!strcmp(name, "error"))
+ return PyString_FromString(PQerrorMessage(self->cnx));
+
+ /* connection status : 1 - OK, 0 - BAD */
+ if (!strcmp(name, "status"))
+ return PyInt_FromLong(PQstatus(self->cnx) == CONNECTION_OK ? 1 : 0);
+
+ /* provided user name */
+ if (!strcmp(name, "user"))
+ return PyString_FromString(PQuser(self->cnx));
+
+ /* protocol version */
+ if (!strcmp(name, "protocol_version"))
+ return PyInt_FromLong(PQprotocolVersion(self->cnx));
+
+ /* backend version */
+ if (!strcmp(name, "server_version"))
+#if PG_VERSION_NUM < 80000
+ return PyInt_FromLong(PG_VERSION_NUM);
+#else
+ return PyInt_FromLong(PQserverVersion(self->cnx));
+#endif
+
+ /* attributes list */
+ if (!strcmp(name, "__members__"))
+ {
+ PyObject *list = PyList_New(10);
+
+ if (list)
+ {
+ PyList_SET_ITEM(list, 0, PyString_FromString("host"));
+ PyList_SET_ITEM(list, 1, PyString_FromString("port"));
+ PyList_SET_ITEM(list, 2, PyString_FromString("db"));
+ PyList_SET_ITEM(list, 3, PyString_FromString("options"));
+ PyList_SET_ITEM(list, 4, PyString_FromString("tty"));
+ PyList_SET_ITEM(list, 5, PyString_FromString("error"));
+ PyList_SET_ITEM(list, 6, PyString_FromString("status"));
+ PyList_SET_ITEM(list, 7, PyString_FromString("user"));
+ PyList_SET_ITEM(list, 8, PyString_FromString("protocol_version"));
+ PyList_SET_ITEM(list, 9, PyString_FromString("server_version"));
+ }
+
+ return list;
+ }
+
+ return Py_FindMethod(pgobj_methods, (PyObject *) self, name);
+}
+
+/* object type definition */
+staticforward PyTypeObject PgType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "pgobject", /* tp_name */
+ sizeof(pgobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor) pg_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc) pg_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+};
+
+
+/* query object methods */
+static struct PyMethodDef pgquery_methods[] = {
+ {"getresult", (PyCFunction) pgquery_getresult, METH_VARARGS,
+ pgquery_getresult__doc__},
+ {"dictresult", (PyCFunction) pgquery_dictresult, METH_VARARGS,
+ pgquery_dictresult__doc__},
+ {"fieldname", (PyCFunction) pgquery_fieldname, METH_VARARGS,
+ pgquery_fieldname__doc__},
+ {"fieldnum", (PyCFunction) pgquery_fieldnum, METH_VARARGS,
+ pgquery_fieldnum__doc__},
+ {"listfields", (PyCFunction) pgquery_listfields, METH_VARARGS,
+ pgquery_listfields__doc__},
+ {"ntuples", (PyCFunction) pgquery_ntuples, METH_VARARGS,
+ pgquery_ntuples__doc__},
+ {NULL, NULL}
+};
+
+/* gets query object attributes */
+static PyObject *
+pgquery_getattr(pgqueryobject * self, char *name)
+{
+ /* list postgreSQL connection fields */
+ return Py_FindMethod(pgquery_methods, (PyObject *) self, name);
+}
+
+/* query type definition */
+staticforward PyTypeObject PgQueryType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ "pgqueryobject", /* tp_name */
+ sizeof(pgqueryobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor) pgquery_dealloc, /* tp_dealloc */
+ (printfunc) pgquery_print, /* tp_print */
+ (getattrfunc) pgquery_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ (reprfunc) pgquery_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+};
+
+
+/* --------------------------------------------------------------------- */
+
+/* MODULE FUNCTIONS */
+
+/* escape string */
+static char escape_string__doc__[] =
+"escape_string(str) -- escape a string for use within SQL.";
+
+static PyObject *
+escape_string(PyObject *self, PyObject *args) {
+ char *from; /* our string argument */
+ char *to=NULL; /* the result */
+ int from_length; /* length of string */
+ int to_length; /* length of result */
+ PyObject *ret; /* string object to return */
+
+ if (!PyArg_ParseTuple(args, "s#", &from, &from_length))
+ return NULL;
+ to_length = 2*from_length + 1;
+ if (to_length < from_length) { /* overflow */
+ to_length = from_length;
+ from_length = (from_length - 1)/2;
+ }
+ to = (char *)malloc(to_length);
+ to_length = (int)PQescapeString(to, from, (size_t)from_length);
+ ret = Py_BuildValue("s#", to, to_length);
+ if (to)
+ free(to);
+ if (!ret) /* pass on exception */
+ return NULL;
+ return ret;
+}
+
+/* escape bytea */
+static char escape_bytea__doc__[] =
+"escape_bytea(data) -- escape binary data for use within SQL as type bytea.";
+
+static PyObject *
+escape_bytea(PyObject *self, PyObject *args) {
+ unsigned char *from; /* our string argument */
+ unsigned char *to; /* the result */
+ int from_length; /* length of string */
+ size_t to_length; /* length of result */
+ PyObject *ret; /* string object to return */
+
+ if (!PyArg_ParseTuple(args, "s#", &from, &from_length))
+ return NULL;
+ to = PQescapeBytea(from, (int)from_length, &to_length);
+ ret = Py_BuildValue("s", to);
+ if (to)
+ PQfreemem((void *)to);
+ if (!ret) /* pass on exception */
+ return NULL;
+ return ret;
+}
+
+/* unescape bytea */
+static char unescape_bytea__doc__[] =
+"unescape_bytea(str) -- unescape bytea data that has been retrieved as text.";
+
+static PyObject
+*unescape_bytea(PyObject *self, PyObject *args) {
+ unsigned char *from; /* our string argument */
+ unsigned char *to; /* the result */
+ size_t to_length; /* length of result string */
+ PyObject *ret; /* string object to return */
+
+ if (!PyArg_ParseTuple(args, "s", &from))
+ return NULL;
+ to = PQunescapeBytea(from, &to_length);
+ ret = Py_BuildValue("s#", to, (int)to_length);
+ if (to)
+ PQfreemem((void *)to);
+ if (!ret) /* pass on exception */
+ return NULL;
+ return ret;
+}
+
+/* set decimal */
+static char set_decimal__doc__[] =
+"set_decimal(cls) -- set a decimal type to be used for numeric values.";
+
+static PyObject *
+set_decimal(PyObject * self, PyObject * args)
+{
+ PyObject *ret = NULL;
+ PyObject *cls;
+
+ if (PyArg_ParseTuple(args, "O", &cls))
+ {
+ if (cls == Py_None)
+ {
+ Py_XDECREF(decimal); decimal = NULL;
+ Py_INCREF(Py_None); ret = Py_None;
+ }
+ else if (PyCallable_Check(cls))
+ {
+ Py_XINCREF(cls); Py_XDECREF(decimal); decimal = cls;
+ Py_INCREF(Py_None); ret = Py_None;
+ }
+ else
+ PyErr_SetString(PyExc_TypeError, "decimal type must be None or callable");
+ }
+ return ret;
+}
+
+#ifdef DEFAULT_VARS
+
+/* gets default host */
+static char getdefhost__doc__[] =
+"get_defhost() -- return default database host.";
+
+static PyObject *
+pggetdefhost(PyObject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method get_defhost() takes no parameter.");
+ return NULL;
+ }
+
+ Py_XINCREF(pg_default_host);
+ return pg_default_host;
+}
+
+/* sets default host */
+static char setdefhost__doc__[] =
+"set_defhost(string) -- set default database host. Return previous value.";
+
+static PyObject *
+pgsetdefhost(PyObject * self, PyObject * args)
+{
+ char *temp = NULL;
+ PyObject *old;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "z", &temp))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "set_defhost(name), with name (string/None).");
+ return NULL;
+ }
+
+ /* adjusts value */
+ old = pg_default_host;
+
+ if (temp)
+ pg_default_host = PyString_FromString(temp);
+ else
+ {
+ Py_INCREF(Py_None);
+ pg_default_host = Py_None;
+ }
+
+ return old;
+}
+
+/* gets default base */
+static char getdefbase__doc__[] =
+"get_defbase() -- return default database name.";
+
+static PyObject *
+pggetdefbase(PyObject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method get_defbase() takes no parameter.");
+ return NULL;
+ }
+
+ Py_XINCREF(pg_default_base);
+ return pg_default_base;
+}
+
+/* sets default base */
+static char setdefbase__doc__[] =
+"set_defbase(string) -- set default database name. Return previous value";
+
+static PyObject *
+pgsetdefbase(PyObject * self, PyObject * args)
+{
+ char *temp = NULL;
+ PyObject *old;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "z", &temp))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "set_defbase(name), with name (string/None).");
+ return NULL;
+ }
+
+ /* adjusts value */
+ old = pg_default_base;
+
+ if (temp)
+ pg_default_base = PyString_FromString(temp);
+ else
+ {
+ Py_INCREF(Py_None);
+ pg_default_base = Py_None;
+ }
+
+ return old;
+}
+
+/* gets default options */
+static char getdefopt__doc__[] =
+"get_defopt() -- return default database options.";
+
+static PyObject *
+pggetdefopt(PyObject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method get_defopt() takes no parameter.");
+ return NULL;
+ }
+
+ Py_XINCREF(pg_default_opt);
+ return pg_default_opt;
+}
+
+/* sets default opt */
+static char setdefopt__doc__[] =
+"set_defopt(string) -- set default database options. Return previous value.";
+
+static PyObject *
+pgsetdefopt(PyObject * self, PyObject * args)
+{
+ char *temp = NULL;
+ PyObject *old;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "z", &temp))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "set_defopt(name), with name (string/None).");
+ return NULL;
+ }
+
+ /* adjusts value */
+ old = pg_default_opt;
+
+ if (temp)
+ pg_default_opt = PyString_FromString(temp);
+ else
+ {
+ Py_INCREF(Py_None);
+ pg_default_opt = Py_None;
+ }
+
+ return old;
+}
+
+/* gets default tty */
+static char getdeftty__doc__[] =
+"get_deftty() -- return default database debug terminal.";
+
+static PyObject *
+pggetdeftty(PyObject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method get_deftty() takes no parameter.");
+ return NULL;
+ }
+
+ Py_XINCREF(pg_default_tty);
+ return pg_default_tty;
+}
+
+/* sets default tty */
+static char setdeftty__doc__[] =
+"set_deftty(string) -- set default database debug terminal. "
+"Return previous value.";
+
+static PyObject *
+pgsetdeftty(PyObject * self, PyObject * args)
+{
+ char *temp = NULL;
+ PyObject *old;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "z", &temp))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "set_deftty(name), with name (string/None).");
+ return NULL;
+ }
+
+ /* adjusts value */
+ old = pg_default_tty;
+
+ if (temp)
+ pg_default_tty = PyString_FromString(temp);
+ else
+ {
+ Py_INCREF(Py_None);
+ pg_default_tty = Py_None;
+ }
+
+ return old;
+}
+
+/* gets default username */
+static char getdefuser__doc__[] =
+"get_defuser() -- return default database username.";
+
+static PyObject *
+pggetdefuser(PyObject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method get_defuser() takes no parameter.");
+
+ return NULL;
+ }
+
+ Py_XINCREF(pg_default_user);
+ return pg_default_user;
+}
+
+/* sets default username */
+static char setdefuser__doc__[] =
+"set_defuser() -- set default database username. Return previous value.";
+
+static PyObject *
+pgsetdefuser(PyObject * self, PyObject * args)
+{
+ char *temp = NULL;
+ PyObject *old;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "z", &temp))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "set_defuser(name), with name (string/None).");
+ return NULL;
+ }
+
+ /* adjusts value */
+ old = pg_default_user;
+
+ if (temp)
+ pg_default_user = PyString_FromString(temp);
+ else
+ {
+ Py_INCREF(Py_None);
+ pg_default_user = Py_None;
+ }
+
+ return old;
+}
+
+/* sets default password */
+static char setdefpasswd__doc__[] =
+"set_defpasswd() -- set default database password.";
+
+static PyObject *
+pgsetdefpasswd(PyObject * self, PyObject * args)
+{
+ char *temp = NULL;
+ PyObject *old;
+
+ /* gets arguments */
+ if (!PyArg_ParseTuple(args, "z", &temp))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "set_defpasswd(password), with password (string/None).");
+ return NULL;
+ }
+
+ /* adjusts value */
+ old = pg_default_passwd;
+
+ if (temp)
+ pg_default_passwd = PyString_FromString(temp);
+ else
+ {
+ Py_INCREF(Py_None);
+ pg_default_passwd = Py_None;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/* gets default port */
+static char getdefport__doc__[] =
+"get_defport() -- return default database port.";
+
+static PyObject *
+pggetdefport(PyObject * self, PyObject * args)
+{
+ /* checks args */
+ if (!PyArg_ParseTuple(args, ""))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "method get_defport() takes no parameter.");
+ return NULL;
+ }
+
+ Py_XINCREF(pg_default_port);
+ return pg_default_port;
+}
+
+/* sets default port */
+static char setdefport__doc__[] =
+"set_defport(integer) -- set default database port. Return previous value.";
+
+static PyObject *
+pgsetdefport(PyObject * self, PyObject * args)
+{
+ long int port = -2;
+ PyObject *old;
+
+ /* gets arguments */
+ if ((!PyArg_ParseTuple(args, "l", &port)) || (port < -1))
+ {
+ PyErr_SetString(PyExc_TypeError, "set_defport(port), with port "
+ "(positive integer/-1).");
+ return NULL;
+ }
+
+ /* adjusts value */
+ old = pg_default_port;
+
+ if (port != -1)
+ pg_default_port = PyInt_FromLong(port);
+ else
+ {
+ Py_INCREF(Py_None);
+ pg_default_port = Py_None;
+ }
+
+ return old;
+}
+#endif /* DEFAULT_VARS */
+
+/* List of functions defined in the module */
+
+static struct PyMethodDef pg_methods[] = {
+ {"connect", (PyCFunction) pgconnect, METH_VARARGS|METH_KEYWORDS,
+ connect__doc__},
+ {"escape_string", (PyCFunction) escape_string, METH_VARARGS,
+ escape_string__doc__},
+ {"escape_bytea", (PyCFunction) escape_bytea, METH_VARARGS,
+ escape_bytea__doc__},
+ {"unescape_bytea", (PyCFunction) unescape_bytea, METH_VARARGS,
+ unescape_bytea__doc__},
+ {"set_decimal", (PyCFunction) set_decimal, METH_VARARGS,
+ set_decimal__doc__},
+
+#ifdef DEFAULT_VARS
+ {"get_defhost", pggetdefhost, METH_VARARGS, getdefhost__doc__},
+ {"set_defhost", pgsetdefhost, METH_VARARGS, setdefhost__doc__},
+ {"get_defbase", pggetdefbase, METH_VARARGS, getdefbase__doc__},
+ {"set_defbase", pgsetdefbase, METH_VARARGS, setdefbase__doc__},
+ {"get_defopt", pggetdefopt, METH_VARARGS, getdefopt__doc__},
+ {"set_defopt", pgsetdefopt, METH_VARARGS, setdefopt__doc__},
+ {"get_deftty", pggetdeftty, METH_VARARGS, getdeftty__doc__},
+ {"set_deftty", pgsetdeftty, METH_VARARGS, setdeftty__doc__},
+ {"get_defport", pggetdefport, METH_VARARGS, getdefport__doc__},
+ {"set_defport", pgsetdefport, METH_VARARGS, setdefport__doc__},
+ {"get_defuser", pggetdefuser, METH_VARARGS, getdefuser__doc__},
+ {"set_defuser", pgsetdefuser, METH_VARARGS, setdefuser__doc__},
+ {"set_defpasswd", pgsetdefpasswd, METH_VARARGS, setdefpasswd__doc__},
+#endif /* DEFAULT_VARS */
+ {NULL, NULL} /* sentinel */
+};
+
+static char pg__doc__[] = "Python interface to PostgreSQL DB";
+
+/* Initialization function for the module */
+DL_EXPORT(void)
+init_pg(void)
+{
+ PyObject *mod,
+ *dict,
+ *v;
+
+ /* Initialize here because some WIN platforms get confused otherwise */
+ PglargeType.ob_type = PgType.ob_type = PgQueryType.ob_type =
+ PgSourceType.ob_type = &PyType_Type;
+
+ /* Create the module and add the functions */
+
<TRUNCATED>