ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | |
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | #pike __REAL_VERSION__
|
5a4c01 | 2016-11-08 | Stephen R. van den Berg | | #pragma dynamic_dot
|
5691e4 | 2014-11-10 | Stephen R. van den Berg | | #require constant(Thread.Thread)
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
#include "pgsql.h"
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | #define PORTALINIT 0 // Portal states
#define PARSING 1
#define BOUND 2
#define COMMITTED 3
#define COPYINPROGRESS 4
#define CLOSING 5
#define CLOSED 6
#define PURGED 7
#define NOERROR 0 // Error states networkparser
#define PROTOCOLERROR 1
#define PROTOCOLUNSUPPORTED 2
#define LOSTERROR "Database connection lost"
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | #if PG_DEADLOCK_SENTINEL
private multiset mutexes = set_weak_flag((<>), Pike.WEAK);
private int deadlockseq;
private class MUTEX {
inherit Thread.Mutex;
private Thread.Thread sentinelthread;
private void dump_lockgraph(Thread.Thread curthread) {
sleep(PG_DEADLOCK_SENTINEL);
String.Buffer buf = String.Buffer();
buf.add("\n{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{\n");
buf.sprintf("Deadlock detected at\n%s\n",
describe_backtrace(curthread.backtrace(), -1));
foreach(mutexes; this_program mu; )
if (mu) {
Thread.Thread ct;
if (ct = mu.current_locking_thread())
buf.sprintf("====================================== Mutex: %O\n%s\n",
mu, describe_backtrace(ct.backtrace(), -1));
}
buf.add("}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}");
werror(replace(buf.get(), "\n", sprintf("\n%d> ", deadlockseq++)) + "\n");
}
Thread.MutexKey lock(void|int type) {
Thread.MutexKey key;
if (!(key = trylock(type))) {
sentinelthread = Thread.Thread(dump_lockgraph, this_thread());
key = ::lock(type);
sentinelthread->kill();
}
return key;
}
protected void create() {
mutexes[this] = 1;
}
};
#else
#define MUTEX Thread.Mutex
#endif
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | final Pike.Backend local_backend;
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
909e4a | 2021-03-25 | Stephen R. van den Berg | | private Shuffler.Shuffler shuffler = Shuffler.Shuffler();
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | private Pike.Backend cb_backend;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | private Result qalreadyprinted;
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private Thread.Mutex backendmux = Thread.Mutex();
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | final multiset(proxy) clients = set_weak_flag((<>), Pike.WEAK);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | mapping describenodata
= (["datarowdesc":({}), "datarowtypes":({}), "datatypeoid":({})]);
private multiset censoroptions = (<"use_ssl", "force_ssl",
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | "cache_autoprepared_statements", "reconnect", "text_query", "is_superuser",
"server_encoding", "server_version", "integer_datetimes",
|
b840fa | 2014-11-19 | Stephen R. van den Berg | | "session_authorization">);
|
609b78 | 2014-11-26 | Stephen R. van den Berg | |
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final Regexp createprefix = iregexp("^\a*(CREATE|DROP)\a");
|
609b78 | 2014-11-26 | Stephen R. van den Berg | |
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | private Regexp dontcacheprefix = iregexp("^\a*(FETCH|COPY)\a");
|
609b78 | 2014-11-26 | Stephen R. van den Berg | |
|
c138a0 | 2014-11-26 | Stephen R. van den Berg | | private Regexp paralleliseprefix
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | = iregexp("^\a*((SELEC|INSER)T|(UPDA|DELE)TE|(FETC|WIT)H)\a");
|
609b78 | 2014-11-26 | Stephen R. van den Berg | |
|
ac1503 | 2020-05-18 | Stephen R. van den Berg | | |
55a08b | 2017-06-25 | Stephen R. van den Berg | | * insert a sync after the statement.
* Failure to do so, will result in portal synchronisation errors
* in the event of an ErrorResponse.
*/
final Regexp transbeginprefix
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | = iregexp("^\a*(BEGIN|START)([; \t\f\r\n]|$)");
|
55a08b | 2017-06-25 | Stephen R. van den Berg | |
|
ac1503 | 2020-05-18 | Stephen R. van den Berg | | |
55a08b | 2017-06-25 | Stephen R. van den Berg | | * insert a sync after the statement.
* Failure to do so, will result in portal synchronisation errors
* in the event of an ErrorResponse.
*/
final Regexp transendprefix
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | = iregexp("^\a*(COMMIT|ROLLBACK|END)([; \t\f\r\n]|$)");
|
55a08b | 2017-06-25 | Stephen R. van den Berg | |
|
ac1503 | 2020-05-18 | Stephen R. van den Berg | |
final Regexp nodataresprefix
= iregexp("^\a*(RESET|CLOSE|DISCARD)\a");
|
609b78 | 2014-11-26 | Stephen R. van den Berg | | |
882833 | 2017-07-28 | Stephen R. van den Berg | | * fetched in pieces. This heuristic will be sub-optimal whenever
* either an UPDATE/DELETE/INSERT statement is prefixed by WITH, or
* if there is a RETURNING with a *lot* of results. In those cases
* the portal will be busy until all results have been fetched, and will
* not be able to deliver results belonging to other parallel queries
* running on the same filedescriptor.
*
* However, considering that the current heuristic increases query-speed
* in the majority of the real-world cases, it would be considered a good
* tradeoff.
|
609b78 | 2014-11-26 | Stephen R. van den Berg | | */
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private Regexp execfetchlimit
|
18805c | 2021-03-04 | Stephen R. van den Berg | | = iregexp("^\a*((UPDA|DELE)TE|INSERT|CREATE|DROP|CALL"
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | "|RESET|CLOSE|DISCARD)\a|\aLIMIT\a+[1-9][; \t\f\r\n]*$");
|
c138a0 | 2014-11-26 | Stephen R. van den Berg | |
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | private void default_backend_runs() {
cb_backend = Pike.DefaultBackend;
}
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void create() {
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | atexit(_destruct);
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | |
|
909e4a | 2021-03-25 | Stephen R. van den Berg | | shuffler->set_backend(cb_backend = local_backend = Pike.Backend());
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | call_out(default_backend_runs, 0);
}
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void _destruct() {
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | foreach (clients; proxy client; )
destruct(client);
}
|
c138a0 | 2014-11-26 | Stephen R. van den Berg | | private Regexp iregexp(string expr) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | Stdio.Buffer ret = Stdio.Buffer();
foreach (expr; ; int c)
if (c >= 'A' && c <= 'Z')
ret->add('[', c, c + 'a' - 'A', ']');
else if (c == '\a')
|
c138a0 | 2014-11-26 | Stephen R. van den Berg | | ret->add("[ \t\f\r\n]");
else
ret->add_int8(c);
return Regexp(ret->read());
}
|
615d42 | 2014-10-31 | Stephen R. van den Berg | |
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final void closestatement(bufcon|conxsess plugbuffer, string oldprep) {
if (oldprep) {
PD("Close statement %s\n", oldprep);
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | CHAIN(plugbuffer)->add_int8('C')->add_hstring(({'S', oldprep, 0}), 4, 4);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void run_local_backend() {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.MutexKey lock;
int looponce;
do {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | looponce = 0;
if (lock = backendmux->trylock()) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | PD("Starting local backend\n");
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | while (sizeof(clients)
|
e1963e | 2017-11-15 | Stephen R. van den Berg | | || sizeof(local_backend->call_out_info())) {
|
cbac2f | 2016-10-12 | Stephen R. van den Berg | | mixed err;
if (err = catch(local_backend(4096.0)))
|
1a2da9 | 2017-11-30 | Stephen R. van den Berg | | master()->handle_error(err);
|
cbac2f | 2016-10-12 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | PD("Terminating local backend\n");
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | lock = 0;
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | looponce = sizeof(clients);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | } while (looponce);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
16b883 | 2014-11-10 | Stephen R. van den Berg | |
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | final void register_backend(proxy client) {
int startbackend = !sizeof(clients);
clients[client] = 1;
|
67879d | 2017-11-10 | Stephen R. van den Berg | | if (startbackend)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.Thread(run_local_backend);
}
|
4741cd | 2008-07-31 | Stephen R. van den Berg | |
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | final void throwdelayederror(Result|proxy parent) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (mixed err = parent->delayederror) {
if (!objectp(parent->pgsqlsess))
parent->untolderror = 0;
else if (parent->pgsqlsess)
|
3d6e3c | 2020-02-22 | Stephen R. van den Berg | | parent->pgsqlsess->untolderror = parent->pgsqlsess->delayederror = 0;
parent->delayederror = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (stringp(err))
err = ({err, backtrace()[..<2]});
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | throw(err);
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | private int readoidformat(int oid) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | switch (oid) {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | case BOOLOID:
case BYTEAOID:
case CHAROID:
case INT8OID:
case INT2OID:
case INT4OID:
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | case FLOAT4OID:
#if !constant(__builtin.__SINGLE_PRECISION_FLOAT__)
case FLOAT8OID:
#endif
|
4855e2 | 2018-02-05 | Stephen R. van den Berg | | case NUMERICOID:
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | case TEXTOID:
case OIDOID:
case XMLOID:
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | case DATEOID:
case TIMEOID:
case TIMETZOID:
case TIMESTAMPOID:
case TIMESTAMPTZOID:
case INTERVALOID:
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | case INT4RANGEOID:
case INT8RANGEOID:
case DATERANGEOID:
case TSRANGEOID:
case TSTZRANGEOID:
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | case MACADDROID:
case BPCHAROID:
case VARCHAROID:
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | case CIDROID:
case INETOID:
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | case CTIDOID:
case UUIDOID:
return 1;
}
return 0;
}
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | private int writeoidformat(int oid, array(string|int) paramValues,
array(int) ai) {
mixed value = paramValues[ai[0]++];
switch (oid) {
case BOOLOID:
case BYTEAOID:
case CHAROID:
case INT8OID:
case INT2OID:
case INT4OID:
case TEXTOID:
case OIDOID:
case XMLOID:
case MACADDROID:
case BPCHAROID:
case VARCHAROID:
case CTIDOID:
case UUIDOID:
return 1;
|
4855e2 | 2018-02-05 | Stephen R. van den Berg | | case NUMERICOID:
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | case CIDROID:
case INETOID:
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | case DATEOID:
case TIMEOID:
case TIMETZOID:
case TIMESTAMPOID:
case TIMESTAMPTZOID:
case INTERVALOID:
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | case INT4RANGEOID:
case INT8RANGEOID:
case DATERANGEOID:
case TSRANGEOID:
case TSTZRANGEOID:
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | case FLOAT4OID:
#if !constant(__builtin.__SINGLE_PRECISION_FLOAT__)
case FLOAT8OID:
#endif
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | if (!stringp(value))
return 1;
}
return 0;
}
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | #define DAYSEPOCHTO2000 10957 // 2000/01/01 00:00:00 UTC
#define USEPOCHTO2000 (DAYSEPOCHTO2000*24*3600*1000000)
private array timestamptotype
|
3794dd | 2017-12-21 | Martin Nilsson | | = ({Val.Timestamp, 8, USEPOCHTO2000, "usecs", 8});
private array datetotype = ({Val.Date, 4, DAYSEPOCHTO2000, "days", 4});
|
01b815 | 2017-12-06 | Stephen R. van den Berg | |
private mapping(int:array) oidtotype = ([
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | DATEOID: datetotype,
|
3794dd | 2017-12-21 | Martin Nilsson | | TIMEOID: ({Val.Time, 8, 0, "usecs", 8}),
TIMETZOID: ({Val.TimeTZ, 12, 0, "usecs", 8, "timezone", 4}),
INTERVALOID: ({Val.Interval, 16, 0, "usecs", 8, "days", 4, "months",4}),
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | TIMESTAMPOID: timestamptotype,
TIMESTAMPTZOID: timestamptotype,
INT4RANGEOID: ({0, 4}),
INT8RANGEOID: ({0, 8}),
DATERANGEOID: datetotype,
TSRANGEOID: timestamptotype,
TSTZRANGEOID: timestamptotype,
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | ]);
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private inline mixed callout(function(mixed ...:void) f,
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | float|int delay, mixed ... args) {
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | return cb_backend->call_out(f, delay, @args);
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | }
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | class bufcon {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | inherit Stdio.Buffer;
|
67879d | 2017-11-10 | Stephen R. van den Berg | | private Thread.ResourceCountKey dirty;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | #ifdef PG_DEBUGRACE
final bufcon `chain() {
return this;
}
#endif
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | private conxion realbuffer;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void create(conxion _realbuffer) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | realbuffer = _realbuffer;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
d43282 | 2008-07-31 | Stephen R. van den Berg | |
|
67879d | 2017-11-10 | Stephen R. van den Berg | | final Thread.ResourceCount `stashcount() {
|
44de4f | 2016-10-15 | Stephen R. van den Berg | | return realbuffer->stashcount;
}
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | final MUTEX `shortmux() {
return realbuffer->shortmux;
}
final bufcon start(void|int|array(Thread.MutexKey) waitforreal) {
dirty = stashcount->acquire();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (waitforreal)
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | error("pgsql.bufcon not allowed here\n");
|
d43282 | 2008-07-31 | Stephen R. van den Berg | | #endif
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return this;
}
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | final void sendcmd(int mode, void|Result portal) {
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | Thread.MutexKey lock = shortmux->lock();
|
aac297 | 2017-07-03 | Stephen R. van den Berg | | if (portal)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | realbuffer->stashqueue->write(portal);
|
aac297 | 2017-07-03 | Stephen R. van den Berg | | if (mode == SYNCSEND) {
add(PGSYNC);
realbuffer->stashqueue->write(1);
mode = SENDOUT;
|
b1fe66 | 2017-06-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | realbuffer->stash->add(this);
|
aac297 | 2017-07-03 | Stephen R. van den Berg | | PD("%d>Stashed mode %d > %d\n",
|
a123c4 | 2017-07-01 | Stephen R. van den Berg | | realbuffer->socket->query_fd(), mode, realbuffer->stashflushmode);
if (mode > realbuffer->stashflushmode)
realbuffer->stashflushmode = mode;
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | dirty = 0;
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | lock = 0;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | this->clear();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (lock = realbuffer->nostash->trylock(1)) {
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | #ifdef PG_DEBUGRACE
conxsess sess = conxsess(realbuffer);
realbuffer->started = lock;
lock = 0;
sess->sendcmd(SENDOUT);
#else
realbuffer->started = lock;
lock = 0;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | realbuffer->sendcmd(SENDOUT);
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | #endif
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
d43282 | 2008-07-31 | Stephen R. van den Berg | | }
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | };
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | class conxiin {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | inherit Stdio.Buffer:i;
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | |
final Thread.Condition fillread;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final MUTEX fillreadmux;
|
7f73f4 | 2014-12-16 | Stephen R. van den Berg | | final int procmsg;
|
7607f5 | 2014-11-25 | Stephen R. van den Berg | | private int didreadcb;
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | |
|
180df8 | 2018-05-18 | Stephen R. van den Berg | | #if PG_DEBUGHISTORY > 0
final array history = ({});
final int(-1..) input_from(Stdio.Stream stm, void|int(0..) nbytes) {
int oldsize = sizeof(this);
int ret = i::input_from(stm, nbytes);
if (ret) {
Stdio.Buffer tb = Stdio.Buffer(this);
tb->consume(oldsize);
history += ({"<<"+tb->read(ret)});
history = history[<PG_DEBUGHISTORY - 1 ..];
}
return ret;
}
#endif
|
67879d | 2017-11-10 | Stephen R. van den Berg | | protected final bool range_error(int howmuch) {
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
6268a6 | 2018-05-17 | Stephen R. van den Berg | | if (howmuch < 0) {
int available = unread(0);
unread(available);
error("Out of range %d %O %O\n", howmuch,
((string)this)[.. available-1], ((string)this)[available ..]);
}
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (fillread) {
Thread.MutexKey lock = fillreadmux->lock();
if (!didreadcb)
|
0c6907 | 2014-11-25 | Stephen R. van den Berg | | fillread.wait(lock);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | didreadcb = 0;
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | } else
throw(MAGICTERMINATE);
return true;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final int read_cb(mixed id, mixed b) {
|
b13bac | 2017-07-01 | Stephen R. van den Berg | | PD("Read callback %O\n", b && ((string)b)
|
9d0a68 | 2016-10-12 | Stephen R. van den Berg | | #ifndef PG_DEBUGMORE
[..255]
#endif
);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | Thread.MutexKey lock = fillreadmux->lock();
if (procmsg && id)
procmsg = 0, lock = 0, Thread.Thread(id);
else if (fillread)
didreadcb = 1, fillread.signal();
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | return 0;
}
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void create() {
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | i::create();
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | fillreadmux = MUTEX();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | fillread = Thread.Condition();
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | }
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | };
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | |
|
0282f9 | 2017-10-29 | Stephen R. van den Berg | | class sfile {
inherit Stdio.File;
|
67879d | 2017-11-10 | Stephen R. van den Berg | | final int query_fd() {
|
0282f9 | 2017-10-29 | Stephen R. van den Berg | | return is_open() ? ::query_fd() : -1;
}
};
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | class conxion {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | inherit Stdio.Buffer:o;
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | final conxiin i;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private Thread.Queue qportals;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final MUTEX shortmux;
|
dcc15c | 2016-02-27 | Stephen R. van den Berg | | private int closenext;
|
da3dc8 | 2016-02-24 | Stephen R. van den Berg | |
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final sfile
#if constant(SSL.File)
|SSL.File
#endif
socket;
|
909e4a | 2021-03-25 | Stephen R. van den Berg | | final Shuffler.Shuffle shuffle;
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | final multiset(Result) runningportals = (<>);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final MUTEX nostash;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final Thread.MutexKey started;
final Thread.Queue stashqueue;
final Stdio.Buffer stash;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | |
final int(KEEP..SYNCSEND) stashflushmode;
|
67879d | 2017-11-10 | Stephen R. van den Berg | | final Thread.ResourceCount stashcount;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int synctransact;
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | #ifdef PG_DEBUGRACE
final mixed nostrack;
#endif
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int queueoutidx;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final int queueinidx = -1;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | #endif
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | private inline void queueup(Result portal) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | qportals->write(portal); portal->_synctransact = synctransact;
PD("%d>%O %d %d Queue portal %d bytes\n", socket->query_fd(),
portal._portalname, ++queueoutidx, synctransact, sizeof(this));
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | }
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | final bufcon|conxsess start(void|int|array(Thread.MutexKey) waitforreal) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | Thread.MutexKey lock;
|
1616b2 | 2018-05-07 | Stephen R. van den Berg | | #ifdef PG_DEBUGRACE
if (nostash->current_locking_thread())
PD("Nostash locked by %s\n",
describe_backtrace(nostash->current_locking_thread()->backtrace()));
#endif
|
a09bfe | 2021-04-06 | Stephen R. van den Berg | | while (lock = nostash
&& ((intp(waitforreal) && waitforreal > 0
? nostash->lock : nostash->trylock)(1))) {
|
337b8d | 2018-05-22 | Stephen R. van den Berg | | int mode;
if (sizeof(stash) && (mode = getstash(KEEP)) > KEEP)
|
e7efba | 2018-05-26 | Stephen R. van den Berg | | sendcmd(mode);
|
fbb0b1 | 2018-06-02 | Stephen R. van den Berg | | if (!stashcount->drained()) {
lock = 0;
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | if (arrayp(waitforreal))
waitforreal[0] = 0;
|
fbb0b1 | 2018-06-02 | Stephen R. van den Berg | | stashcount->wait_till_drained();
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | if (arrayp(waitforreal))
return 0;
|
fbb0b1 | 2018-06-02 | Stephen R. van den Berg | | continue;
}
#ifdef PG_DEBUGRACE
conxsess sess = conxsess(this);
#endif
|
e7efba | 2018-05-26 | Stephen R. van den Berg | | started = lock;
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | #ifdef PG_DEBUGRACE
return sess;
#else
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return this;
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | #endif
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | if (arrayp(waitforreal))
waitforreal[0] = 0;
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | return !waitforreal && bufcon(this)->start();
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
909e4a | 2021-03-25 | Stephen R. van den Berg | | private void done_cb() {
|
51e96a | 2021-03-28 | Stephen R. van den Berg | | if (!i->fillread)
close();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
b1fe66 | 2017-06-27 | Stephen R. van den Berg | | private int getstash(int mode) {
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | Thread.MutexKey lock = shortmux->lock();
add(stash); stash->clear();
foreach (stashqueue->try_read_array(); ; int|Result portal)
if (intp(portal))
qportals->write(synctransact++);
else
queueup(portal);
PD("%d>Got stash mode %d > %d\n",
socket->query_fd(), stashflushmode, mode);
if (stashflushmode > mode)
mode = stashflushmode;
stashflushmode = KEEP;
|
b1fe66 | 2017-06-27 | Stephen R. van den Berg | | return mode;
}
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | final void sendcmd(void|int mode, void|Result portal) {
|
b1fe66 | 2017-06-27 | Stephen R. van den Berg | | if (portal)
queueup(portal);
unfinalised:
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | do {
|
4c965a | 2016-10-13 | Stephen R. van den Berg | | switch (mode) {
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | default:
|
b1fe66 | 2017-06-27 | Stephen R. van den Berg | | break unfinalised;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case SYNCSEND:
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | PD("%d>Sync %d %d Queue\n",
|
4c965a | 2016-10-13 | Stephen R. van den Berg | | socket->query_fd(), synctransact, ++queueoutidx);
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | add(PGSYNC);
|
4c965a | 2016-10-13 | Stephen R. van den Berg | | mode = SENDOUT;
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | break;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case FLUSHLOGSEND:
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("%d>%d Queue simplequery %d bytes\n",
socket->query_fd(), ++queueoutidx, sizeof(this));
|
4c965a | 2016-10-13 | Stephen R. van den Berg | | mode = FLUSHSEND;
|
35dc28 | 2014-11-13 | Stephen R. van den Berg | | }
qportals->write(synctransact++);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | } while (0);
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | if (sizeof(stash))
mode = getstash(mode);
|
e4ff9f | 2018-05-23 | Stephen R. van den Berg | | #ifdef PG_DEBUG
mixed err;
#endif
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | for(;;) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
e4ff9f | 2018-05-23 | Stephen R. van den Berg | | err =
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | #endif
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | catch {
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | outer:
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | do {
switch (mode) {
default:
PD("%d>Skip flush %d Queue %O\n",
socket->query_fd(), mode, (string)this);
break outer;
case FLUSHSEND:
PD("Flush\n");
add(PGFLUSH);
case SENDOUT:;
}
|
909e4a | 2021-03-25 | Stephen R. van den Berg | | if (sizeof(this)) {
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | PD("%d>Sendcmd %O\n", socket->query_fd(), (string)this);
|
909e4a | 2021-03-25 | Stephen R. van den Berg | | #if PG_DEBUGHISTORY > 0
i->history += ({">>" + (string)this});
i->history = i->history[<PG_DEBUGHISTORY - 1 ..];
#endif
shuffle->add_source(this);
|
92de16 | 2021-04-24 | Stephen R. van den Berg | | shuffle->start(1, 1);
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | }
} while (0);
started = 0;
|
e7efba | 2018-05-26 | Stephen R. van den Berg | | if (sizeof(stash) && (started = nostash->trylock(2))) {
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | #ifdef PG_DEBUGRACE
conxsess sess = conxsess(this);
sess->sendcmd(SENDOUT);
#else
mode = getstash(SENDOUT);
continue;
#endif
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | }
|
79b54f | 2018-05-22 | Stephen R. van den Berg | | return;
};
break;
}
started = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("Sendcmd failed %s\n", describe_backtrace(err));
|
4b055c | 2017-11-17 | Stephen R. van den Berg | | destruct(this);
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | final int close() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!closenext && nostash) {
closenext = 1;
|
81790f | 2017-11-28 | Stephen R. van den Berg | | {
Thread.MutexKey lock = i->fillreadmux->lock();
if (i->fillread) {
|
51e96a | 2021-03-28 | Stephen R. van den Berg | | shuffle->set_done_callback(done_cb);
|
81790f | 2017-11-28 | Stephen R. van den Berg | | i->fillread.signal();
i->fillread = 0;
}
|
b95bf7 | 2016-02-17 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%d>Delayed close, flush write\n", socket->query_fd());
i->read_cb(socket->query_id(), 0);
|
32857b | 2016-02-28 | Stephen R. van den Berg | | return 0;
} else
return -1;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final void purge() {
if (stashcount) {
stashcount = 0;
PD("%d>Purge conxion %d\n", socket ? socket->query_fd() : -1, !!nostash);
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | int|Result portal;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (qportals)
while (portal = qportals->try_read())
if (objectp(portal))
portal->_purgeportal();
if (nostash) {
while (sizeof(runningportals))
catch {
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | foreach (runningportals; Result result; )
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!result.datarowtypes) {
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | result.datarowtypes = ({});
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (result._state != PURGED && !result.delayederror)
result.delayederror = LOSTERROR;
result._ddescribe->broadcast();
runningportals[result] = 0;
} else
destruct(result);
};
|
32857b | 2016-02-28 | Stephen R. van den Berg | | destruct(nostash);
|
21efd7 | 2019-05-29 | Stephen R. van den Berg | | if (socket->set_non_blocking)
socket->set_non_blocking();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%d>Close socket\n", socket->query_fd());
|
51e96a | 2021-03-28 | Stephen R. van den Berg | | shuffle->stop();
|
57fdb2 | 2017-11-21 | Stephen R. van den Berg | | socket->close();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
destruct(this);
|
32857b | 2016-02-28 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void _destruct() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%d>Close conxion %d\n", socket ? socket->query_fd() : -1, !!nostash);
catch(purge());
}
final void connectloop(proxy pgsqlsess, int nossl) {
|
4b7cf5 | 2017-11-21 | Stephen R. van den Berg | | #ifdef PG_DEBUG
mixed err =
#endif
catch {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | for (; ; clear()) {
socket->connect(pgsqlsess. host, pgsqlsess. port);
|
e6f0d2 | 2021-03-28 | Stephen R. van den Berg | | socket->set_nodelay(1);
|
fc7f09 | 2014-06-01 | Martin Nilsson | | #if constant(SSL.File)
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!nossl && !pgsqlsess->nossl
&& (pgsqlsess.options.use_ssl || pgsqlsess.options.force_ssl)) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | PD("SSLRequest\n");
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | start()->add_int32(8)->add_int32(PG_PROTOCOL(1234, 5679))
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | ->sendcmd(SENDOUT);
|
17cca2 | 2017-11-21 | Stephen R. van den Berg | | string s = socket.read(1);
switch (sizeof(s) && s[0]) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | case 'S':
|
17cca2 | 2017-11-21 | Stephen R. van den Berg | | SSL.File fcon = SSL.File(socket, SSL.Context());
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (fcon->connect()) {
socket->set_backend(local_backend);
socket = fcon;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | break;
}
|
846944 | 2016-12-06 | Stephen R. van den Berg | | default:
PD("%d>Close socket short\n", socket->query_fd());
|
4f2ed8 | 2014-11-15 | Stephen R. van den Berg | | socket->close();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | pgsqlsess.nossl = 1;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | continue;
case 'N':
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (pgsqlsess.options.force_ssl)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | error("Encryption not supported on connection to %s:%d\n",
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | pgsqlsess.host, pgsqlsess.port);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
}
#else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (pgsqlsess.options.force_ssl)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | error("Encryption library missing,"
" cannot establish connection to %s:%d\n",
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | pgsqlsess.host, pgsqlsess.port);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | #endif
break;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!socket->is_open())
error(strerror(socket->errno()) + ".\n");
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | socket->set_backend(local_backend);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | socket->set_buffer_mode(i, 0);
|
909e4a | 2021-03-25 | Stephen R. van den Berg | | socket->set_nonblocking(i->read_cb, 0, close);
|
51e96a | 2021-03-28 | Stephen R. van den Berg | | shuffle = shuffler->shuffle(socket);
|
4b055c | 2017-11-17 | Stephen R. van den Berg | | if (nossl != 2)
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | Thread.Thread(pgsqlsess->processloop, this);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return;
};
|
4b7cf5 | 2017-11-21 | Stephen R. van den Berg | | PD("Connect error %s\n", describe_backtrace(err));
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | catch(destruct(pgsqlsess->waitforauthready));
|
4b055c | 2017-11-17 | Stephen R. van den Berg | | destruct(this);
|
480874 | 2014-11-14 | Stephen R. van den Berg | | }
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected string _sprintf(int type) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | string res;
|
86b605 | 2021-04-14 | Stephen R. van den Berg | | if (!this)
|
9ef3d0 | 2021-05-02 | Stephen R. van den Berg | | return "(destructed)";
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | switch (type) {
|
480874 | 2014-11-14 | Stephen R. van den Berg | | case 'O':
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | int fd = -1;
if (socket)
catch(fd = socket->query_fd());
|
0bd775 | 2021-04-30 | Stephen R. van den Berg | | if (!this)
|
9ef3d0 | 2021-05-02 | Stephen R. van den Berg | | return "(destructed)";
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | res = predef::sprintf("conxion fd: %d input queue: %d/%d "
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | "queued portals: %d output queue: %d/%d\n"
|
67879d | 2017-11-10 | Stephen R. van den Berg | | "started: %d\n",
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | fd, sizeof(i), i->_size_object(),
|
e28813 | 2017-07-01 | Stephen R. van den Berg | | qportals && qportals->size(), sizeof(this), _size_object(),
|
67879d | 2017-11-10 | Stephen R. van den Berg | | !!started);
|
480874 | 2014-11-14 | Stephen R. van den Berg | | break;
}
return res;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void create(proxy pgsqlsess, Thread.Queue _qportals, int nossl) {
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | o::create();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | qportals = _qportals;
|
3e8df2 | 2014-10-29 | Stephen R. van den Berg | | synctransact = 1;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | socket = sfile();
i = conxiin();
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | shortmux = MUTEX();
nostash = MUTEX();
|
dcc15c | 2016-02-27 | Stephen R. van den Berg | | closenext = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | stashqueue = Thread.Queue();
stash = Stdio.Buffer();
|
67879d | 2017-11-10 | Stephen R. van den Berg | | stashcount = Thread.ResourceCount();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | Thread.Thread(connectloop, pgsqlsess, nossl);
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | };
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | #ifdef PG_DEBUGRACE
class conxsess {
final conxion chain;
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void create(conxion parent) {
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | if (parent->started)
werror("Overwriting conxsess %s %s\n",
describe_backtrace(({"new ", backtrace()[..<1]})),
describe_backtrace(({"old ", parent->nostrack})));
parent->nostrack = backtrace();
chain = parent;
}
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | final void sendcmd(int mode, void|Result portal) {
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | chain->sendcmd(mode, portal);
chain = 0;
}
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void _destruct() {
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | if (chain)
werror("Untransmitted conxsess %s\n",
describe_backtrace(({"", backtrace()[..<1]})));
}
};
#endif
|
f4c9d6 | 2009-02-15 | Stephen R. van den Berg | |
|
63fcae | 2017-11-22 | Stephen R. van den Berg | |
|
041296 | 2009-01-19 | Stephen R. van den Berg | |
|
63fcae | 2017-11-22 | Stephen R. van den Berg | |
class Result {
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
b52b45 | 2017-03-15 | Henrik Grubbström (Grubba) | | inherit __builtin.Sql.Result;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | private proxy pgsqlsess;
private int(0..1) eoffound;
|
39e1c4 | 2014-11-14 | Stephen R. van den Berg | | private conxion c;
|
c7de86 | 2014-11-20 | Stephen R. van den Berg | | private conxiin cr;
|
a55cc4 | 2017-11-22 | Stephen R. van den Berg | | final int(0..1) untolderror;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final mixed delayederror;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | |
final int(PORTALINIT..PURGED) _state;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int _fetchlimit;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | private int(0..1) alltext;
final int(0..1) _forcetext;
|
657cd9 | 2017-02-04 | Stephen R. van den Berg | | private int syncparse;
|
55a08b | 2017-06-25 | Stephen R. van den Berg | | private int transtype;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | |
final string _portalname;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | private int inflight;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | int portalbuffersize;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | private MUTEX closemux;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | private Thread.Queue datarows;
|
67879d | 2017-11-10 | Stephen R. van den Berg | | private Thread.ResourceCountKey stmtifkey, portalsifkey;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | private array(mapping(string:mixed)) datarowdesc;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final array(int) datarowtypes;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | private string statuscmdcomplete;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | private int bytesreceived;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final int _synctransact;
final Thread.Condition _ddescribe;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final MUTEX _ddescribemux;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final Thread.MutexKey _unnamedportalkey, _unnamedstatementkey;
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | final array _params;
final string _query;
final string _preparedname;
final mapping(string:mixed) _tprepared;
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | private function(:void) gottimeout;
private int timeout;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
67879d | 2017-11-10 | Stephen R. van den Berg | | protected string _sprintf(int type) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | string res;
|
86b605 | 2021-04-14 | Stephen R. van den Berg | | if (!this)
|
9ef3d0 | 2021-05-02 | Stephen R. van den Berg | | return "(destructed)";
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | switch (type) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | case 'O':
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | int fd = -1;
if (c && c->socket)
catch(fd = c->socket->query_fd());
|
0bd775 | 2021-04-30 | Stephen R. van den Berg | | if (!this)
return "";
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | res = sprintf(
"Result state: %d numrows: %d eof: %d inflight: %d\n"
"fd: %O portalname: %O coltypes: %d"
" synctransact: %d laststatus: %s\n"
"stash: %O\n"
|
180df8 | 2018-05-18 | Stephen R. van den Berg | | #if PG_DEBUGHISTORY > 0
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | "history: %O\n"
|
180df8 | 2018-05-18 | Stephen R. van den Berg | | #endif
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | "query: %O\n%s\n",
_state, index, eoffound, inflight,
fd, _portalname,
datarowtypes && sizeof(datarowtypes), _synctransact,
statuscmdcomplete
|| (_unnamedstatementkey ? "*parsing*" : ""),
qalreadyprinted == this ? 0
: c && (string)c->stash,
|
180df8 | 2018-05-18 | Stephen R. van den Berg | | #if PG_DEBUGHISTORY > 0
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | qalreadyprinted == this ? 0 : c && c->i->history,
|
180df8 | 2018-05-18 | Stephen R. van den Berg | | #endif
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | qalreadyprinted == this
? "..." : replace(_query, "xxxx\n", "\\n"),
qalreadyprinted == this ? "..." : _showbindings()*"\n");
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | qalreadyprinted = this;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | break;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
return res;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | protected void create(proxy _pgsqlsess, conxion _c, string query,
int _portalbuffersize, int alltyped, array params, int forcetext,
|
55a08b | 2017-06-25 | Stephen R. van den Berg | | int _timeout, int _syncparse, int _transtype) {
|
3c93de | 2014-11-03 | Stephen R. van den Berg | | pgsqlsess = _pgsqlsess;
|
81790f | 2017-11-28 | Stephen R. van den Berg | | if (c = _c)
cr = c->i;
else
|
0b714c | 2020-05-18 | Stephen R. van den Berg | | losterror(LOSTERROR);
|
11b13b | 2014-08-16 | Martin Nilsson | | _query = query;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarows = Thread.Queue();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | _ddescribe = Thread.Condition();
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | _ddescribemux = MUTEX();
closemux = MUTEX();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | portalbuffersize = _portalbuffersize;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | alltext = !alltyped;
|
11b13b | 2014-08-16 | Martin Nilsson | | _params = params;
_forcetext = forcetext;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | _state = PORTALINIT;
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | timeout = _timeout;
|
657cd9 | 2017-02-04 | Stephen R. van den Berg | | syncparse = _syncparse;
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | gottimeout = _pgsqlsess->cancelquery;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | c->runningportals[this] = 1;
|
55a08b | 2017-06-25 | Stephen R. van den Berg | | transtype = _transtype;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | final array(string) _showbindings() {
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | array(string) msgs = ({});
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | if (_params) {
array from, to, paramValues;
[from, to, paramValues] = _params;
if (sizeof(paramValues)) {
int i;
string val, fmt = sprintf("%%%ds %%3s %%.61s", max(@map(from, sizeof)));
foreach (paramValues; i; val)
msgs += ({sprintf(fmt, from[i], to[i], sprintf("%O", val))});
}
}
return msgs;
}
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
42dcee | 2018-05-05 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final string status_command_complete() {
|
42dcee | 2018-05-05 | Stephen R. van den Berg | | if (!statuscmdcomplete) {
if (!datarowtypes)
waitfordescribe();
{
Thread.MutexKey lock = closemux->lock();
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | if (_fetchlimit) {
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | array(Thread.MutexKey) reflock = ({ _fetchlimit = 0 });
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | for (;;) {
reflock[0] = lock;
lock = 0;
if (!_sendexecute(0, reflock)) {
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("Status_command_complete retry closemux %O\n", _portalname);
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | lock = closemux->lock();
continue;
}
|
28a80a | 2020-05-27 | Stephen R. van den Berg | | break;
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | }
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | }
lock = 0;
|
42dcee | 2018-05-05 | Stephen R. van den Berg | | lock = _ddescribemux->lock();
if (!statuscmdcomplete)
PT(_ddescribe->wait(lock));
}
if (this)
trydelayederror();
else
error(LOSTERROR);
}
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | return statuscmdcomplete;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
42dcee | 2018-05-05 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final int affected_rows() {
|
11b13b | 2014-08-16 | Martin Nilsson | | int rows;
|
42dcee | 2018-05-05 | Stephen R. van den Berg | | sscanf(status_command_complete() || "", "%*s %d %d", rows, rows);
|
11b13b | 2014-08-16 | Martin Nilsson | | return rows;
}
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | final void _storetiming() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (_tprepared) {
_tprepared.trun = gethrtime() - _tprepared.trunstart;
m_delete(_tprepared, "trunstart");
_tprepared = 0;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | }
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void waitfordescribe() {
|
81790f | 2017-11-28 | Stephen R. van den Berg | | {
Thread.MutexKey lock = _ddescribemux->lock();
if (!datarowtypes)
PT(_ddescribe->wait(lock));
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (this)
trydelayederror();
else
error(LOSTERROR);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
63fcae | 2017-11-22 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final int num_fields() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!datarowtypes)
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | waitfordescribe();
|
531835 | 2014-11-22 | Stephen R. van den Berg | | return sizeof(datarowtypes);
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
7214f6 | 2014-11-24 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
63fcae | 2017-11-22 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final int num_rows() {
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | trydelayederror();
|
d9e1ab | 2017-11-22 | Stephen R. van den Berg | | return index;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
0b714c | 2020-05-18 | Stephen R. van den Berg | | private void losterror(void|string err) {
|
e1963e | 2017-11-15 | Stephen R. van den Berg | | if (pgsqlsess)
|
0b714c | 2020-05-18 | Stephen R. van den Berg | | err = pgsqlsess->geterror(1) || err;
if (err)
error("%s\n", err);
|
e1963e | 2017-11-15 | Stephen R. van den Berg | | }
private void trydelayederror() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (delayederror)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | throwdelayederror(this);
|
e1963e | 2017-11-15 | Stephen R. van den Berg | | else if (_state == PURGED)
losterror();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
63fcae | 2017-11-22 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final int eof() {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
|
11b13b | 2014-08-16 | Martin Nilsson | | return eoffound;
}
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
63fcae | 2017-11-22 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final array(mapping(string:mixed)) fetch_fields() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!datarowtypes)
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | waitfordescribe();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!datarowdesc)
error(LOSTERROR);
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | return datarowdesc + ({});
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | }
#ifdef PG_DEBUG
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | #define INTVOID int
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | #else
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | #define INTVOID void
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final INTVOID _decodedata(int msglen, string cenc) {
|
2e28a9 | 2017-06-18 | Stephen R. van den Berg | | _storetiming(); _releasestatement();
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | string serror;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | bytesreceived += msglen;
int cols = cr->read_int16();
array a = allocate(cols, !alltext && Val.null);
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen -= 2 + 4 * cols;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | foreach (datarowtypes; int i; int typ) {
int collen = cr->read_sint(4);
if (collen > 0) {
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen -= collen;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | #endif
mixed value;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | switch (typ) {
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | case FLOAT4OID:
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | #if !constant(__builtin.__SINGLE_PRECISION_FLOAT__)
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | case FLOAT8OID:
#endif
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | if (_forcetext) {
if (!alltext) {
value = (float)cr->read(collen);
break;
}
} else {
[ value ] = cr->sscanf(collen == 4 ? "%4F" : "%8F");
if (alltext)
|
b2e431 | 2018-02-01 | Stephen R. van den Berg | | value = sprintf("%.*g", collen == 4 ? 9 : 17, value);
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | break;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | default:value = cr->read(collen);
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | break;
case CHAROID:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | value = alltext ? cr->read(1) : cr->read_int8();
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | break;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | case BOOLOID:value = cr->read_int8();
switch (value) {
case 'f':value = 0;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | break;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | case 't':value = 1;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (alltext)
value = value ? "t" : "f";
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | break;
case TEXTOID:
case BPCHAROID:
case VARCHAROID:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | value = cr->read(collen);
if (cenc == UTF8CHARSET && catch(value = utf8_to_string(value))
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | && !serror)
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | serror = SERROR("%O contains non-%s characters\n",
value, UTF8CHARSET);
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | break;
|
4855e2 | 2018-02-05 | Stephen R. van den Berg | | case NUMERICOID:
if (_forcetext) {
value = cr->read(collen);
if (!alltext) {
value = value/".";
if (sizeof(value) == 1)
value = (int)value[0];
else {
|
0d4b5d | 2018-02-06 | Stephen R. van den Berg | | int i, denom;
for (i = sizeof(value[1]), denom = 1; --i >= 0; denom *= 10);
i = (int)value[0];
value = (int)value[1];
value = Gmp.mpq(i * denom + (i >= 0 ? value : -value),
|
4855e2 | 2018-02-05 | Stephen R. van den Berg | | denom);
}
}
} else {
int nwords = cr->read_int16();
int magnitude = cr->read_sint(2);
int sign = cr->read_int16();
cr->consume(2);
|
3bf8e8 | 2018-03-10 | Stephen R. van den Berg | | if (nwords) {
for (value = cr->read_int16(); --nwords; magnitude--)
value = value * NUMERIC_MAGSTEP + cr->read_int16();
if (sign)
value = -value;
if (magnitude > 0)
do
value *= NUMERIC_MAGSTEP;
while (--magnitude);
else if (magnitude < 0) {
for (sign = NUMERIC_MAGSTEP;
++magnitude;
sign *= NUMERIC_MAGSTEP);
value = Gmp.mpq(value, sign);
}
} else
value = 0;
|
0d4b5d | 2018-02-06 | Stephen R. van den Berg | | if (alltext)
value = (string)value;
|
4855e2 | 2018-02-05 | Stephen R. van den Berg | | }
break;
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | case INT4RANGEOID:
case INT8RANGEOID:
case DATERANGEOID:
case TSRANGEOID:
case TSTZRANGEOID:
if (_forcetext)
value = cr->read(collen);
else {
array totype = oidtotype[typ];
|
ebc421 | 2017-12-11 | Stephen R. van den Berg | | mixed from = -Math.inf, till = Math.inf;
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | switch (cr->read_int8()) {
case 1: from = till = 0;
break;
|
7a97fb | 2017-12-13 | Stephen R. van den Berg | | case 0x12: from = cr->read_sint(cr->read_int32());
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | break;
|
7a97fb | 2017-12-13 | Stephen R. van den Berg | | case 2: from = cr->read_sint(cr->read_int32());
case 8: till = cr->read_sint(cr->read_int32());
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | }
if (totype[0]) {
if (intp(from)) {
value = totype[0]();
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | value[totype[3]] = from + totype[2];
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | from = value;
}
if (intp(till)) {
value = totype[0]();
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | value[totype[3]] = till + totype[2];
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | till = value;
}
}
|
b46f4d | 2017-12-22 | Stephen R. van den Berg | | value = Val.Range(from, till);
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | if (alltext)
|
90ca77 | 2017-12-28 | Stephen R. van den Berg | | value = value->sql();
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | }
break;
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | case CIDROID:
case INETOID:
if (_forcetext)
value = cr->read(collen);
else {
|
b46f4d | 2017-12-22 | Stephen R. van den Berg | | value = Val.Inet();
|
db9867 | 2017-12-07 | Stephen R. van den Berg | | int iptype = cr->read_int8();
value->masklen = cr->read_int8() + (iptype == 2 && 12*8);
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | cr->read_int8();
|
db9867 | 2017-12-07 | Stephen R. van den Berg | | value->address = cr->read_hint(1);
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | if (alltext)
value = (string)value;
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | }
break;
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | case TIMESTAMPOID:
case TIMESTAMPTZOID:
case INTERVALOID:
case TIMETZOID:
case TIMEOID:
case DATEOID:
if (_forcetext)
value = cr->read(collen);
else {
array totype = oidtotype[typ];
value = totype[0]();
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | value[totype[3]] = cr->read_sint(totype[4]) + totype[2];
int i = 5;
while (i < sizeof(totype)) {
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | value[totype[i]] = cr->read_sint(totype[i+1]);
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | i += 2;
}
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | if (alltext)
value = (string)value;
}
break;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | case INT8OID:case INT2OID:
case OIDOID:case INT4OID:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (_forcetext) {
value = cr->read(collen);
if (!alltext)
value = (int)value;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | } else {
|
f37f60 | 2021-04-18 | Stephen R. van den Berg | | value = cr->read_sint(collen);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (alltext)
value = (string)value;
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | }
}
a[i]=value;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | } else if (!collen)
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | a[i]="";
}
_processdataready(a);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (serror)
|
aed714 | 2014-11-18 | Stephen R. van den Berg | | error(serror);
#ifdef PG_DEBUG
return msglen;
#endif
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
805925 | 2014-11-25 | Stephen R. van den Berg | | final void _setrowdesc(array(mapping(string:mixed)) drowdesc,
array(int) drowtypes) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | Thread.MutexKey lock = _ddescribemux->lock();
datarowdesc = drowdesc;
datarowtypes = drowtypes;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | _ddescribe->broadcast();
}
|
075c54 | 2014-11-03 | Stephen R. van den Berg | | final void _preparebind(array dtoid) {
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | array(string|int) paramValues = _params ? _params[2] : ({});
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (sizeof(dtoid) != sizeof(paramValues))
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | SUSERERROR("Invalid number of bindings, expected %d, got %d\n",
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | sizeof(dtoid), sizeof(paramValues));
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("PrepareBind\n");
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | Thread.MutexKey lock = _ddescribemux->lock();
if (!_portalname) {
_portalname
= (_unnamedportalkey = pgsqlsess.unnamedportalmux->trylock(1))
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | ? "" : PORTALPREFIX
#ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | + (string)(c->socket->query_fd()) + "_"
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | + String.int2hex(pgsqlsess.pportalcount++);
lock = 0;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | #ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("ParamValues to bind: %O\n", paramValues);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | Stdio.Buffer plugbuffer = Stdio.Buffer();
{ array dta = ({sizeof(dtoid)});
plugbuffer->add(_portalname, 0, _preparedname, 0)
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | ->add_ints(dta
+ map(dtoid, writeoidformat, paramValues, ({0})) + dta, 2);
|
c9c7fc | 2014-11-26 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | string cenc = pgsqlsess.runtimeparameter[CLIENT_ENCODING];
foreach (paramValues; int i; mixed value) {
if (undefinedp(value) || objectp(value) && value->is_val_null)
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | plugbuffer->add_int32(-1);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | else if (stringp(value) && !sizeof(value)) {
int k = 0;
switch (dtoid[i]) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | default:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | k = -1;
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | case BYTEAOID:
case TEXTOID:
case XMLOID:
case BPCHAROID:
case VARCHAROID:;
}
plugbuffer->add_int32(k);
} else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | switch (dtoid[i]) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | case TEXTOID:
case BPCHAROID:
case VARCHAROID: {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!value) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | plugbuffer->add_int32(-1);
break;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | value = (string)value;
switch (cenc) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | case UTF8CHARSET:
|
d87fb2 | 2020-01-21 | Stephen R. van den Berg | | if (has_value(value, 0))
SUSERERROR("NUL characters not allowed in PG-UTF-8: %O\n",
value);
else
value = string_to_utf8(value);
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | break;
default:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (String.width(value)>8) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | SUSERERROR("Don't know how to convert %O to %s encoding\n",
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | value, cenc);
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | value="";
}
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | plugbuffer->add_hstring(value, 4);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | break;
}
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | default: {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!value) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | plugbuffer->add_int32(-1);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | break;
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | }
|
bb7afa | 2020-05-28 | Stephen R. van den Berg | | if (!objectp(value) || typeof(value) != typeof(Stdio.Buffer()))
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | |
if (multisetp(value) && sizeof(value) == 1)
value = indices(value)[0];
else {
|
7c9d77 | 2017-07-10 | Stephen R. van den Berg | | value = (string)value;
|
bb7afa | 2020-05-28 | Stephen R. van den Berg | | if (cenc == UTF8CHARSET
&& (dtoid[i] != BYTEAOID || String.width(value) > 8))
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | |
bb7afa | 2020-05-28 | Stephen R. van den Berg | | * FIXME For BYTEAOID and wide strings we should
* throw an error here, but for historical reasons and
* as a DWIM convenience we autoconvert to UTF8 anyway.
|
7c9d77 | 2017-07-10 | Stephen R. van den Berg | | */
|
bb7afa | 2020-05-28 | Stephen R. van den Berg | | value = string_to_utf8(value);
else if (String.width(value) > 8) {
SUSERERROR(
"Wide string %O not supported for type OID %d\n",
value, dtoid[i]);
value = "";
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
plugbuffer->add_hstring(value, 4);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | break;
}
|
42ab4c | 2014-11-25 | Stephen R. van den Berg | | case BOOLOID:
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | do {
int tval;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (stringp(value))
tval = value[0];
else if (!intp(value)) {
value = !!value;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | break;
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | } else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | tval = value;
switch (tval) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | case 'o':case 'O':
catch {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | tval = value[1];
value = tval == 'n' || tval == 'N';
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | };
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | break;
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | default:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | value = 1;
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | break;
case 0:case '0':case 'f':case 'F':case 'n':case 'N':
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | value = 0;
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | break;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | } while (0);
|
65f303 | 2017-12-08 | Stephen R. van den Berg | | plugbuffer->add("\0\0\0\1", value);
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | break;
case CHAROID:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (intp(value))
plugbuffer->add_hstring(value, 4);
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | else {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | value = (string)value;
switch (sizeof(value)) {
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | default:
SUSERERROR(
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | "\"char\" types must be 1 byte wide, got %O\n", value);
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | case 0:
plugbuffer->add_int32(-1);
break;
case 1:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | plugbuffer->add_hstring(value[0], 4);
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | }
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | break;
|
4855e2 | 2018-02-05 | Stephen R. van den Berg | | case NUMERICOID:
if (stringp(value))
plugbuffer->add_hstring(value, 4);
else {
int num, den, sign, magnitude = 0;
value = Gmp.mpq(value);
num = value->num();
den = value->den();
for (value = den;
value > NUMERIC_MAGSTEP;
value /= NUMERIC_MAGSTEP);
if (value > 1) {
value = NUMERIC_MAGSTEP / value;
num *= value;
den *= value;
}
if (num < 0)
sign = 0x4000, num = -num;
else
sign = 0;
array stor = ({});
if (num) {
while (!(num % NUMERIC_MAGSTEP))
num /= NUMERIC_MAGSTEP, magnitude++;
do
stor = ({num % NUMERIC_MAGSTEP}) + stor, magnitude++;
while (num /= NUMERIC_MAGSTEP);
num = --magnitude << 2;
while (den > 1)
magnitude--, den /= NUMERIC_MAGSTEP;
}
plugbuffer->add_int32(4 * 2 + (sizeof(stor) << 1))
->add_int16(sizeof(stor))->add_int16(magnitude)
->add_int16(sign)->add_int16(num)->add_ints(stor, 2);
}
break;
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | case INT4RANGEOID:
case INT8RANGEOID:
case DATERANGEOID:
case TSRANGEOID:
case TSTZRANGEOID:
if (stringp(value))
plugbuffer->add_hstring(value, 4);
else if (value->from >= value->till)
plugbuffer->add("\0\0\0\1\1");
else {
array totype = oidtotype[dtoid[i]];
int w = totype[1];
int from, till;
if (totype[0])
from = value->from, till = value->till;
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | else {
from = value->from[totype[3]] - totype[2];
till = value->till[totype[3]] - totype[2];
}
|
ebc421 | 2017-12-11 | Stephen R. van den Berg | | if (value->till == Math.inf)
if (value->from == -Math.inf)
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | plugbuffer->add("\0\0\0\1\30");
else
plugbuffer->add("\0\0\0", 1 + 4 + w, "\22\0\0\0", w)
->add_int(from, w);
else {
|
ebc421 | 2017-12-11 | Stephen R. van den Berg | | if (value->from == -Math.inf)
|
7d5748 | 2017-12-11 | Stephen R. van den Berg | | plugbuffer->add("\0\0\0", 1 + 4 + w, 8);
else
plugbuffer->add("\0\0\0", 1 + 4 * 2 + w * 2, "\2\0\0\0", w)
->add_int(from, w);
plugbuffer->add_int32(w)->add_int(till, w);
}
}
break;
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | case CIDROID:
case INETOID:
if (stringp(value))
plugbuffer->add_hstring(value, 4);
|
db9867 | 2017-12-07 | Stephen R. van den Berg | | else if (value->address <= 0xffffffff)
|
65f303 | 2017-12-08 | Stephen R. van den Berg | | plugbuffer->add("\0\0\0\10\2",
value->masklen - 12 * 8, dtoid[i] == CIDROID, 4)
->add_int32(value->address);
|
db9867 | 2017-12-07 | Stephen R. van den Berg | | else
|
65f303 | 2017-12-08 | Stephen R. van den Berg | | plugbuffer->add("\0\0\0\24\3",
value->masklen, dtoid[i] == CIDROID, 16)
|
db9867 | 2017-12-07 | Stephen R. van den Berg | | ->add_int(value->address, 16);
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | break;
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | case DATEOID:
case TIMEOID:
case TIMETZOID:
case INTERVALOID:
case TIMESTAMPOID:
case TIMESTAMPTZOID:
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | if (stringp(value))
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | plugbuffer->add_hstring(value, 4);
|
adfd4e | 2017-12-07 | Stephen R. van den Berg | | else {
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | array totype = oidtotype[dtoid[i]];
if (!objectp(value))
value = totype[0](value);
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | plugbuffer->add_int32(totype[1])
->add_int(value[totype[3]] - totype[2], totype[4]);
int i = 5;
while (i < sizeof(totype)) {
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | plugbuffer->add_int(value[totype[i]], totype[i+1]);
|
c44ed9 | 2017-12-13 | Stephen R. van den Berg | | i += 2;
}
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | }
break;
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | case FLOAT4OID:
#if !constant(__builtin.__SINGLE_PRECISION_FLOAT__)
case FLOAT8OID:
#endif
if (stringp(value))
plugbuffer->add_hstring(value, 4);
else {
int w = dtoid[i] == FLOAT4OID ? 4 : 8;
plugbuffer->add_int32(w)
|
2ac307 | 2020-02-17 | Stephen R. van den Berg | | ->sprintf(w == 4 ? "%4F" : "%8F", (float)value);
|
a46919 | 2017-12-11 | Stephen R. van den Berg | | }
break;
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | case INT8OID:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | plugbuffer->add_int32(8)->add_int((int)value, 8);
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | break;
case OIDOID:
case INT4OID:
plugbuffer->add_int32(4)->add_int32((int)value);
break;
case INT2OID:
plugbuffer->add_int32(2)->add_int16((int)value);
break;
}
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!datarowtypes) {
if (_tprepared && dontcacheprefix->match(_query))
m_delete(pgsqlsess->prepareds, _query), _tprepared = 0;
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("WaitForDescribe\n");
|
531835 | 2014-11-22 | Stephen R. van den Berg | | waitfordescribe();
|
d57b1a | 2014-11-18 | Stephen R. van den Berg | | }
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("About to bind %d\n", _state);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (_state >= CLOSING)
lock = _unnamedstatementkey = 0;
|
531835 | 2014-11-22 | Stephen R. van den Berg | | else {
plugbuffer->add_int16(sizeof(datarowtypes));
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | if (sizeof(datarowtypes)) {
|
01b815 | 2017-12-06 | Stephen R. van den Berg | | plugbuffer->add_ints(map(datarowtypes, readoidformat), 2);
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | lock = 0;
} else if (syncparse < 0 && !pgsqlsess->wasparallelisable
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | && !pgsqlsess->statementsinflight->drained(1)) {
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | lock = 0;
|
67879d | 2017-11-10 | Stephen R. van den Berg | | PD("Commit waiting for statements to finish\n");
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | catch(PT(pgsqlsess->statementsinflight->wait_till_drained(1)));
|
531835 | 2014-11-22 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("Bind portal %O statement %O\n", _portalname, _preparedname);
_fetchlimit = pgsqlsess->_fetchlimit;
|
662374 | 2017-06-17 | Stephen R. van den Berg | | _bindportal();
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | conxsess bindbuffer = c->start();
|
1a2da9 | 2017-11-30 | Stephen R. van den Berg | | stmtifkey = 0;
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | CHAIN(bindbuffer)->add_int8('B')->add_hstring(plugbuffer, 4, 4);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!_tprepared && sizeof(_preparedname))
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | closestatement(CHAIN(bindbuffer), _preparedname);
|
531835 | 2014-11-22 | Stephen R. van den Berg | | _sendexecute(_fetchlimit
|
55a08b | 2017-06-25 | Stephen R. van den Berg | | && !(transtype != NOTRANS
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | || sizeof(_query) >= MINPREPARELENGTH &&
|
531835 | 2014-11-22 | Stephen R. van den Berg | | execfetchlimit->match(_query))
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | && _fetchlimit, bindbuffer);
|
21efd7 | 2019-05-29 | Stephen R. van den Berg | | _unnamedstatementkey = 0;
|
531835 | 2014-11-22 | Stephen R. van den Berg | | }
|
81790f | 2017-11-28 | Stephen R. van den Berg | | }
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
805925 | 2014-11-25 | Stephen R. van den Berg | | final void _processrowdesc(array(mapping(string:mixed)) datarowdesc,
array(int) datarowtypes) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | _setrowdesc(datarowdesc, datarowtypes);
if (_tprepared) {
_tprepared.datarowdesc = datarowdesc;
_tprepared.datarowtypes = datarowtypes;
|
805925 | 2014-11-25 | Stephen R. van den Berg | | }
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
662374 | 2017-06-17 | Stephen R. van den Berg | | final void _parseportal() {
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | for (;;) {
|
81790f | 2017-11-28 | Stephen R. van den Berg | | Thread.MutexKey lock = closemux->lock();
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | if ((syncparse || syncparse < 0 && pgsqlsess->wasparallelisable)
&& !pgsqlsess->statementsinflight->drained()) {
lock = 0;
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("Commit waiting for statements to finish %d\n",
pgsqlsess->statementsinflight->_count);
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | catch(PT(pgsqlsess->statementsinflight->wait_till_drained()));
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("Parseportal retry closemux %O\n", _portalname);
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | continue;
|
81790f | 2017-11-28 | Stephen R. van den Berg | | }
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | _state = PARSING;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | stmtifkey = pgsqlsess->statementsinflight->acquire();
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | break;
|
662374 | 2017-06-17 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | statuscmdcomplete = 0;
pgsqlsess->wasparallelisable = paralleliseprefix->match(_query);
|
662374 | 2017-06-17 | Stephen R. van den Berg | | }
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final void _releasestatement() {
|
e85f6b | 2018-05-17 | Stephen R. van den Berg | | Thread.MutexKey lock = closemux->lock();
|
2e28a9 | 2017-06-18 | Stephen R. van den Berg | | if (_state <= BOUND) {
|
67879d | 2017-11-10 | Stephen R. van den Berg | | stmtifkey = 0;
|
86cd34 | 2018-05-30 | Stephen R. van den Berg | | _state = COMMITTED;
|
2e28a9 | 2017-06-18 | Stephen R. van den Berg | | }
}
|
662374 | 2017-06-17 | Stephen R. van den Berg | | final void _bindportal() {
|
2e28a9 | 2017-06-18 | Stephen R. van den Berg | | Thread.MutexKey lock = closemux->lock();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | _state = BOUND;
portalsifkey = pgsqlsess->portalsinflight->acquire();
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | final void _purgeportal() {
|
662374 | 2017-06-17 | Stephen R. van den Berg | | PD("Purge portal\n");
|
5bbace | 2014-11-18 | Stephen R. van den Berg | | datarows->write(1);
|
81790f | 2017-11-28 | Stephen R. van den Berg | | {
Thread.MutexKey lock = closemux->lock();
_fetchlimit = 0;
|
86cd34 | 2018-05-30 | Stephen R. van den Berg | | stmtifkey = portalsifkey = 0;
|
81790f | 2017-11-28 | Stephen R. van den Berg | | _state = PURGED;
|
2e28a9 | 2017-06-18 | Stephen R. van den Berg | | }
|
04f130 | 2014-11-14 | Stephen R. van den Berg | | releaseconditions();
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final int _closeportal(conxsess cs, array(Thread.MutexKey) reflock) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | void|bufcon|conxsess plugbuffer = CHAIN(cs);
int retval = KEEP;
PD("%O Try Closeportal %d\n", _portalname, _state);
_fetchlimit = 0;
|
86cd34 | 2018-05-30 | Stephen R. van den Berg | | stmtifkey = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | switch (_state) {
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case PORTALINIT:
|
2e28a9 | 2017-06-18 | Stephen R. van den Berg | | case PARSING:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | _unnamedstatementkey = 0;
_state = CLOSING;
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | break;
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case COPYINPROGRESS:
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | PD("CopyDone\n");
plugbuffer->add("c\0\0\0\4");
|
2e28a9 | 2017-06-18 | Stephen R. van den Berg | | case COMMITTED:
|
2eef0b | 2014-11-15 | Stephen R. van den Berg | | case BOUND:
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | _state = CLOSING;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | if (reflock)
reflock[0] = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("Close portal %O\n", _portalname);
|
c02a6a | 2017-06-21 | Stephen R. van den Berg | | if (_portalname && sizeof(_portalname)) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | plugbuffer->add_int8('C')
->add_hstring(({'P', _portalname, 0}), 4, 4);
retval = FLUSHSEND;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | } else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | _unnamedportalkey = 0;
|
67879d | 2017-11-10 | Stephen R. van den Berg | | portalsifkey = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (pgsqlsess->portalsinflight->drained()) {
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | if (plugbuffer->stashcount->drained() && transtype != TRANSBEGIN) {
|
44de4f | 2016-10-15 | Stephen R. van den Berg | |
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | Thread.MutexKey lock = plugbuffer->shortmux->lock();
if (plugbuffer->stashcount->drained())
pgsqlsess->readyforquerycount++, retval = SYNCSEND;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | pgsqlsess->pportalcount = 0;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
}
return retval;
}
|
ed6f02 | 2018-05-05 | Stephen R. van den Berg | | private void replenishrows() {
|
c248e9 | 2018-05-24 | Stephen R. van den Berg | | if (_fetchlimit && datarows->size() <= _fetchlimit >> 1
&& _state >= COMMITTED) {
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | Thread.MutexKey lock;
for (;;) {
lock = closemux->lock();
if (_fetchlimit) {
_fetchlimit = pgsqlsess._fetchlimit;
if (bytesreceived)
_fetchlimit = min((portalbuffersize >> 1)
* index / bytesreceived || 1, _fetchlimit);
if (_fetchlimit)
if (inflight <= (_fetchlimit - 1) >> 1) {
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | array(Thread.MutexKey) reflock = ({ lock });
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | lock = 0;
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | if (!_sendexecute(_fetchlimit, reflock)) {
PD("Replenishrows retry closemux %O\n", _portalname);
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | continue;
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | }
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | } else
PD("<%O _fetchlimit %d, inflight %d, skip execute\n",
_portalname, _fetchlimit, inflight);
}
break;
|
1616b2 | 2018-05-07 | Stephen R. van den Berg | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
ed6f02 | 2018-05-05 | Stephen R. van den Berg | | final void _processdataready(array datarow, void|int msglen) {
bytesreceived += msglen;
inflight--;
|
e4ff9f | 2018-05-23 | Stephen R. van den Berg | | if (_state < CLOSED)
|
ed6f02 | 2018-05-05 | Stephen R. van den Berg | | datarows->write(datarow);
if (++index == 1)
PD("<%O _fetchlimit %d=min(%d||1,%d), inflight %d\n", _portalname,
_fetchlimit, (portalbuffersize >> 1) * index / bytesreceived,
pgsqlsess._fetchlimit, inflight);
replenishrows();
}
|
3d6e3c | 2020-02-22 | Stephen R. van den Berg | | private void releaseconditions(void|int aborted) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | _unnamedportalkey = _unnamedstatementkey = 0;
if (!datarowtypes) {
if (_state != PURGED && !delayederror)
delayederror = LOSTERROR;
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | datarowtypes = ({});
|
56cd39 | 2014-11-17 | Stephen R. van den Berg | | _ddescribe->broadcast();
|
f0522e | 2014-11-13 | Stephen R. van den Berg | | }
|
3d6e3c | 2020-02-22 | Stephen R. van den Berg | | if (aborted && delayederror && pgsqlsess && !pgsqlsess.delayederror)
|
8b6d74 | 2018-01-31 | Stephen R. van den Berg | | pgsqlsess.delayederror = delayederror;
|
3d6e3c | 2020-02-22 | Stephen R. van den Berg | | pgsqlsess = 0;
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | | }
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | final void _releasesession(void|string statusccomplete) {
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | int aborted = statusccomplete == "ABORT" ? 2 : 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | c->runningportals[this] = 0;
|
42dcee | 2018-05-05 | Stephen R. van den Berg | | if (statusccomplete && !statuscmdcomplete) {
Thread.MutexKey lock = _ddescribemux->lock();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | statuscmdcomplete = statusccomplete;
|
42dcee | 2018-05-05 | Stephen R. van den Berg | | _ddescribe->broadcast();
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | inflight = 0;
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | conxsess plugbuffer;
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | array(Thread.MutexKey) reflock = ({ 0 });
for (;;) {
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | reflock[0] = closemux->lock(aborted);
|
218ad9 | 2021-04-30 | Stephen R. van den Berg | | if (!catch(plugbuffer = c->start(reflock))) {
if (!this)
return;
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | if (plugbuffer)
plugbuffer->sendcmd(_closeportal(plugbuffer, reflock));
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | else {
PD("Releasesession retry closemux %O\n", _portalname);
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | continue;
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | }
|
218ad9 | 2021-04-30 | Stephen R. van den Berg | | }
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | break;
}
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | reflock[0] = 0;
|
1ccfab | 2018-05-21 | Stephen R. van den Berg | | if (_state < CLOSED) {
stmtifkey = 0;
|
86cd34 | 2018-05-30 | Stephen R. van den Berg | | _state = CLOSED;
|
1ccfab | 2018-05-21 | Stephen R. van den Berg | | }
|
088917 | 2017-11-09 | Stephen R. van den Berg | | datarows->write(1);
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | releaseconditions(aborted);
|
04f130 | 2014-11-14 | Stephen R. van den Berg | | }
|
c071bc | 2017-11-05 | Henrik Grubbström (Grubba) | | protected void _destruct() {
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | if (_state < CLOSED)
catch {
_releasesession("ABORT");
};
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | final int _sendexecute(int fetchlimit,
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | void|array(Thread.MutexKey)|bufcon|conxsess plugbuffer) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | int flushmode;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | array(Thread.MutexKey) reflock;
|
b1fe66 | 2017-06-27 | Stephen R. van den Berg | | PD("Execute portal %O fetchlimit %d transtype %d\n", _portalname,
fetchlimit, transtype);
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | if (arrayp(plugbuffer)) {
reflock = plugbuffer;
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | if (!(plugbuffer = c->start(reflock)))
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | return 0;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | CHAIN(plugbuffer)->add_int8('E')->add_hstring(({_portalname, 0}), 4, 8)
|
c9c7fc | 2014-11-26 | Stephen R. van den Berg | | ->add_int32(fetchlimit);
|
55a08b | 2017-06-25 | Stephen R. van den Berg | | if (!fetchlimit) {
if (transtype != NOTRANS)
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | pgsqlsess.intransaction = transtype == TRANSBEGIN;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | flushmode = _closeportal(plugbuffer, reflock) == SYNCSEND
|
55a08b | 2017-06-25 | Stephen R. van den Berg | | || transtype == TRANSEND ? SYNCSEND : FLUSHSEND;
} else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | inflight += fetchlimit, flushmode = FLUSHSEND;
plugbuffer->sendcmd(flushmode, this);
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | if (reflock)
reflock[0] = 0;
return 1;
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | inline private array setuptimeout() {
return local_backend->call_out(gottimeout, timeout);
}
|
770af1 | 2018-05-17 | Stephen R. van den Berg | | inline private void scuttletimeout(array cid) {
|
b05ab2 | 2018-05-17 | Stephen R. van den Berg | | if (local_backend)
local_backend->remove_call_out(cid);
}
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final array(mixed) fetch_row() {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | int|array datarow;
|
a80971 | 2019-11-01 | Stephen R. van den Berg | | if (!this)
return 0;
|
ed6f02 | 2018-05-05 | Stephen R. van den Berg | | replenishrows();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (arrayp(datarow = datarows->try_read()))
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return datarow;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!eoffound) {
if (!datarow) {
PD("%O Block for datarow\n", _portalname);
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | array cid = setuptimeout();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PT(datarow = datarows->read());
|
770af1 | 2018-05-17 | Stephen R. van den Berg | | if (!this)
return 0;
|
b05ab2 | 2018-05-17 | Stephen R. van den Berg | | scuttletimeout(cid);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (arrayp(datarow))
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | return datarow;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | eoffound = 1;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarows->write(1);
|
615d42 | 2014-10-31 | Stephen R. van den Berg | | }
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
return 0;
}
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final array(array(mixed)) fetch_row_array() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (eoffound)
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return 0;
|
ed6f02 | 2018-05-05 | Stephen R. van den Berg | | replenishrows();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | array(array|int) datarow = datarows->try_read_array();
|
574c65 | 2017-11-22 | Stephen R. van den Berg | | if (!sizeof(datarow)) {
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | array cid = setuptimeout();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PT(datarow = datarows->read_array());
|
770af1 | 2018-05-17 | Stephen R. van den Berg | | if (!this)
return 0;
|
b05ab2 | 2018-05-17 | Stephen R. van den Berg | | scuttletimeout(cid);
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | }
|
ed6f02 | 2018-05-05 | Stephen R. van den Berg | | replenishrows();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (arrayp(datarow[-1]))
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | return datarow;
|
e95258 | 2018-01-05 | Stephen R. van den Berg | | do datarow = datarow[..<1];
while (sizeof(datarow) && !arrayp(datarow[-1]));
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | eoffound = 1;
|
05b1f5 | 2014-11-17 | Stephen R. van den Berg | | datarows->write(1);
|
e95258 | 2018-01-05 | Stephen R. van den Berg | | return datarow;
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
ae952f | 2014-11-10 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
11b13b | 2014-08-16 | Martin Nilsson | |
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | |
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final void send_row(void|string|array(string) copydata) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | trydelayederror();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (copydata) {
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | PD("CopyData\n");
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | void|bufcon|conxsess cs = c->start();
|
c02c1d | 2017-06-03 | Stephen R. van den Berg | | CHAIN(cs)->add_int8('d')->add_hstring(copydata, 4, 4);
cs->sendcmd(SENDOUT);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | } else
_releasesession();
}
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void run_result_cb(
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | function(Result, array(mixed), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | array(mixed) args) {
int|array datarow;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | for (;;) {
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | array cid = setuptimeout();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PT(datarow = datarows->read());
|
770af1 | 2018-05-17 | Stephen R. van den Berg | | if (!this)
return 0;
|
b05ab2 | 2018-05-17 | Stephen R. van den Berg | | scuttletimeout(cid);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!arrayp(datarow))
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | break;
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, datarow, @args);
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | eoffound = 1;
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, 0, @args);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final void set_result_callback(
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | function(Result, array(mixed), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | mixed ... args) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (callback)
Thread.Thread(run_result_cb, callback, args);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
838482 | 2014-11-12 | Stephen R. van den Berg | | private void run_result_array_cb(
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | function(Result, array(array(mixed)), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | array(mixed) args) {
array(array|int) datarow;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | for (;;) {
|
1cfbdc | 2017-12-02 | Stephen R. van den Berg | | array cid = setuptimeout();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PT(datarow = datarows->read_array());
|
770af1 | 2018-05-17 | Stephen R. van den Berg | | if (!this)
return 0;
|
b05ab2 | 2018-05-17 | Stephen R. van den Berg | | scuttletimeout(cid);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!datarow || !arrayp(datarow[-1]))
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | break;
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, datarow, @args);
|
5cb4f2 | 2014-11-28 | Stephen R. van den Berg | | }
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | eoffound = 1;
if (sizeof(datarow)>1)
callout(callback, 0, this, datarow = datarow[..<1], @args);
|
2c9800 | 2014-11-10 | Stephen R. van den Berg | | callout(callback, 0, this, 0, @args);
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | }
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | final void set_result_array_callback(
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | function(Result, array(array(mixed)), mixed ...:void) callback,
|
16ce8b | 2014-09-12 | Stephen R. van den Berg | | mixed ... args) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (callback)
Thread.Thread(run_result_array_cb, callback, args);
}
};
class proxy {
final int _fetchlimit = FETCHLIMIT;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final MUTEX unnamedportalmux;
final MUTEX unnamedstatement;
|
8e5eda | 2020-06-22 | Stephen R. van den Berg | | private Thread.MutexKey|int termlock;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final Thread.ResourceCount portalsinflight, statementsinflight;
final int(0..1) wasparallelisable;
final int(0..1) intransaction;
final conxion c;
private string cancelsecret;
private int backendpid;
final int(-128..127) backendstatus;
final mapping(string:mixed) options;
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | private array(string) lastmessage = ({});
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final int(0..1) clearmessage;
final int(0..1) untolderror;
|
3d6e3c | 2020-02-22 | Stephen R. van den Berg | | final mixed delayederror;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | private mapping(string:array(mixed)) notifylist = ([]);
final mapping(string:string) runtimeparameter;
final mapping(string:mapping(string:mixed)) prepareds = ([]);
final int pportalcount;
final int totalhits;
final int msgsreceived;
final int bytesreceived;
final int warningsdropcount;
private int warningscollected;
final int(0..1) invalidatecache;
private Thread.Queue qportals;
|
aa8177 | 2018-01-26 | Stephen R. van den Berg | | final function (:void) readyforquery_cb;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | |
final string host;
final int(0..65535) port;
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | final string database, user, pass;
|
d921db | 2017-11-30 | Henrik Grubbström (Grubba) | | private Crypto.Hash.SCRAM SASLcontext;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final Thread.Condition waitforauthready;
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | final MUTEX shortmux;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final int readyforquerycount;
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected string _sprintf(int type) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | string res;
|
86b605 | 2021-04-14 | Stephen R. van den Berg | | if (!this)
|
9ef3d0 | 2021-05-02 | Stephen R. van den Berg | | return "(destructed)";
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | switch (type) {
case 'O':
res = sprintf(DRIVERNAME".proxy(%s@%s:%d/%s,%d,%d)",
|
81790f | 2017-11-28 | Stephen R. van den Berg | | user, host, port, database, c && c->socket && c->socket->query_fd(),
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | backendpid);
break;
}
return res;
}
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void create(void|string host, void|string database,
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | void|string user, void|string pass,
void|mapping(string:mixed) options) {
if (this::pass = pass) {
String.secure(pass);
pass = "CENSORED";
}
this::user = user;
this::database = database;
this::options = options;
if (!host) host = PGSQL_DEFAULT_HOST;
if (has_value(host,":") && sscanf(host,"%s:%d", host, port) != 2)
error("Error in parsing the hostname argument\n");
this::host = host;
if (!port)
port = PGSQL_DEFAULT_PORT;
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | register_backend(this);
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | shortmux = MUTEX();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("Connect\n");
waitforauthready = Thread.Condition();
qportals = Thread.Queue();
readyforquerycount = 1;
qportals->write(1);
if (!(c = conxion(this, qportals, 0)))
error("Couldn't connect to database on %s:%d\n", host, port);
runtimeparameter = ([]);
|
62f1ba | 2018-05-08 | Stephen R. van den Berg | | unnamedportalmux = MUTEX();
unnamedstatement = MUTEX();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | readyforquery_cb = connect_cb;
portalsinflight = Thread.ResourceCount();
statementsinflight = Thread.ResourceCount();
wasparallelisable = 0;
}
final int is_open() {
|
81790f | 2017-11-28 | Stephen R. van den Berg | | return c && c->socket && c->socket->is_open();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
final string geterror(void|int clear) {
untolderror = 0;
string s = lastmessage * "\n";
if (clear)
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | lastmessage = ({});
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | warningscollected = 0;
return sizeof(s) && s;
}
final string host_info() {
return sprintf("fd:%d TCP/IP %s:%d PID %d",
c ? c->socket->query_fd() : -1, host, port, backendpid);
}
final void cancelquery() {
if (cancelsecret > "") {
PD("CancelRequest\n");
conxion lcon = conxion(this, 0, 2);
#ifdef PG_DEBUG
mixed err =
#endif
catch(lcon->add_int32(16)->add_int32(PG_PROTOCOL(1234, 5678))
->add_int32(backendpid)->add(cancelsecret)->sendcmd(FLUSHSEND));
#ifdef PG_DEBUG
if (err)
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | PD("CancelRequest failed to connect %s\n", describe_backtrace(err));
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | #endif
destruct(lcon);
#ifdef PG_DEBUGMORE
PD("Closetrace %O\n", backtrace());
#endif
} else
error("Connection not established, cannot cancel any query\n");
}
private string a2nls(array(string) msg) {
return msg * "\n" + "\n";
}
private string pinpointerror(void|string query, void|string offset) {
if (!query)
return "";
int k = (int)offset;
if (k <= 0)
return MARKSTART + query + MARKEND;
return MARKSTART + (k > 1 ? query[..k-2] : "")
+ MARKERROR + query[k - 1..] + MARKEND;
}
private void connect_cb() {
PD("%O\n", runtimeparameter);
}
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | private array(string) showbindings(Result portal) {
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | return portal ? portal._showbindings() : ({});
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
private void preplastmessage(mapping(string:string) msgresponse) {
lastmessage = ({
sprintf("%s %s:%s %s\n (%s:%s:%s)",
msgresponse.S, msgresponse.C, msgresponse.P || "",
msgresponse.M, msgresponse.F || "", msgresponse.R || "",
msgresponse.L||"")});
}
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | private int|Result portal;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | private string datarowdebug;
private int datarowdebugcount;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | |
final void processloop(conxion ci) {
(c = ci)->socket->set_id(procmessage);
cancelsecret = 0;
portal = 0;
{
Stdio.Buffer plugbuffer = Stdio.Buffer()->add_int32(PG_PROTOCOL(3, 0));
if (user)
plugbuffer->add("user\0", user, 0);
if (database)
plugbuffer->add("database\0", database, 0);
foreach (options - censoroptions; string name; mixed value)
plugbuffer->add(name, 0, (string)value, 0);
plugbuffer->add_int8(0);
PD("%O\n", (string)plugbuffer);
void|bufcon|conxsess cs;
if (catch(cs = ci->start())) {
|
218ad9 | 2021-04-30 | Stephen R. van den Berg | | if (this) {
destruct(waitforauthready);
unnamedstatement = 0;
termlock = 1;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | return;
} else {
CHAIN(cs)->add_hstring(plugbuffer, 4, 4);
cs->sendcmd(SENDOUT);
}
}
procmessage();
}
|
d88b50 | 2020-06-09 | Stephen R. van den Berg | | private void stasherror(int|object portal, mixed err) {
if (stringp(err)) {
if (!objectp(portal))
portal = this;
if (!portal->delayederror)
portal->delayederror = err;
}
|
4c9e2e | 2021-04-09 | Stephen R. van den Berg | | if (objectp(portal) && portal->_purgeportal)
|
d88b50 | 2020-06-09 | Stephen R. van den Berg | | portal->_purgeportal();
}
private void tryprepbind(Result portal, array dtoid) {
mixed err = catch(portal->_preparebind(dtoid));
if (err) {
stasherror(portal, err);
if (!stringp(err))
throw(err);
}
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | private void procmessage() {
mixed err;
int terminating = 0;
err = catch {
|
bea3fb | 2018-05-26 | Stephen R. van den Berg | | conxion ci = c;
conxiin cr = ci->i;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("Processloop\n");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | void showportalstack(string label) {
PD(sprintf(">>>>>>>>>>> Portalstack %s: %O\n", label, portal));
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | foreach (qportals->peek_array(); ; int|Result qp)
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD(" =========== Portal: %O\n", qp);
PD("<<<<<<<<<<<<<< Portalstack end\n");
};
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | void showportal(int msgtype) {
if (objectp(portal))
PD("%d<%O %d %c switch portal\n",
ci->socket->query_fd(), portal._portalname, ++ci->queueinidx, msgtype);
|
e4ff9f | 2018-05-23 | Stephen R. van den Berg | | else if (portal > 0)
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%d<Sync %d %d %c portal\n",
ci->socket->query_fd(), ++ci->queueinidx, portal, msgtype);
};
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | int msgisfatal(mapping(string:string) msgresponse) {
|
aa8177 | 2018-01-26 | Stephen R. van den Berg | | int isfatal = (has_prefix(msgresponse.C, "53")
|| has_prefix(msgresponse.C, "3D")
|| has_prefix(msgresponse.C, "57P")) && MAGICTERMINATE;
if (isfatal && !terminating)
runcallback(backendpid, "_lost", "");
return isfatal;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | };
for (;;) {
err = catch {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!portal && datarowdebug) {
PD("%s rows %d\n", datarowdebug, datarowdebugcount);
datarowdebug = 0; datarowdebugcount = 0;
}
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
#ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportalstack("LOOPTOP");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (!sizeof(cr)) {
Thread.MutexKey lock = cr->fillreadmux->lock();
if (!sizeof(cr)) {
if (!cr->fillread) {
lock = 0;
throw(MAGICTERMINATE);
}
cr->procmsg = 1;
return;
}
}
int msgtype = cr->read_int8();
if (!portal) {
portal = qportals->try_read();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportal(msgtype);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
int msglen = cr->read_int32();
msgsreceived++;
bytesreceived += 1 + msglen;
int errtype = NOERROR;
PD("%d<", ci->socket->query_fd());
switch (msgtype) {
array getcols() {
int bintext = cr->read_int8();
int cols = cr->read_int16();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | array a;
msglen -= 4 + 1 + 2 + 2 * cols;
foreach (a = allocate(cols, ([])); ; mapping m)
m.type = cr->read_int16();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | cr->consume(cols << 1);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif // Discard column info, and make it line oriented
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | return ({ ({(["name":"line"])}), ({bintext?BYTEAOID:TEXTOID}) });
};
array(string) reads() {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (msglen < 1)
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
3d6cb0 | 2020-02-23 | Stephen R. van den Berg | | array ret = ({}), aw = ({0});
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | do {
string w = cr->read_cstring();
msglen -= sizeof(w) + 1; aw[0] = w; ret += aw;
} while (msglen);
return ret;
};
mapping(string:string) getresponse() {
mapping(string:string) msgresponse = ([]);
msglen -= 4;
foreach (reads(); ; string f)
if (sizeof(f))
msgresponse[f[..0]] = f[1..];
PD("%O\n", msgresponse);
return msgresponse;
};
case 'R': {
void authresponse(string|array msg) {
void|bufcon|conxsess cs = ci->start();
CHAIN(cs)->add_int8('p')->add_hstring(msg, 4, 4);
cs->sendcmd(SENDOUT);
};
PD("Authentication ");
msglen -= 4 + 4;
int authtype, k;
switch (authtype = cr->read_int32()) {
case 0:
PD("Ok\n");
if (SASLcontext) {
PD("Authentication validation still in progress\n");
errtype = PROTOCOLUNSUPPORTED;
} else
cancelsecret = "";
break;
case 2:
PD("KerberosV5\n");
errtype = PROTOCOLUNSUPPORTED;
break;
case 3:
PD("ClearTextPassword\n");
authresponse(({pass, 0}));
break;
case 4:
PD("CryptPassword\n");
errtype = PROTOCOLUNSUPPORTED;
break;
case 5:
PD("MD5Password\n");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (msglen < 4)
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
#define md5hex(x) String.string2hex(Crypto.MD5.hash(x))
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | authresponse(({"md5",
md5hex(md5hex(pass + user) + cr->read(msglen)), 0}));
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 6:
PD("SCMCredential\n");
errtype = PROTOCOLUNSUPPORTED;
break;
case 7:
PD("GSS\n");
errtype = PROTOCOLUNSUPPORTED;
break;
case 9:
PD("SSPI\n");
errtype = PROTOCOLUNSUPPORTED;
break;
case 8:
PD("GSSContinue\n");
errtype = PROTOCOLUNSUPPORTED;
cr->read(msglen);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (msglen<1)
errtype = PROTOCOLERROR;
msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 10: {
string word;
PD("AuthenticationSASL\n");
k = 0;
while (sizeof(word = cr->read_cstring())) {
switch (word) {
case "SCRAM-SHA-256":
k = 1;
}
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen -= sizeof(word) + 1;
if (msglen < 1)
break;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
if (k) {
|
d921db | 2017-11-30 | Henrik Grubbström (Grubba) | | SASLcontext = Crypto.SHA256.SCRAM();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | word = SASLcontext.client_1();
authresponse(({
"SCRAM-SHA-256", 0, sprintf("%4c", sizeof(word)), word
}));
} else
errtype = PROTOCOLUNSUPPORTED;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (msglen != 1)
errtype = PROTOCOLERROR;
msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
}
case 11: {
PD("AuthenticationSASLContinue\n");
string response;
if (response
= SASLcontext.client_2(cr->read(msglen), pass))
authresponse(response);
else
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
}
case 12:
PD("AuthenticationSASLFinal\n");
if (SASLcontext.client_3(cr->read(msglen)))
SASLcontext = 0;
else
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
default:
PD("Unknown Authentication Method %c\n", authtype);
errtype = PROTOCOLUNSUPPORTED;
break;
}
switch (errtype) {
default:
case PROTOCOLUNSUPPORTED:
error("Unsupported authenticationmethod %c\n", authtype);
case NOERROR:
break;
}
break;
}
case 'K':
msglen -= 4 + 4; backendpid = cr->read_int32();
cancelsecret = cr->read(msglen);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("BackendKeyData %O\n", cancelsecret);
msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 'S': {
PD("ParameterStatus ");
msglen -= 4;
array(string) ts = reads();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (sizeof(ts) == 2) {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | runtimeparameter[ts[0]] = ts[1];
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%O=%O\n", ts[0], ts[1]);
} else
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
}
case '3':
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("CloseComplete\n");
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 'Z': {
backendstatus = cr->read_int8();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen -= 4 + 1;
PD("ReadyForQuery %c\n", backendstatus);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
#ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportalstack("READYFORQUERY");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | int keeplooking;
do
for (keeplooking = 0;
objectp(portal);
portal = qportals->read()) {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportal(msgtype);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (backendstatus == 'I' && intransaction
&& portal->transtype != TRANSEND)
keeplooking = 1;
portal->_purgeportal();
}
while (keeplooking && (portal = qportals->read()));
if (backendstatus == 'I')
intransaction = 0;
|
63fcae | 2017-11-22 | Stephen R. van den Berg | | foreach (qportals->peek_array(); ; Result qp) {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (objectp(qp) && qp._synctransact
&& qp._synctransact <= portal) {
PD("Checking portal %O %d<=%d\n",
qp._portalname, qp._synctransact, portal);
qp->_purgeportal();
}
}
portal = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportalstack("AFTER READYFORQUERY");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | readyforquerycount--;
|
6476a4 | 2020-05-12 | Stephen R. van den Berg | | function (:void) cb;
|
acc6dd | 2020-05-14 | Stephen R. van den Berg | | destruct(waitforauthready);
|
6476a4 | 2020-05-12 | Stephen R. van den Berg | | if (cb = readyforquery_cb)
readyforquery_cb = 0, cb();
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
}
case '1':
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("ParseComplete portal %O\n", portal);
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 't': {
array a;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | int cols = cr->read_int16();
PD("%O ParameterDescription %d values\n", portal._query, cols);
msglen -= 4 + 2 + 4 * cols;
a = cr->read_ints(cols, 4);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | a = cr->read_ints(cr->read_int16(), 4);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
#ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%O\n", a);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (portal._tprepared)
portal._tprepared.datatypeoid = a;
|
d88b50 | 2020-06-09 | Stephen R. van den Berg | | Thread.Thread(tryprepbind, portal, a);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
}
case 'T': {
array a, at;
int cols = cr->read_int16();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("RowDescription %d columns %O\n", cols, portal._query);
msglen -= 4 + 2;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | at = allocate(cols);
foreach (a = allocate(cols); int i; ) {
string s = cr->read_cstring();
mapping(string:mixed) res = (["name":s]);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen -= sizeof(s) + 1 + 4 + 2 + 4 + 2 + 4 + 2;
res.tableoid = cr->read_int32() || UNDEFINED;
res.tablecolattr = cr->read_int16() || UNDEFINED;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | cr->consume(6);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | at[i] = cr->read_int32();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | res.type = at[i];
{
int len = cr->read_sint(2);
res.length = len >= 0 ? len : "variable";
}
res.atttypmod = cr->read_int32();
res.formatcode = cr->read_int16();
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | cr->consume(8);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | a[i] = res;
}
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%O\n", a);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (portal._forcetext)
portal->_setrowdesc(a, at);
else {
portal->_processrowdesc(a, at);
portal = 0;
}
break;
}
case 'n': {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen -= 4;
PD("NoData %O\n", portal._query);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
0b714c | 2020-05-18 | Stephen R. van den Berg | | portal._fetchlimit = 0;
portal->_processrowdesc(({}), ({}));
portal = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
}
case 'H':
portal->_processrowdesc(@getcols());
PD("CopyOutResponse %O\n", portal. _query);
break;
case '2': {
mapping tp;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen -= 4;
PD("%O BindComplete\n", portal._portalname);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (tp = portal._tprepared) {
int tend = gethrtime();
int tstart = tp.trun;
if (tend == tstart)
m_delete(prepareds, portal._query);
else {
tp.hits++;
totalhits++;
if (!tp.preparedname) {
if (sizeof(portal._preparedname)) {
PD("Finalising stored statement %s\n",
portal._preparedname);
tp.preparedname = portal._preparedname;
}
tstart = tend - tstart;
if (!tp.tparse || tp.tparse>tstart)
tp.tparse = tstart;
}
tp.trunstart = tend;
}
}
break;
}
case 'D':
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
#ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%O DataRow %d bytes\n", portal._portalname, msglen);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | datarowdebugcount++;
if (!datarowdebug)
datarowdebug = sprintf(
"%O DataRow %d bytes", portal._portalname, msglen);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
#ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen=
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | portal->_decodedata(msglen, runtimeparameter[CLIENT_ENCODING]);
break;
case 's':
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%O PortalSuspended\n", portal._portalname);
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | portal = 0;
break;
case 'C': {
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (msglen < 1)
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | string s = cr->read(msglen - 1);
|
6476a4 | 2020-05-12 | Stephen R. van den Berg | | PD("%O CommandComplete %O\n",
objectp(portal) && portal._portalname, s);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (cr->read_int8())
errtype = PROTOCOLERROR;
msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #else
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | cr->consume(1);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
#ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportalstack("COMMANDCOMPLETE");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
6476a4 | 2020-05-12 | Stephen R. van den Berg | | if (!portal._forcetext) {
portal->_storetiming();
portal->_releasesession(s);
portal = 0;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
}
case 'I':
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("EmptyQueryResponse %O\n", portal._portalname);
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
#ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportalstack("EMPTYQUERYRESPONSE");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
6476a4 | 2020-05-12 | Stephen R. van den Berg | | if (!portal._forcetext) {
portal->_releasesession();
portal = 0;
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 'd':
PD("%O CopyData\n", portal._portalname);
portal->_storetiming();
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (msglen < 0)
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | portal->_processdataready(({cr->read(msglen)}), msglen);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 'G':
portal->_releasestatement();
portal->_setrowdesc(@getcols());
PD("%O CopyInResponse\n", portal._portalname);
portal._state = COPYINPROGRESS;
break;
case 'c':
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | PD("%O CopyDone\n", portal._portalname);
msglen -= 4;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
6476a4 | 2020-05-12 | Stephen R. van den Berg | | if (!portal._forcetext)
portal = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | break;
case 'E': {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportalstack("ERRORRESPONSE");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (portalsinflight->drained() && !readyforquerycount)
sendsync();
PD("%O ErrorResponse %O\n",
objectp(portal) && (portal._portalname || portal._preparedname),
objectp(portal) && portal._query);
mapping(string:string) msgresponse;
msgresponse = getresponse();
warningsdropcount += warningscollected;
warningscollected = 0;
untolderror = 1;
switch (msgresponse.C) {
case "P0001":
lastmessage
= ({sprintf("%s: %s", msgresponse.S, msgresponse.M)});
USERERROR(a2nls(lastmessage
+({pinpointerror(portal._query, msgresponse.P)})
+showbindings(portal)));
case "53000":case "53100":case "53200":case "53300":case "53400":
case "57P01":case "57P02":case "57P03":case "57P04":case "3D000":
|
0e133b | 2020-01-20 | Stephen R. van den Berg | | case "34000":case "08P01":
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | preplastmessage(msgresponse);
PD(a2nls(lastmessage)); throw(msgisfatal(msgresponse));
|
0e133b | 2020-01-20 | Stephen R. van den Berg | | case "42P05":
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | errtype = PROTOCOLERROR;
case "XX000":case "42883":case "42P01":
invalidatecache = 1;
default:
preplastmessage(msgresponse);
if (msgresponse.D)
lastmessage += ({msgresponse.D});
if (msgresponse.H)
lastmessage += ({msgresponse.H});
lastmessage += ({
pinpointerror(objectp(portal) && portal._query, msgresponse.P)
+ pinpointerror(msgresponse.q, msgresponse.p)});
if (msgresponse.W)
lastmessage += ({msgresponse.W});
if (objectp(portal))
lastmessage += showbindings(portal);
switch (msgresponse.S) {
case "PANIC":werror(a2nls(lastmessage));
}
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | case "25P02":
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | USERERROR(a2nls(lastmessage));
}
break;
}
case 'N': {
PD("NoticeResponse\n");
mapping(string:string) msgresponse = getresponse();
|
86ee0d | 2020-05-18 | Stephen R. van den Berg | | switch (msgresponse.C) {
default:
if (clearmessage) {
warningsdropcount += warningscollected;
clearmessage = warningscollected = 0;
lastmessage = ({});
}
warningscollected++;
lastmessage = ({sprintf("%s %s: %s",
msgresponse.S, msgresponse.C, msgresponse.M)});
int val;
if (val = msgisfatal(msgresponse)) {
preplastmessage(msgresponse);
PD(a2nls(lastmessage)); throw(val);
}
case "25P01":
break;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
break;
}
case 'A': {
PD("NotificationResponse\n");
msglen -= 4 + 4;
int pid = cr->read_int32();
string condition, extrainfo;
{
array(string) ts = reads();
switch (sizeof(ts)) {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #if PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | case 0:
errtype = PROTOCOLERROR;
break;
default:
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | case 2:
extrainfo = ts[1];
case 1:
condition = ts[0];
}
}
PD("%d %s\n%s\n", pid, condition, extrainfo);
runcallback(pid, condition, extrainfo);
break;
}
default:
if (msgtype != -1) {
string s;
PD("Unknown message received %c\n", msgtype);
s = cr->read(msglen -= 4); PD("%O\n", s);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | msglen = 0;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | errtype = PROTOCOLUNSUPPORTED;
} else {
lastmessage += ({
sprintf("Connection lost to database %s@%s:%d/%s %d\n",
user, host, port, database, backendpid)});
runcallback(backendpid, "_lost", "");
if (!waitforauthready)
throw(0);
USERERROR(a2nls(lastmessage));
}
break;
}
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (msglen)
errtype = PROTOCOLERROR;
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | {
string msg;
switch (errtype) {
case PROTOCOLUNSUPPORTED:
msg
= sprintf("Unsupported servermessage received %c\n", msgtype);
break;
case PROTOCOLERROR:
msg = sprintf("Protocol error with database %s", host_info());
break;
case NOERROR:
continue;
}
error(a2nls(lastmessage += ({msg})));
}
};
if (err == MAGICTERMINATE) {
catch {
void|bufcon|conxsess cs = ci->start();
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | CHAIN(cs)->add(PGSYNC)->add("X\0\0\0\4");
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | cs->sendcmd(SENDOUT);
};
terminating = 1;
err = 0;
} else if (stringp(err)) {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUGMORE
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportalstack("THROWN");
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
d88b50 | 2020-06-09 | Stephen R. van den Berg | | stasherror(portal, err);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | portal = 0;
if (!waitforauthready)
continue;
}
break;
}
PD("Closing database processloop %s\n", err ? describe_backtrace(err) : "");
delayederror = err;
if (objectp(portal)) {
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #ifdef PG_DEBUG
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | showportal(0);
|
6534f9 | 2018-01-20 | Stephen R. van den Berg | | #endif
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | portal->_purgeportal();
}
destruct(waitforauthready);
|
8e5eda | 2020-06-22 | Stephen R. van den Berg | | termlock = 1;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (err && !stringp(err))
throw(err);
};
catch {
|
8e5eda | 2020-06-22 | Stephen R. van den Berg | | unnamedstatement = 0;
termlock = 1;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (err) {
PD("Terminating processloop due to %s\n", describe_backtrace(err));
delayederror = err;
}
destruct(waitforauthready);
c->purge();
};
|
11b13b | 2014-08-16 | Martin Nilsson | | }
|
ecbab1 | 2008-07-27 | Stephen R. van den Berg | |
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | final void close() {
throwdelayederror(this);
|
81790f | 2017-11-28 | Stephen R. van den Berg | | {
|
cb81a8 | 2018-05-05 | Stephen R. van den Berg | | Thread.MutexKey lock;
|
8e5eda | 2020-06-22 | Stephen R. van den Berg | | if (unnamedstatement && !termlock)
|
81790f | 2017-11-28 | Stephen R. van den Berg | | termlock = unnamedstatement->lock(1);
|
cb81a8 | 2018-05-05 | Stephen R. van den Berg | | foreach (c->runningportals; Result result; )
|
433336 | 2020-05-28 | Stephen R. van den Berg | | if (result->_state < CLOSED)
catch(result->status_command_complete());
|
81790f | 2017-11-28 | Stephen R. van den Berg | | if (c)
c->close();
if (unnamedstatement)
lock = unnamedstatement->lock(1);
if (c)
c->purge();
}
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | destruct(waitforauthready);
}
|
83fabd | 2019-04-17 | Henrik Grubbström (Grubba) | | protected void _destruct() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | string errstring;
mixed err = catch(close());
|
3fbf57 | 2018-12-16 | Stephen R. van den Berg | | clients[this] = 0;
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if (untolderror) {
|
f5173f | 2021-04-13 | Stephen R. van den Berg | | catch {
lastmessage = filter(lastmessage, lambda(string val) {
return has_prefix(val, "ERROR ") || has_prefix(val, "FATAL "); });
if (err || (err = catch(errstring = geterror(1))))
werror(describe_backtrace(err));
else if (errstring && sizeof(errstring))
werror("%s\n", errstring);
};
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | }
}
|
aa8177 | 2018-01-26 | Stephen R. van den Berg | | final void sendsync() {
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | readyforquerycount++;
c->start()->sendcmd(SYNCSEND);
}
private void runcallback(int pid, string condition, string extrainfo) {
array cb;
|
aa8177 | 2018-01-26 | Stephen R. van den Berg | | if (condition == "_lost")
destruct(c);
|
f66d60 | 2017-11-18 | Stephen R. van den Berg | | if ((cb = notifylist[condition] || notifylist[""])
&& (pid != backendpid || sizeof(cb) > 1 && cb[1]))
callout(cb[0], 0, pid, condition, extrainfo, @cb[2..]);
}
private inline void closestatement(
bufcon|conxsess plugbuffer, string oldprep) {
closestatement(plugbuffer, oldprep);
}
|
e7c5c8 | 2014-11-24 | Stephen R. van den Berg | | };
|
63fcae | 2017-11-22 | Stephen R. van den Berg | |
#pragma deprecation_warnings
__deprecated__(program(Result)) sql_result =
(__deprecated__(program(Result)))Result;
|