You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fixes 707: use sql.unnest instead of sql.join for bulk insert (getodk#771)
We use a function called insertMany to do bulk inserting of certain things including Form Fields, Submission Attachments, Comments, Audits, and Client Audits.
insertMany was using sql.join internally, but broke down in extreme cases such as a very large form with 25K fields. In such a form, we store ~10 columns about each form field, so sql.join was forming a query with 250,000 parameters that was too much. Slonik throws 'Maximum call stack size exceeded' due to a bug gajus/slonik#344. Even after solving that bug, it is not possible to execute sql query with 250K parameters in Postgresql because database supports only 65535 parameters.
Right way to insert bulk rows in postgresql is to use unnest function, for e.g:
INSERT INTO table (col1, col2)
SELECT * FROM
UNNEST($1, $2) as t
where $1 is an array of values for col1 and $2 is an array of values for col2.
Slonik has sql.unnest to implement similar query, e.g., when inserting 25K of 10-column form fields, it will have 10 parameters where each is a 25K length array of every value for that one column. The one caveat of using sql.unnest is that it takes a second required argument to list out the types of each column.
Most of the code in this PR is about modifying our frames to also define field types on any frame that needs to use insertMany. If field types are missing and insertMany is called anyway, there is a 500 Problem explaining that.
To summarize
- insertMany changed to use sql.unnest instead of sql.join.
- Frames that use insertMany must now also specify a fieldTypes array for the properties in that frame.
0 commit comments