[PATCH] reorder charset handlling in tsql (Re: SQL Server version and TDS Version)
"Craig A. Berry" <[email protected]>
| Newsgroups | gmane.comp.db.tds.freetds |
|---|---|
| Message-ID | <[email protected]> |
On Apr 29, 2010, at 11:02 PM, Craig A. Berry wrote: > I think the right fix is going to be to reorder things in tsql.c so > it only puts a charset in the login structure when the user > specifies one explicitly on the command line or, as a last chance, > puts the charset in the connection structure if it's empty after the > call to tds_read_config_info(). And that's what I've done in the attached patch. Specifically, 1.) Implement the -J command-line option (lifted directly from the Sybase documentation) to explicitly set the client charset. This is now the only case where tsql will set the charset before reading configuration info, and we know from recent experience that this trumps what's in freetds.conf. 2.) If and only if reading configuration info fails to set the client charset (which I think is unlikely since it apparently chooses its own default), tsql will set it to the charset read from locale_charset() or nl_langinfo(). If it wasn't able to get a charset from the locale, it will hardwire it to ISO-8859-1. There is a new line of output showing the default charset actually being used, which is now somewhat less likely to be the locale charset. This output could of course be suppressed in cases where they are the same: % ./src/apps/tsql -Usomeuser -Smyserver Password: locale is "C" locale charset is "US-ASCII" using default charset "ISO-8859-1" 1> My assumption throughout is that the TDS library already knows how to pick a charset and the application should defer to it unless there is good reason to explicitly override it, which we now have the ability to do. Most likely the old logic using locale charset in tsql.c predates all of the advanced charset handling in src/tds/iconv.c ________________________________________ Craig A. Berry mailto:[email protected] "... getting out of a sonnet is much more difficult than getting in." Brad Leithauser _______________________________________________ FreeTDS mailing list [email protected] http://lists.ibiblio.org/mailman/listinfo/freetds
tsql_charset.patch
(application/octet-stream, 4 KB)
Index: src/apps/tsql.c
===================================================================
RCS file: /cvsroot/freetds/freetds/src/apps/tsql.c,v
retrieving revision 1.133
diff -p -u -r1.133 tsql.c
--- src/apps/tsql.c 8 Apr 2010 08:19:16 -0000 1.133
+++ src/apps/tsql.c 30 Apr 2010 15:17:57 -0000
@@ -297,7 +297,8 @@ static void
tsql_print_usage(const char *progname)
{
fprintf(stderr,
- "Usage:\t%s [-S <server> | -H <hostname> -p <port>] -U <username> [-P <password>] [-I <config file>] [-o <options>] [-t delim] [-r delim] [-D database]\n"
+ "Usage:\t%s [-S <server> | -H <hostname> -p <port>] -U <username> [-P <password>]\n"
+ "\t\t[-I <config file>] [-J <client charset>] [-o <options>] [-t delim] [-r delim] [-D database]\n"
"\t%s -C\n"
"Options:\n"
"\tf\tDo not print footer\n"
@@ -402,23 +403,10 @@ populate_login(TDSLOGIN * login, int arg
char *confile = NULL;
int port = 0;
int opt;
- const char *locale = NULL;
const char *charset = NULL;
char *opt_flags_str = NULL;
- setlocale(LC_ALL, "");
- locale = setlocale(LC_ALL, NULL);
-
-#if HAVE_LOCALE_CHARSET
- charset = locale_charset();
-#endif
-#if HAVE_NL_LANGINFO && defined(CODESET)
- if (!charset)
- charset = nl_langinfo(CODESET);
-#endif
-
-
- while ((opt = getopt(argc, argv, "H:S:I:P:U:p:Co:t:r:D:Lv")) != -1) {
+ while ((opt = getopt(argc, argv, "H:S:I:J:P:U:p:Co:t:r:D:Lv")) != -1) {
switch (opt) {
case 't':
opt_col_term = strdup(optarg);
@@ -452,6 +440,9 @@ populate_login(TDSLOGIN * login, int arg
free(confile);
confile = strdup(optarg);
break;
+ case 'J':
+ charset = strdup(optarg);
+ break;
case 'p':
port = atoi(optarg);
break;
@@ -495,16 +486,6 @@ populate_login(TDSLOGIN * login, int arg
}
}
-
- if (locale)
- if (!QUIET) printf("locale is \"%s\"\n", locale);
- if (charset) {
- if (!QUIET) printf("locale charset is \"%s\"\n", charset);
- } else {
- charset = "ISO-8859-1";
- if (!QUIET) printf("using default charset \"%s\"\n", charset);
- }
-
if ((global_opt_flags & OPT_INSTANCES) && hostname) {
static const char template[] = "%s.instances";
char ip[24] = {'\0'};
@@ -582,7 +563,7 @@ populate_login(TDSLOGIN * login, int arg
tds_set_app(login, "TSQL");
tds_set_library(login, "TDS-Library");
tds_set_server(login, servername);
- tds_set_client_charset(login, charset);
+ if (charset) tds_set_client_charset(login, charset);
tds_set_language(login, "us_english");
tds_set_passwd(login, password);
if (confile) {
@@ -595,7 +576,7 @@ populate_login(TDSLOGIN * login, int arg
tds_set_library(login, "TDS-Library");
tds_set_server(login, hostname);
tds_set_port(login, port);
- tds_set_client_charset(login, charset);
+ if (charset) tds_set_client_charset(login, charset);
tds_set_language(login, "us_english");
tds_set_passwd(login, password);
}
@@ -681,6 +662,8 @@ main(int argc, char **argv)
pid_t timer_pid = 0;
int pipes[2];
#endif
+ const char *locale = NULL;
+ const char *charset = NULL;
istty = isatty(0);
@@ -710,6 +693,32 @@ main(int argc, char **argv)
tds_set_parent(tds, NULL);
connection = tds_read_config_info(tds, login, context->locale);
+ setlocale(LC_ALL, "");
+ locale = setlocale(LC_ALL, NULL);
+
+#if HAVE_LOCALE_CHARSET
+ charset = locale_charset();
+#endif
+#if HAVE_NL_LANGINFO && defined(CODESET)
+ if (!charset)
+ charset = nl_langinfo(CODESET);
+#endif
+
+ if (locale)
+ if (!QUIET) printf("locale is \"%s\"\n", locale);
+ if (charset) {
+ if (!QUIET) printf("locale charset is \"%s\"\n", charset);
+ }
+
+ if (tds_dstr_isempty(&connection->client_charset)) {
+ if (!charset)
+ charset = "ISO-8859-1";
+
+ tds_set_client_charset(login, charset);
+ tds_dstr_dup(&connection->client_charset, &login->client_charset);
+ }
+ if (!QUIET) printf("using default charset \"%s\"\n", tds_dstr_cstr(&connection->client_charset));
+
if (opt_default_db) {
tds_dstr_copy(&connection->database, opt_default_db);
if (!QUIET) fprintf(stderr, "Default database being set to %s\n", opt_default_db);