Don't issue a SET TRANSACTION ISOLATION LEVEL at every begin: use PG's
GUC default, eventually set by set_transaction.
Dropped the last query at connection, yay!
Method set_isolation_level() and property isolation_level refactored using
the new structures, keeping the previous semantic.
The encoding can be set by PGCLIENTENCODING, which may be an alternative
spelling. Bug reported by Peter Eisentraut.
At this point the idea of considering one of the random spellings such as
EUC_CN as somewhat "blessed" is debunked. So just store the cleaned-up
version of the encoding in the mapping table. Note that the cleaned-up
version was needed by the unicode adapter: this requirement has been
surpassed as the connection now contains a copy of the Python codec name
set whenever the client encoding is set.
PG 9.0 uses the hex format by default, and clients < 9.0 can't parse that
format, requiring client update and great care in what is linked at runtime,
and generally giving headache to users and transitively us.
- Check return value of PyErr_Malloc and set an exception in case of error
- Avoid exposing variables with refcount 0 as connection attributes.
- PyErr_Free guards itself for NULL input
It has long been used in wrong ways, with the function receiving a
connection or lobject instead of a cursor. It has always been unnoticed
(nobody has noticed the wrong object attached to the exception in the
wrong cases) but it started crashing the interpreter with Python 3.2 on
Windows.
Thanks to Jason Erickson for finding the problem and helping fixing it.
Empty array can be returned untyped by postgres. To handle
this case, a special handler is added for the type UNKNOWNOID.
If the value return by the database is strictly equal to "{}",
the value is converted. Otherwise, the conversion fallback on
the default handler.
Python 3.2 hash() function will now return a 64bit value when run on a 64bit
architecture, where as previously, it would always return a 32bit value.
Modified the code to use the now Py_hash_t typedef and for Python versions
less than 3.2, hard code Py_hash_t to long and Py_uhash_t to unsigned long.
- Raise an exception on incomplete placeholders.
- Minor speedups.
- Don't change the string in place (??!!) if the placeholder is not s
and the value is null.
The latter point can be done because downstream we don't accept anything
different from s anyway (in the Bytes_Format function).
Notice that now the format string is constant whatever the arguments.
This means that executemany is still more inefficient than it should be
as mogrify may work only on the parameters. However this is an
implementation only worthwhile if we start supporting real parameters.
Let's talk about that for the next release.
The value is used to control the number of records to fetch per network
roundtrip in named cursors iteration. Used to avoid the inefficient
arraysize default of 1 without giving this value the magic meaning of
2000.
Supporting this interface is required to adapt memoryview on Python 2.7 as they
don't support the old style. But because the old style is long deprecated it
makes sense to start supporting the new one.
The feature in itself is not extremely useful and instead PostgreSQL is
not always able to cast away from text[], which is a regression see
(ticket #42).
Apparently, using * for the architecture has the potential to not work on
on some amd64 systems. Added checks and split the manifest based upon
architecture.
Added a change at the end of the build process that would reinsert the VC library manifest. This patch will fix issues when an embedded program does not have a manifest pointing to the VC 2008 runtime library, such as in an apache/mod_python situation.
Signed-off-by: Jason Erickson <jerickso@stickpeople.com>
If a connection is destroyed before an async operation is completed, the
`async_cursor` member creates a reference loop, leaving the connection and
the cursor alive. `async_cursor` is now a weak reference.
Added an internal function with C signature to avoid the creation of a
tuple to be later unpacked. When the tuple was decref'd, Python 2.4 64
bits regularly segfaulted; Python 2.5 less regularly; don't know about
other versions.
It was an error as the string is not conform to the protocol. The error
is masked by the None fast path in _mogrify, but surfaces when adapting
a tuple contains a None.
This makes the behaviour between the two versions similar. It also have
the effect of a more specific error message in case an user specifies a
placeholder different from 's'.
Not sure this is the best way to go: it is now impossible to write a
binary typecaster in Python; furthermore it is the opposite approach of
the codecs, which should return bytes.
Just compiled! No test run yet and many points to review, marked in the
code.
The patch is largely Martin von Löwis work, simplified after refactoring
in the previous commits and adapted to the new code (as the patch was
originally for Psycopg 2.0.9)
.c files only need to import psycopg.h: it will in turn import
dependencies from Python and libpq and configure.h. psycopg.h should be
the first to be imported, so the basic imports are not required in
the .h's
As a guideline I'm trying to import from the most specific to the most
generic to detect missing imports in the .h's.
Note: the functions are private because typecast.c imports the .c's of
typecast_[mx]datetime, not the .h's.
Work around the warning for 'skip_until_space' not used with an #ifdef.
Furthermore, those functions are now static.
This cuts off server whose version is older than 7.4. But enables us to
remove large portions of code rarely used and tested (e.g. p2 copy) and
will allow us to drop the query we do at each connection to establish
the client encoding and the datestyle.
Explicit comparison with the tuple is required if we want to make
Notify() == (pid, channel) work: item access is not enough (and a test
in the suite fails if we get this wrong).
We don't do somersaults to ensure people can use snowmen as transaction
ids anyway: it would require passing the connection to xid_ensure and
down below to use the correct encoding.
By James Henstridge on 2008-07-23.
Merged from lp:~jamesh/psycopg/two-phase-commit/revision/356
* psycopg/connection_type.c (psyco_conn_xid): add a
Connection.xid() method that instantiates Xid objects.
* psycopg/psycopgmodule.c (init_psycopg): initialise the Xid
object type.
* psycopg/xid.h:
* psycopg/xid_type.c: Implement a basic transaction ID object for
use in two phase commit.
It was deprecated for version 2.1. There are bugs to be fixed made more
complex by its presence and it doesn't keep into account PostgreSQL 9.0
new binary format.
Time to go!
Allow the objects to be recognized as the proper type by Postgres in not
strong contexts: problem reported by Peter Eisentraut.
Added tests to check the types are respected in a complete Py -> PG ->
Py roundtrip without context.
Don't rely on Postgres casting the literal according to the context:
this doesn't work e.g. passing the object as function argument where a
function with the same name but taking a text exists. It doesn't work
either when the object is in an ARRAY construct.
Added test to check the type is respected in a complete Py -> PG -> Py
roundtrip without context.
Bug and solution reported by Peter Eisentraut.
Dropped set/unset nonblocking mode for copy and lobject operations:
lobjects don't work in nonblocking mode so they will hardly be supported
in green/async branches. Support for copy is still feasible, but it
will be done in other code paths (called by poll).
Failing in doing that broke notifications reception.
The responsibility for changing the async_status has been moved to the
poll function: this is consistent with how the async branch is
implemented.
With this commit all the test suite passes in "green" mode.
With the current implementation, at best they would silently block. They
actually hang everything.
Implementation posponed after some refactoring of the polling system,
because it will be probably possible to provide an implementation for
'poll()' during COPY which is good for both async and green modes.
The function is called without holding the GIL. Because it is necessary
to execute the Python callback if set, we need to re-acquire the GIL and
tnen release it again. In order to correctly bookkeep the thread state,
the pointer of the _save variable is passed to the function.
If the connection is sync, notices will be processed by pq_fetch()
downstream.
If the connection is async, here we have only sent the query: no result
is ready yet, and neither notices have had a chance to arrive: they will
be retrieved later by pq_is_busy().
Added tests to check the above statement don't break.
Instead, the code should be using the fileno() and poll() methods of
the cursor's connection. Handle the case when poll() is called on an
already built connection as a request to poll the asynchronous query
(if there is one) and get NOTIFY events.
Update the tests to reflect that change, add a test for NOTIFY.
Do it by keeping the reference to the last PGresult in the cursor and
calling pq_fetch() before ending the asynchronous execution. This
takes care of handling the possible error state of the PGresult and
also allows the removal of the needsfetch flag, since now after
execution ends the results are already fetched and parsed.
Without this a query that did not get flushed completely to the server
would cause cursor.poll() to always go into the curs_poll_send()
branch even if it was retuning ASYNC_READ.
Bug report by Daniele Varrazzo.
This hides from the user the libpq's implementation detail of
requiring the first select() to wait for the connection socket to
become writable and makes it possible to have a uniform select loop
for both cursors and connections, in which you always start by polling
the object and then acting according to the result from poll().
Idea and implementation by Daniele Varrazzo.
If there is an asynchronous query, polling a cursor that did not
initiate it will raise an exception. Polling while there is no
asynchronous query underway still works, because the user needs to
have a way to get asynchronous NOTIFYs.
POLL_OK has been changed from 3 to 0 to let the user specify a short loop
just as "if not curs.poll()" instead of having to check for write and read
separately. For an example of this, see examples/notify.py.
It was trying to get all pending results from the connection and if
the client sent many and anyone except the first one would not be
immediately available the loop in curs_get_last_result would call
PQgetResult blockingly.
Avoid that by calling PQisBusy every time and telling the client to
wait for more data if it returns 1.
The CONN_STATUS_SENT_* statuses were not being handled at all, and
they indicate that a query has been sent, but not fully, so the client
should wait for the socket to become writable again and flush the output.
The methods changed are connection.commit(), rollback(), reset(),
set_isolation_level(), set_client_encoding(), lobject(), cursor(str)
as well as cursor.execute() and cursor.callproc() if another query is
in progress and cursor.executemany(), cursor.copy_{from,to,expert)().
Drop the async kwarg from cursor.execute(), cursors created by
asynchronous connections will be asynchronous by default, ones created
by synchronous connections will be synchronous.
Mind that this might break third party subclasses of
psycopg2.extensions.cursor, if they try to chain to the superclass in
their execute() implementation and are passing the async kwarg. The
example cursors in psycopg2.extras have been fixed no to do that.
Clients using async connections are expected to do their own
transaction management by sending (asynchronously) BEGIN and COMMIT
statements.
As a bonus, it allows to drop one step from the async connection
building, namely getting the default isolation level from the server.
The isread() API was not safe, because the query might have not been
sent fully to the server after calling execute(). To make the async
API complete, a similar mechanism to async connections must be used.
The cursor now has a poll() method that you would use identically to
the poll() method of the connection class.
After calling psycopg2.connect(dsn, async=True) you can poll the
connection that will tell you whether its file descriptor should be
waited on to become writable or readable or that the connection
attempt has succeeded.
Edited commit by Jan to not expose internal state in extensions.py.
Remove the big loop in pq_fetch with the select() call, among
others. Code paths that don't support asynchronous queries should now
be adequately guarded.
The lobject.truncate(len=0) method will be available if psycopg2 has
been built against libpq from 8.3 or later (which is when the lobject
truncating support has been introduced).
* psycopg/adapter_binary.c (binary_escape): simplify PostgreSQL
version check.
* setup.py (psycopg_build_ext.finalize_options): use a single
define of the PostgreSQL version in a form that can easily be used
by #ifdefs.
coverage for datetime and time strings with and without time zone
information.
* psycopg/typecast_datetime.c (typecast_PYDATETIME_cast): adjust
to handle the changes in typecast_parse_time.
(typecast_PYTIME_cast): add support for time zone aware time
values.
* psycopg/typecast_mxdatetime.c (typecast_MXDATE_cast): make sure
that values with time zones are correctly processed (even though
that means ignoring the time zone value).
(typecast_MXTIME_cast): same here.
* psycopg/typecast.c (typecast_parse_time): Update method to parse
second resolution timezone offsets.
negative timezone offsets with a non-zero minutes field.
* tests/test_dates.py (DatetimeTests): Add tests for time zone
parsing. The test for HH:MM:SS time zones is disabled because we
don't currently support it.