question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

on linux, unicode parameters cannot be longer than 128

See original GitHub issue

I noticed the following when posting a query from linux using parameters:

If the parameter string is longer than 127 characters, pypyodbc will throw an error on row 1572 when trying this:

param_buffer.value = c_char_buf

It complains that c_char_buf is too large.

I checked: c_char_buf is created by UCS_buf() if parameter type is ‘u’ (unicode less than 255 characters):

c_char_buf = UCS_buf(param_val)
c_buf_len = len(c_char_buf)

UCS_buf(string) is defined to return encoding(utf-16-le) for linux, and return its argument for windows.

Thus on linux, due to 2 byte minimum char width for utf-16, the length of the byte array will be double the length of the underlying string.

As param_buffer.value size is defined as 255 no matter what platform, this leads to above error.

My fix was to double the buffer size for linux:

 if param_types[col_num][0] == 'u':
                sql_c_type = SQL_C_WCHAR
                sql_type = SQL_WVARCHAR 
                if sys.platform not in ('win32','cli'):
                          buf_size = 255 * 2 # double buffer size for linux                 
                else:
                         buf_size = 255
                ParameterBuffer = create_buffer_u(buf_size)   

Hope this helps someone.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
timjen3commented, May 31, 2018

An alternative that works for me is to pass encoded bytes as parameters. I’m working with SQL Server and pypyodbc 1.3.4.3

For example:

cursor = pypyodbc.connect(connection_string).cursor()
city= "Louisville".encode("utf-8", "ignore")[:32]
state = "KY".encode("utf-8", "ignore")[:2]
uid = "UID123".encode("utf-8", "ignore")[:16]
cursor.execute("UPDATE MyTable SET City=?, State=? WHERE Id=?", (city, state, uid))

I purposefully left the byte-trunacting in (ie: [:32]) because that works properly.

1reaction
dmfreemoncommented, Apr 12, 2018
Read more comments on GitHub >

github_iconTop Results From Across the Web

3 Using Unicode in Erlang
On such a system, a filename containing characters with code points from 128 through 255 can be named as plain ISO Latin-1 or...
Read more >
SQL and XML limits - IBM DB2 9.7 for Linux, UNIX, and Windows
For example, because the width of a UTF-8 character can range from 1 to 4 bytes, the character limit for an identifier in...
Read more >
Overcoming frustration: Correctly using unicode in python2
Sending the wrong value here will lead to a UnicodeError being thrown when the string contains non-ASCII characters. Note. There is one mitigating...
Read more >
Manage Unicode Characters in Data Using T-SQL - SQLShack
In this article, we'll give some valuable information on how to use Unicode in SQL Server and various problems that arise from the...
Read more >
perluniintro - Perl Unicode introduction - Perldoc Browser
Whether to call these extended grapheme clusters "characters" depends on your point of view. If you are a programmer, you probably would tend...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found