Changeset: d947ddc7c002 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/d947ddc7c002
Modified Files:
sql/server/rel_select.c
Branch: label
Log Message:
merged with default
diffs (truncated from 4080 to 300 lines):
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -745,12 +745,23 @@ const char *mo_find_option(opt *set, int
void mo_free_options(opt *set, int setlen);
void mo_print_options(opt *set, int setlen);
int mo_system_config(opt **Set, int setlen);
+mparm mparm_enumerate(int i);
+bool mparm_is_core(mparm parm);
+const char *mparm_name(mparm parm);
mparm mparm_parse(const char *name);
+char *msetting_as_string(const msettings *mp, mparm parm);
bool msetting_bool(const msettings *mp, mparm parm);
long msetting_long(const msettings *mp, mparm parm);
+const char *msetting_parm_name(const msettings *mp, mparm parm);
+msettings_error msetting_parse(msettings *mp, mparm parm, const char *text);
int msetting_parse_bool(const char *text);
+msettings_error msetting_set_bool(msettings *mp, mparm parm, bool value);
+msettings_error msetting_set_ignored(msettings *mp, const char *key, const
char *value);
+msettings_error msetting_set_long(msettings *mp, mparm parm, long value);
msettings_error msetting_set_named(msettings *mp, bool allow_core, const char
*key, const char *value);
+msettings_error msetting_set_string(msettings *mp, mparm parm, const char
*value) __attribute__((__nonnull__(3)));
const char *msetting_string(const msettings *mp, mparm parm);
+msettings *msettings_clone(const msettings *mp);
long msettings_connect_binary(const msettings *mp);
const char *msettings_connect_certhash_digits(const msettings *mp);
const char *msettings_connect_clientcert(const msettings *mp);
@@ -761,8 +772,12 @@ const char *msettings_connect_tcp(const
enum msetting_tls_verify msettings_connect_tls_verify(const msettings *mp);
const char *msettings_connect_unix(const msettings *mp);
msettings *msettings_create(void);
+const msettings *msettings_default;
msettings *msettings_destroy(msettings *mp);
+bool msettings_malloc_failed(msettings_error err);
bool msettings_parse_url(msettings *mp, const char *url, char **error_buffer);
+void msettings_reset(msettings *mp);
+void msettings_set_localizer(msettings *mp, const char *(*localizer)(const
void *data, mparm parm), void *data);
bool msettings_validate(msettings *mp, char **errmsg);
const char *wsaerror(int);
diff --git a/clients/examples/C/testsfile.c b/clients/examples/C/testsfile.c
--- a/clients/examples/C/testsfile.c
+++ b/clients/examples/C/testsfile.c
@@ -85,7 +85,7 @@ handle_set_command(const char *location,
{
msettings_error msg = msetting_set_named(mp, true, key, value);
if (msg) {
- fprintf(stderr, "%s: cannot set '%s': %s\n", location, key,
msg);
+ fprintf(stderr, "%s: %s\n", location, msg);
return false;
}
return true;
diff --git a/clients/mapiclient/mclient.c b/clients/mapiclient/mclient.c
--- a/clients/mapiclient/mclient.c
+++ b/clients/mapiclient/mclient.c
@@ -174,7 +174,7 @@ static char *nullstring = default_nullst
static timertype
gettime(void)
{
- /* Return the time in milliseconds since an epoch. The epoch
+ /* Return the time in microseconds since an epoch. The epoch
is roughly the time this program started. */
#ifdef _MSC_VER
static LARGE_INTEGER freq, start; /* automatically initialized to
0 */
diff --git a/clients/mapilib/connect.c b/clients/mapilib/connect.c
--- a/clients/mapilib/connect.c
+++ b/clients/mapilib/connect.c
@@ -144,6 +144,17 @@ establish_connection(Mapi mid)
msg = mapi_handshake(mid);
}
+ // Switch from MP_CONNECT_TIMEOUT to MP_REPLY_TIMEOUT
+ if (msg == MOK) {
+ long connect_timeout = msetting_long(mid->settings,
MP_CONNECT_TIMEOUT);
+ long reply_timeout = msetting_long(mid->settings,
MP_REPLY_TIMEOUT);
+ if (connect_timeout > 0 || reply_timeout > 0) {
+ if (reply_timeout < 0)
+ reply_timeout = 0;
+ msg = mapi_timeout(mid, reply_timeout);
+ }
+ }
+
return msg;
}
@@ -153,6 +164,7 @@ connect_socket(Mapi mid)
assert(!mid->connected);
const char *sockname = msettings_connect_unix(mid->settings);
const char *tcp_host = msettings_connect_tcp(mid->settings);
+ long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT);
assert(*sockname || *tcp_host);
do {
@@ -165,6 +177,11 @@ connect_socket(Mapi mid)
return mid->error;
} while (0);
+ // the socket code may have set SO_SNDTIMEO and SO_RCVTIMEO but
+ // the mapi layer doesn't know this yet.
+ if (timeout > 0)
+ mapi_timeout(mid, timeout);
+
mid->connected = true;
return MOK;
}
@@ -293,6 +310,8 @@ connect_socket_tcp(Mapi mid)
static SOCKET
connect_socket_tcp_addr(Mapi mid, struct addrinfo *info)
{
+ long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT);
+
if (mid->tracelog) {
char addrbuf[100] = {0};
const char *addrtext;
@@ -311,7 +330,7 @@ connect_socket_tcp_addr(Mapi mid, struct
port = -1;
addrtext = NULL;
}
- mapi_log_record(mid, "CONN", "Trying IP %s port %d", addrtext ?
addrtext : "<UNKNOWN>", port);
+ mapi_log_record(mid, "CONN", "Trying IP %s port %d wih timeout
%ld", addrtext ? addrtext : "<UNKNOWN>", port, timeout);
}
@@ -332,6 +351,23 @@ connect_socket_tcp_addr(Mapi mid, struct
(void) fcntl(s, F_SETFD, FD_CLOEXEC);
#endif
+ if (timeout > 0) {
+ struct timeval tv = {
+ .tv_sec = timeout / 1000,
+ .tv_usec = timeout % 1000,
+ };
+ /* cast to char * for Windows, no harm on "normal" systems */
+ if (
+ setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv,
sizeof(tv)) == SOCKET_ERROR
+ || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv,
sizeof(tv)) == SOCKET_ERROR
+ ) {
+ closesocket(s);
+ return mapi_printError(
+ mid, __func__, MERROR,
+ "could not set connect timeout: %s",
strerror(errno));
+ }
+ }
+
// cast addrlen to int to satisfy Windows.
if (connect(s, info->ai_addr, (int)info->ai_addrlen) == SOCKET_ERROR) {
mapi_printError(
diff --git a/clients/mapilib/connect_unix.c b/clients/mapilib/connect_unix.c
--- a/clients/mapilib/connect_unix.c
+++ b/clients/mapilib/connect_unix.c
@@ -130,15 +130,16 @@ connect_socket_unix(Mapi mid)
{
const char *sockname = msettings_connect_unix(mid->settings);
assert (*sockname != '\0');
+ long timeout = msetting_long(mid->settings, MP_CONNECT_TIMEOUT);
- mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s",
sockname);
+ mapi_log_record(mid, "CONN", "Connecting to Unix domain socket %s with
timeout %ld", sockname, timeout);
struct sockaddr_un userver;
if (strlen(sockname) >= sizeof(userver.sun_path)) {
return mapi_printError(mid, __func__, MERROR, "path name '%s'
too long", sockname);
}
- // Create the socket, taking care of CLOEXEC
+ // Create the socket, taking care of CLOEXEC and SNDTIMEO
#ifdef SOCK_CLOEXEC
int s = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
@@ -154,6 +155,22 @@ connect_socket_unix(Mapi mid)
(void) fcntl(s, F_SETFD, FD_CLOEXEC);
#endif
+ if (timeout > 0) {
+ struct timeval tv = {
+ .tv_sec = timeout / 1000,
+ .tv_usec = timeout % 1000,
+ };
+ if (
+ setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv))
== SOCKET_ERROR
+ || setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv,
sizeof(tv)) == SOCKET_ERROR
+ ) {
+ closesocket(s);
+ return mapi_printError(
+ mid, __func__, MERROR,
+ "could not set connect timeout: %s",
strerror(errno));
+ }
+ }
+
// Attempt to connect
userver = (struct sockaddr_un) {
diff --git a/clients/mapilib/msettings.c b/clients/mapilib/msettings.c
--- a/clients/mapilib/msettings.c
+++ b/clients/mapilib/msettings.c
@@ -13,6 +13,7 @@
#include "monetdb_config.h"
#include "msettings.h"
+#include "mstring.h"
#include <assert.h>
#include <ctype.h>
@@ -25,7 +26,17 @@
#include <strings.h>
#endif
-#define FATAL() do { fprintf(stderr, "\n\n abort in params.c: %s\n\n",
__func__); abort(); } while (0)
+#define FATAL() do { fprintf(stderr, "\n\n abort in msettings.c: %s\n\n",
__func__); abort(); } while (0)
+
+static const char * const MALLOC_FAILED = "malloc failed";
+
+bool
+msettings_malloc_failed(msettings_error err)
+{
+ return ((const char*)err == (const char*)MALLOC_FAILED);
+}
+
+
int msetting_parse_bool(const char *text)
{
@@ -49,22 +60,19 @@ char* allocprintf(const char *fmt, ...)
char *
allocprintf(const char *fmt, ...)
{
- size_t buflen = 80;
- while (1) {
- char *buf = malloc(buflen);
- if (buf == NULL)
- return NULL;
- va_list ap;
- va_start(ap, fmt);
- int n = vsnprintf(buf, buflen, fmt, ap);
- va_end(ap);
- if (n >= 0 && (size_t)n < buflen)
- return buf;
- free(buf);
- if (n < 0)
- return NULL;
- buflen = n + 1;
- }
+ va_list ap;
+ char *buf = NULL;
+ size_t pos = 0, cap = 0;
+ int n;
+
+ va_start(ap, fmt);
+ n = vreallocprintf(&buf, &pos, &cap, fmt, ap);
+ va_end(ap);
+
+ if (n >= 0)
+ return buf;
+ free(buf);
+ return NULL;
}
@@ -78,12 +86,15 @@ by_name[] = {
{ .name="certhash", .parm=MP_CERTHASH },
{ .name="clientcert", .parm=MP_CLIENTCERT },
{ .name="clientkey", .parm=MP_CLIENTKEY },
+ { .name="connect_timeout", .parm=MP_CONNECT_TIMEOUT },
{ .name="database", .parm=MP_DATABASE },
{ .name="host", .parm=MP_HOST },
{ .name="language", .parm=MP_LANGUAGE },
+ { .name="map_to_long_varchar", .parm=MP_MAPTOLONGVARCHAR },
{ .name="password", .parm=MP_PASSWORD },
{ .name="port", .parm=MP_PORT },
{ .name="replysize", .parm=MP_REPLYSIZE },
+ { .name="reply_timeout", .parm=MP_REPLY_TIMEOUT },
{ .name="fetchsize", .parm=MP_REPLYSIZE },
{ .name="schema", .parm=MP_SCHEMA },
{ .name="sock", .parm=MP_SOCK },
@@ -94,9 +105,10 @@ by_name[] = {
{ .name="tls", .parm=MP_TLS },
{ .name="user", .parm=MP_USER },
//
+ { .name="logfile", .parm=MP_LOGFILE },
+ //
{ .name="hash", .parm=MP_IGNORE },
{ .name="debug", .parm=MP_IGNORE },
- { .name="logfile", .parm=MP_IGNORE },
};
mparm
@@ -111,6 +123,15 @@ mparm_parse(const char *name)
return strchr(name, '_') ? MP_IGNORE : MP_UNKNOWN;
}
+mparm
+mparm_enumerate(int i)
+{
+ int n = sizeof(by_name) / sizeof(by_name[0]);
+ if (i < 0 || i >= n)
+ return MP_UNKNOWN;
+ return by_name[i].parm;
+}
+
const char *
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]