From ca9627e70852f6b2e835660df870fe3ab405882d Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sun, 1 Sep 2019 00:00:32 +0200 Subject: Initial import --- .../freetds/files/freetds-20080603-odbc-csa2.patch | 404 +++++++++++++++++++++ 1 file changed, 404 insertions(+) create mode 100644 dev-db/freetds/files/freetds-20080603-odbc-csa2.patch (limited to 'dev-db/freetds/files/freetds-20080603-odbc-csa2.patch') diff --git a/dev-db/freetds/files/freetds-20080603-odbc-csa2.patch b/dev-db/freetds/files/freetds-20080603-odbc-csa2.patch new file mode 100644 index 0000000..1615ddd --- /dev/null +++ b/dev-db/freetds/files/freetds-20080603-odbc-csa2.patch @@ -0,0 +1,404 @@ +diff -dPNur freetds/include/tds.h freetds-ds/include/tds.h +--- freetds/include/tds.h 2008-06-18 11:06:26.000000000 +0200 ++++ freetds-ds/include/tds.h 2008-07-02 22:10:03.000000000 +0200 +@@ -1009,6 +1009,7 @@ + TDS_INT *column_lenbind; + TDS_INT column_textpos; + TDS_INT column_text_sqlgetdatapos; ++ TDS_CHAR column_text_sqlputdatainfo; + + BCPCOLDATA *bcp_column_data; + /** +diff -dPNur freetds/src/odbc/odbc.c freetds-ds/src/odbc/odbc.c +--- freetds/src/odbc/odbc.c 2008-06-18 11:06:26.000000000 +0200 ++++ freetds-ds/src/odbc/odbc.c 2008-07-02 22:10:03.000000000 +0200 +@@ -4652,6 +4652,7 @@ + SQLLEN dummy_cb; + int nSybType; + ++ TDS_INT converted_column_cur_size; + int extra_bytes = 0; + + INIT_HSTMT; +@@ -4690,6 +4691,7 @@ + ODBC_RETURN(stmt, SQL_ERROR); + } + colinfo = tds->current_results->columns[icol - 1]; ++ converted_column_cur_size = colinfo->column_cur_size; + + if (colinfo->column_cur_size < 0) { + *pcbValue = SQL_NULL_DATA; +@@ -4715,7 +4717,7 @@ + if (is_blob_type(colinfo->column_type)) + src = ((TDSBLOB *) src)->textvalue; + +- if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) { ++ if (fCType == SQL_C_CHAR) { + TDS_CHAR buf[3]; + SQLLEN len; + +@@ -4758,40 +4760,15 @@ + } + } else { + nread = colinfo->column_text_sqlgetdatapos / 2; +- if (nread >= colinfo->column_cur_size) ++ ++ if (colinfo->column_text_sqlgetdatapos > 0 ++ && nread >= colinfo->column_cur_size) + ODBC_RETURN(stmt, SQL_NO_DATA); + } + + src += nread; + srclen = colinfo->column_cur_size - nread; +- break; +- default: +- if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size) +- ODBC_RETURN(stmt, SQL_NO_DATA); +- +- src += colinfo->column_text_sqlgetdatapos; +- srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos; +- +- } +- } else if (fCType == SQL_C_BINARY) { +- switch (nSybType) { +- case SYBCHAR: +- case SYBVARCHAR: +- case SYBTEXT: +- case XSYBCHAR: +- case XSYBVARCHAR: +- nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0; +- +- while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0')) +- nread++; +- +- nread += colinfo->column_text_sqlgetdatapos * 2; +- +- if (nread && nread >= colinfo->column_cur_size) +- ODBC_RETURN(stmt, SQL_NO_DATA); +- +- src += nread; +- srclen = colinfo->column_cur_size - nread; ++ converted_column_cur_size *= 2; + break; + default: + if (colinfo->column_text_sqlgetdatapos > 0 +@@ -4842,7 +4819,7 @@ + if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0) + ++colinfo->column_text_sqlgetdatapos; + +- if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) { /* not all read ?? */ ++ if (colinfo->column_text_sqlgetdatapos < converted_column_cur_size) { /* not all read ?? */ + odbc_errs_add(&stmt->errs, "01004", "String data, right truncated"); + ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO); + } +diff -dPNur freetds/src/odbc/prepare_query.c freetds-ds/src/odbc/prepare_query.c +--- freetds/src/odbc/prepare_query.c 2007-04-18 16:29:24.000000000 +0200 ++++ freetds-ds/src/odbc/prepare_query.c 2008-07-02 22:10:03.000000000 +0200 +@@ -275,21 +275,110 @@ + /* copy to destination */ + if (blob) { + TDS_CHAR *p; ++ int dest_type, src_type, sql_src_type, res; ++ CONV_RESULT ores; ++ TDS_DBC * dbc = stmt->dbc; ++ void *free_ptr = NULL; ++ int start = 0; ++ SQLPOINTER extradata = NULL; ++ SQLLEN extralen = 0; ++ ++ ++ dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type); ++ if (dest_type == TDS_FAIL) ++ return SQL_ERROR; ++ ++ /* get C type */ ++ sql_src_type = drec_apd->sql_desc_concise_type; ++ if (sql_src_type == SQL_C_DEFAULT) ++ sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type); ++ ++ /* test source type */ ++ /* TODO test intervals */ ++ src_type = odbc_c_to_server_type(sql_src_type); ++ if (src_type == TDS_FAIL) ++ return SQL_ERROR; ++ ++ if (sql_src_type == SQL_C_CHAR) { ++ switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) { ++ case SYBBINARY: ++ case SYBVARBINARY: ++ case XSYBBINARY: ++ case XSYBVARBINARY: ++ case SYBLONGBINARY: ++ case SYBIMAGE: ++ if (!*((char*)DataPtr+len-1)) ++ --len; ++ ++ if (!len) ++ return SQL_SUCCESS; ++ ++ if (curcol->column_cur_size > 0 ++ && curcol->column_text_sqlputdatainfo) { ++ TDS_CHAR data[2]; ++ data[0] = curcol->column_text_sqlputdatainfo; ++ data[1] = *(char*)DataPtr; ++ ++ res = tds_convert(dbc->env->tds_ctx, src_type, data, 2, dest_type, &ores); ++ if (res < 0) ++ return SQL_ERROR; ++ ++ extradata = ores.ib; ++ extralen = res; ++ ++ start = 1; ++ --len; ++ } ++ ++ if (len&1) { ++ --len; ++ curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len); ++ } ++ ++ res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr+start, len, dest_type, &ores); ++ if (res < 0) { ++ if (extradata) ++ free(extradata); ++ ++ return SQL_ERROR; ++ } ++ ++ DataPtr = free_ptr = ores.ib; ++ len = res; ++ break; ++ } ++ } + + if (blob->textvalue) +- p = (TDS_CHAR *) realloc(blob->textvalue, len + curcol->column_cur_size); ++ p = (TDS_CHAR *) realloc(blob->textvalue, len + extralen + curcol->column_cur_size); + else { + assert(curcol->column_cur_size == 0); +- p = (TDS_CHAR *) malloc(len); ++ p = (TDS_CHAR *) malloc(len + extralen); + } +- if (!p) ++ if (!p) { ++ if (free_ptr) ++ free(free_ptr); ++ if (extradata) ++ free(extradata); + return SQL_ERROR; ++ } + blob->textvalue = p; ++ if (extralen) { ++ memcpy(blob->textvalue + curcol->column_cur_size, extradata, extralen); ++ curcol->column_cur_size += extralen; ++ } + memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len); ++ ++ if (extradata) ++ free(extradata); ++ if (free_ptr) ++ free(free_ptr); + } else { + memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len); + } ++ + curcol->column_cur_size += len; ++ + if (blob && curcol->column_cur_size > curcol->column_size) + curcol->column_size = curcol->column_cur_size; + +diff -dPNur freetds/src/odbc/unittests/blob1.c freetds-ds/src/odbc/unittests/blob1.c +--- freetds/src/odbc/unittests/blob1.c 2008-01-12 01:14:11.000000000 +0100 ++++ freetds-ds/src/odbc/unittests/blob1.c 2008-07-02 22:09:28.000000000 +0200 +@@ -47,6 +47,16 @@ + buf[n] = 'a' + ((start+n) * step % ('z' - 'a' + 1)); + } + ++static void ++fill_hex(char *buf, size_t len, unsigned int start, unsigned int step) ++{ ++ size_t n; ++ ++ for (n = 0; n < len; ++n) ++ sprintf(buf + 2*n, "%2x", (unsigned int)('a' + ((start+n) * step % ('z' - 'a' + 1)))); ++} ++ ++ + static int + check_chars(const char *buf, size_t len, unsigned int start, unsigned int step) + { +@@ -60,6 +70,21 @@ + } + + static int ++check_hex(const char *buf, size_t len, unsigned int start, unsigned int step) ++{ ++ size_t n; ++ char symbol[3]; ++ ++ for (n = 0; n < len; ++n) { ++ sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1)))); ++ if (buf[n] != symbol[(start+n) % 2]) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static int + readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos) + { + SQLRETURN rcode; +@@ -93,6 +118,43 @@ + return rcode; + } + ++static int ++readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step) ++{ ++ SQLRETURN rcode = SQL_SUCCESS_WITH_INFO; ++ char buf[8192]; ++ SQLLEN len, total = 0; ++ int i = 0; ++ int check; ++ int bufsize; ++ ++ if (step%2) bufsize = sizeof(buf) - 1; ++ else bufsize = sizeof(buf); ++ ++ printf(">> readBlobAsChar field %d\n", pos); ++ while (rcode == SQL_SUCCESS_WITH_INFO) { ++ i++; ++ rcode = SQLGetData(stmth, pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len); ++ if (!SQL_SUCCEEDED(rcode) || len <= 0) ++ break; ++ if (len > (SQLLEN) bufsize) ++ len = (SQLLEN) bufsize - 1; ++ printf(">> step %d: %d bytes readed\n", i, (int) len); ++ ++ check = check_hex(buf, len, 2*987 + total, 25); ++ if (!check) { ++ fprintf(stderr, "Wrong buffer content\n"); ++ failed = 1; ++ } ++ total += len; ++ } ++ printf(">> total bytes read = %d \n", (int) total); ++ if (total != 20000) ++ failed = 1; ++ return rcode; ++} ++ ++ + int + main(int argc, char **argv) + { +@@ -106,12 +168,14 @@ + SQLLEN vind1; + char buf2[NBYTES]; + SQLLEN vind2; ++ char buf3[NBYTES*2 + 1]; ++ SQLLEN vind3; + int cnt = 2; + + use_odbc_version3 = 1; + Connect(); + +- Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b IMAGE, v INT )"); ++ Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b1 IMAGE, b2 IMAGE, v INT )"); + + /* Insert rows ... */ + +@@ -121,7 +185,7 @@ + rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt); + CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH"); + +- rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ? )", SQL_NTS); ++ rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare"); + + SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0); +@@ -133,9 +197,12 @@ + SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 3"); + +- SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0); ++ SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 4"); + ++ SQLBindParameter(m_hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0); ++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 5"); ++ + key = i; + vind0 = 0; + +@@ -144,6 +211,10 @@ + + fill_chars(buf2, NBYTES, 987, 25); + vind2 = SQL_LEN_DATA_AT_EXEC(NBYTES); ++ ++ memset(buf3, 0, sizeof(buf3)); ++ vind3 = SQL_LEN_DATA_AT_EXEC(2*NBYTES+1); ++ + + printf(">> insert... %d\n", i); + rcode = SQLExecute(m_hstmt); +@@ -155,10 +226,25 @@ + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH"); + printf(">> SQLParamData: ptr = %p rcode = %d\n", (void *) p, rcode); + if (rcode == SQL_NEED_DATA) { +- SQLRETURN rcode = SQLPutData(m_hstmt, p, NBYTES); ++ SQLRETURN rcode; ++ if (p == buf3) { ++ fill_hex(buf3, NBYTES, 987, 25); ++ ++ rcode = SQLPutData(m_hstmt, p, NBYTES - (i&1)); + +- CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH"); +- printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES); ++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH"); ++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1)); ++ ++ rcode = SQLPutData(m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1)); ++ ++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH"); ++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1)); ++ } else { ++ rcode = SQLPutData(m_hstmt, p, NBYTES); ++ ++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH"); ++ printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES); ++ } + } + } + +@@ -182,7 +268,7 @@ + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY"); + } + +- rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS); ++ rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare"); + + SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0); +@@ -192,7 +278,9 @@ + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 2"); + SQLBindCol(m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 3"); +- SQLBindCol(m_hstmt, 3, SQL_C_LONG, &key, 0, &vind0); ++ SQLBindCol(m_hstmt, 3, SQL_C_BINARY, NULL, 0, &vind3); ++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 4"); ++ SQLBindCol(m_hstmt, 4, SQL_C_LONG, &key, 0, &vind0); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 1"); + + vind0 = 0; +@@ -210,6 +298,8 @@ + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1"); + rcode = readBlob(m_hstmt, 2); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2"); ++ rcode = readBlobAsChar(m_hstmt, 3, i); ++ CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 3 as SQL_C_CHAR"); + + rcode = SQLCloseCursor(m_hstmt); + CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLCloseCursor StmtH"); -- cgit v1.2.3