Changeset: 5abe110d77bd for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5abe110d77bd
Modified Files:
clients/mapilib/mapi.c
clients/mapilib/mapi.h
clients/odbc/driver/SQLConnect.c
clients/odbc/driver/SQLExecute.c
clients/odbc/driver/SQLPrepare.c
sql/backends/monet5/sql_result.mx
sql/backends/monet5/sql_scenario.c
sql/server/sql_mvc.c
sql/server/sql_mvc.h
Branch: Aug2011
Log Message:
ODBC needs the declared size of columns in result sets.
This was implemented by adding a header to result sets giving this
information. But since only (for now) ODBC needs it, the header is
only added when the client asks for it explicitly (using a new "X"
command).
diffs (217 lines):
diff --git a/clients/mapilib/mapi.c b/clients/mapilib/mapi.c
--- a/clients/mapilib/mapi.c
+++ b/clients/mapilib/mapi.c
@@ -846,6 +846,8 @@ struct MapiColumn {
char *columnname;
char *columntype;
int columnlength;
+ int digits;
+ int scale;
};
/* information about bound columns */
@@ -3498,6 +3500,19 @@ mapi_setAutocommit(Mapi mid, int autocom
}
MapiMsg
+mapi_set_size_header(Mapi mid, int value)
+{
+ if (mid->languageId != LANG_SQL) {
+ mapi_setError(mid, "size header only supported in SQL",
"mapi_toggle_size_header", MERROR);
+ return MERROR;
+ }
+ if (value)
+ return mapi_Xcommand(mid, "sizeheader", "1");
+ else
+ return mapi_Xcommand(mid, "sizeheader", "0");
+}
+
+MapiMsg
mapi_trace(Mapi mid, int flag)
{
mapi_clrError(mid);
@@ -3804,6 +3819,16 @@ parse_header_line(MapiHdl hdl, char *lin
anchors[i] = NULL;
}
}
+ } else if (strcmp(tag, "typesizes") == 0) {
+ for (i = 0; i < n; i++) {
+ if (anchors[i]) {
+ char *p;
+ result->fields[i].digits = atoi(anchors[i]);
+ p = strchr(anchors[i], ' ');
+ if (p)
+ result->fields[i].scale = atoi(p + 1);
+ }
+ }
}
/* clean up */
@@ -5267,6 +5292,30 @@ mapi_get_len(MapiHdl hdl, int fnr)
return 0;
}
+int
+mapi_get_digits(MapiHdl hdl, int fnr)
+{
+ struct MapiResultSet *result;
+
+ mapi_hdl_check0(hdl, "mapi_get_digits");
+ if ((result = hdl->result) != 0 && fnr >= 0 && fnr < result->fieldcnt)
+ return result->fields[fnr].digits;
+ mapi_setError(hdl->mid, "Illegal field number", "mapi_get_digits",
MERROR);
+ return 0;
+}
+
+int
+mapi_get_scale(MapiHdl hdl, int fnr)
+{
+ struct MapiResultSet *result;
+
+ mapi_hdl_check0(hdl, "mapi_get_scale");
+ if ((result = hdl->result) != 0 && fnr >= 0 && fnr < result->fieldcnt)
+ return result->fields[fnr].scale;
+ mapi_setError(hdl->mid, "Illegal field number", "mapi_get_scale",
MERROR);
+ return 0;
+}
+
char *
mapi_get_query(MapiHdl hdl)
{
diff --git a/clients/mapilib/mapi.h b/clients/mapilib/mapi.h
--- a/clients/mapilib/mapi.h
+++ b/clients/mapilib/mapi.h
@@ -165,6 +165,7 @@ mapi_export int mapi_get_trace(Mapi mid)
mapi_export int mapi_get_autocommit(Mapi mid);
mapi_export MapiMsg mapi_log(Mapi mid, const char *nme);
mapi_export MapiMsg mapi_setAutocommit(Mapi mid, int autocommit);
+mapi_export MapiMsg mapi_set_size_header(Mapi mid, int value);
mapi_export char *mapi_result_error(MapiHdl hdl);
mapi_export MapiMsg mapi_next_result(MapiHdl hdl);
mapi_export MapiMsg mapi_needmore(MapiHdl hdl);
@@ -232,6 +233,8 @@ mapi_export char *mapi_get_table(MapiHdl
mapi_export char *mapi_get_name(MapiHdl hdl, int fnr);
mapi_export char *mapi_get_type(MapiHdl hdl, int fnr);
mapi_export int mapi_get_len(MapiHdl hdl, int fnr);
+mapi_export int mapi_get_digits(MapiHdl hdl, int fnr);
+mapi_export int mapi_get_scale(MapiHdl hdl, int fnr);
mapi_export char *mapi_get_query(MapiHdl hdl);
mapi_export int mapi_get_querytype(MapiHdl hdl);
mapi_export int mapi_get_tableid(MapiHdl hdl);
diff --git a/clients/odbc/driver/SQLConnect.c b/clients/odbc/driver/SQLConnect.c
--- a/clients/odbc/driver/SQLConnect.c
+++ b/clients/odbc/driver/SQLConnect.c
@@ -234,6 +234,7 @@ SQLConnect_(ODBCDbc *dbc,
dbc->dbname = schema ? strdup(schema) : NULL;
mapi_setAutocommit(mid, dbc->sql_attr_autocommit ==
SQL_AUTOCOMMIT_ON);
set_timezone(mid);
+ mapi_set_size_header(mid, 1);
}
return rc;
diff --git a/clients/odbc/driver/SQLExecute.c b/clients/odbc/driver/SQLExecute.c
--- a/clients/odbc/driver/SQLExecute.c
+++ b/clients/odbc/driver/SQLExecute.c
@@ -216,7 +216,8 @@ ODBCInitResult(ODBCStmt *stmt)
rec->sql_desc_base_table_name = (SQLCHAR *) strdup(s ? s : "");
rec->sql_desc_table_name = (SQLCHAR *) strdup(s ? s : "");
- rec->sql_desc_length = mapi_get_len(hdl, i);
+ if ((rec->sql_desc_length = mapi_get_digits(hdl, i)) == 0)
+ rec->sql_desc_length = mapi_get_len(hdl, i);
rec->sql_desc_local_type_name = (SQLCHAR *) strdup("");
rec->sql_desc_catalog_name = (SQLCHAR *) strdup("");
@@ -235,6 +236,11 @@ ODBCInitResult(ODBCStmt *stmt)
rec->sql_desc_length = ODBCLength(rec, SQL_DESC_LENGTH);
rec->sql_desc_display_size = ODBCLength(rec,
SQL_DESC_DISPLAY_SIZE);
rec->sql_desc_octet_length = ODBCLength(rec,
SQL_DESC_OCTET_LENGTH);
+ if (rec->sql_desc_length == 0) {
+ rec->sql_desc_length = SQL_NO_TOTAL;
+ rec->sql_desc_display_size = SQL_NO_TOTAL;
+ rec->sql_desc_octet_length = SQL_NO_TOTAL;
+ }
rec++;
}
diff --git a/clients/odbc/driver/SQLPrepare.c b/clients/odbc/driver/SQLPrepare.c
--- a/clients/odbc/driver/SQLPrepare.c
+++ b/clients/odbc/driver/SQLPrepare.c
@@ -257,6 +257,11 @@ SQLPrepare_(ODBCStmt *stmt,
rec->sql_desc_length = ODBCLength(rec, SQL_DESC_LENGTH);
rec->sql_desc_display_size = ODBCLength(rec,
SQL_DESC_DISPLAY_SIZE);
rec->sql_desc_octet_length = ODBCLength(rec,
SQL_DESC_OCTET_LENGTH);
+ if (rec->sql_desc_length == 0) {
+ rec->sql_desc_length = SQL_NO_TOTAL;
+ rec->sql_desc_display_size = SQL_NO_TOTAL;
+ rec->sql_desc_octet_length = SQL_NO_TOTAL;
+ }
}
/* update the internal state */
diff --git a/sql/backends/monet5/sql_result.mx
b/sql/backends/monet5/sql_result.mx
--- a/sql/backends/monet5/sql_result.mx
+++ b/sql/backends/monet5/sql_result.mx
@@ -1199,6 +1199,23 @@ mvc_export_head(mvc *m, stream *s, int r
if (mnstr_write(s, " # length\n", 10, 1) != 1)
return export_error(order);
+ if (m->sizeheader) {
+ if (mnstr_write(s, "% ", 2, 1) != 1)
+ return export_error(order);
+ for (i = 0; i < t->nr_cols; i++) {
+ res_col *c = t->cols + i;
+
+ if (mnstr_printf(s, "%u %u",
+ c->type.digits, c->type.scale) < 0)
+ return export_error(order);
+ if (i + 1 < t->nr_cols &&
+ mnstr_write(s, ",\t", 2, 1) != 1)
+ return export_error(order);
+ }
+ if (mnstr_write(s, " # typesizes\n", 13, 1) != 1)
+ return export_error(order);
+ }
+
if ( order)
BBPunfix(order->batCacheid);
return res;
diff --git a/sql/backends/monet5/sql_scenario.c
b/sql/backends/monet5/sql_scenario.c
--- a/sql/backends/monet5/sql_scenario.c
+++ b/sql/backends/monet5/sql_scenario.c
@@ -1208,6 +1208,12 @@ SQLparser(Client c)
in->pos = in->len; /* HACK: should use parsed
lenght */
return NULL;
}
+ if (strncmp(in->buf + in->pos, "sizeheader", 10) == 0) {
+ v = (int) strtol(in->buf + in->pos + 10, NULL, 10);
+ m->sizeheader = v != 0;
+ in->pos = in->len; /* HACK: should use parsed
lenght */
+ return NULL;
+ }
if( strncmp(in->buf + in->pos,"quit",4)==0 ) {
c->mode = FINISHING;
return NULL;
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -61,6 +61,8 @@ mvc_init(char *dbname, int debug, store_
m->caching = 0;
/* disable history */
m->history = 0;
+ /* disable size header */
+ m->sizeheader = 0;
mvc_trans(m);
s = m->session->schema = mvc_bind_schema(m, "sys");
assert(m->session->schema != NULL);
diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h
--- a/sql/server/sql_mvc.h
+++ b/sql/server/sql_mvc.h
@@ -105,6 +105,7 @@ typedef struct mvc {
int caching; /* cache current query ? */
int history; /* queries statistics are kept */
int reply_size; /* reply size */
+ int sizeheader; /* print size header in result set */
int debug;
char emode; /* execution mode */
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list