odbc-api: `panicked at 'range end index ... out of range for slice of length ...'`
thread '<unnamed>' panicked at 'range end index 10084237 out of range for slice of length 10084230', ...\odbc-api-0.40.1\src\buffers\text_column.rs:230:13
Was also getting this at a lower value with a smaller insert when I was initiating TextColumn at 0,0
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 27 (8 by maintainers)
New way to insert bulk: https://docs.rs/odbc-api/latest/odbc_api/guide/index.html#columnar-bulk-inserts
Probably only somewhat easier.
0.42.0is a breaking release and but it closes a safety hole and is faster. Cheers, MarkusI will leave the issues open, until I feel I improved the accessability of that subject somewhat.
Since a lot of it is driver dependent it is hard to make definitiv statements, but in general these statements hold true.
65536. See this issue with SAP anywhere https://github.com/pacman82/odbc-api/issues/93Thanks for the feedback, by the way. It is helpful.
More questions than I can answer right now 😅 .
The most important thing to point out. These are bindings to the ODBC API. At some point they have to talk to a driver manager over a C interface. This crate tries to adhere to the zero overhead principle. So you should be able to write the best and fastest code you can. More specifically it doesn’t perform unnecessary copies of the payload data. This implies laying the data out in memory exactly as the C interface commands it. This is why
isizeshows up for the indicator values in this crate.You are not required to write unsafe code, but there are escape hatches for power users.
Columnaris not a type. It means the data is layed out in columns, rather than it being organized row by row. ODBC supports both, so this is something to clarify.Maybe it is due to it wrapping the ODBC C API? It is also lower level than you might be used to. You could read up on ODBC here: https://docs.microsoft.com/en-us/sql/odbc/reference/develop-app/developing-applications?view=sql-server-ver15
buffer_from_descriptionorColumnarAnyBuffer::buffer_from_descriptionfits this usecase. I would suggest deriving the buffer description from the value’s type. https://docs.rs/odbc-api/latest/odbc_api/buffers/struct.BufferDescription.htmlIMHO a common misconception is to model the input buffers after the DB schema, but in most use cases I would modell them after the appliaction input data. An example for illustration: if your input data does not contain any
NULLs the buffer does not need to support nullability` indpendent of the fact that the DB schema might.As I mentioned before, it clearly seems I need more documentation. Actually it is the other usecase (knowing the table scheme at compile time) which is not supported with specific features by this crate. So far any downstream artefacts
odbc2parquet,odbcsvorarrow-odbcdo not know anything about the shape of the data in advance. The first two also can perform inserts on generic user data (provided in the form of csv or parquet files) and insert that into the database (with schema information unknown at compile time).odbc2parquetwill be a tough read due to some optimzations and percularities of parquet. Theodbcsvsample linked above does very much what you want, with text input only though. It might be a good first iteration.Personally I would suggest you start like this:
TextRowSet(which is just a type alias forColumnarBuffer<TextRowSet>anyway)ColumnarAnyBuffer, but still matching every type toText.Speaking of your usecase. There does your input data come from? If it is all text stopping after
1.might be the best thing to do.Unless you are providing your own buffer implementation your code shoud have no need to interact with
TextColumndirectly. ATextColumnis a very low level class, which does not even know how many elements in holds. Just use the higher levelColumnarAnyBufferorTextRowSetbuffers. They will instantiate and manage theseTextColumns for you.You can test if my suggestions would work by just running the
odbcsvtool against your database. If it doesn’t work and panics please open a bug. My guess is though that the original error is caused by a misunderstanding of whatTextColumnis and how it works.Chunking currently works in this libray like this:
ColumnarBuffer(notTextColumn) with a chunk of data.Here is how row wise chunking is performed in the
odbcsvtool (a chunk is called ‘batch’ here):Here is actually an inefficiency of this crate hidden. It currently forces users to rebind the buffer in safe code. I am working on it, but this is likely fast enough, for now.
Hope this helps.
Cheers, Markus
FYI: The first argument in the constructor of
TextColumnrefers to the number of rows you can put into the buffer at once. Yet there should not even be a need to instantiate it manually, for just inserting values.