[freetds] Charset question

James K. Lowden jklowden at freetds.org
Sat Apr 15 11:40:39 EDT 2006


Frediano Ziglio wrote:
> 
> > Meanwhile, I tried to find the source your package was built from.  
> 
> http://packages.ubuntulinux.org/dapper/libs/libct3

Bingo!  I assume you saw this, and other parts:

+#ifdef HAVE_NL_LANGINFO
+       if ((s = nl_langinfo(CODESET))) {
+               if (locale->char_set) free(locale->char_set);
+               if (locale->client_charset) free(locale->client_charset);
+               locale->client_charset = strdup(s);
+               locale->char_set = strdup(s);
+       }
+       if ((s = nl_langinfo(D_T_FMT))) {
+               if (locale->date_fmt) free(locale->date_fmt);
+               locale->date_fmt = strdup(s);
+       }
+#endif

This lets LC_LANG & friends override locales.conf.  Another part of the
patch (to src/tds/mem.c) initializes client_charset from whatever came out
of locale.c.  

I think I recognize Steve's patch?  

Jack, your distibution includes a patch that derives the client character
set -- UTF-8 on your system -- from the locale set in libc (based on
environment variables).  We've discussed this recently here.  It appears
there are some unintended consequences.  But I have an easy suggestion,
see below.   

> Mainly debian package. I'm thinking about a merge for debian charset
> code before final 0.64... what do you think about ?

I don't think we should include it in 0.64.  It's too new.  This thread is
an example of why not.  

However, I do think Steve's patch goes in the right direction; I do think
FreeTDS should respond to nl_langinfo(3) by default.  I think we have to
look at how freetds.conf overrides the environment.  Normally I focus on
iconv issues; I hadn't thought about TDS 5.0 logins for a long time.  

Jack, you found that unsetting LC_LANG caused an ASCII login.  That leads
to two possibilities.  One, you could set your client for ISO 8859-1,
which is what Sybase calls iso_1.  I think that will fix your login
problem.  

The solution should be to do this in freetds.conf:

	[global] # or servername
		tds version = 5.0
		client charset = ISO-8859-1

That should work, but ISTR you tried that and it didn't.  Here's the
relevant code from login.c:

        /* use charset nearest to client or nothing */
        server_charset = NULL;
        if (!tds_dstr_isempty(&connection->server_charset))
                server_charset =
tds_dstr_cstr(&connection->server_charset);
        else
                server_charset =
tds_sybase_charset_name(tds_dstr_cstr(&connection->client_charset));
        if (!server_charset)
                server_charset = "";
        tds_put_login_string(tds, server_charset, TDS_MAX_LOGIN_STR_SZ);  
     /* charset */

So, clearly, if that freetds.conf entry doesn't override the environment,
then connection->server_charset is not null.  It will take a little work
to find out why.  But I think we're at least in the neighborhood.  

Regards, 

--jkl


More information about the FreeTDS mailing list