Skip to content

Commit

Permalink
Fix #3579: Unexpected end of row when setup diesel
Browse files Browse the repository at this point in the history
We use `PRAGMA table_info` for older versions of sqlite. This returns
fewer columns that `PRAGMA table_xinfo` which we use in newer versions
of sqlite, making the two code paths incompatbile with the `Queryable`
implementations. We instead now use `sql_query` with an implementation
of `QueryableByName` to return default values for the case of `PRAGMA table_info`.
  • Loading branch information
dsp committed Jul 25, 2023
1 parent 99c01cf commit 22b5608
Showing 1 changed file with 23 additions and 12 deletions.
35 changes: 23 additions & 12 deletions diesel_cli/src/infer_schema_internals/sqlite.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::error::Error;

use diesel::deserialize::{self, FromStaticSqlRow, Queryable};
use diesel::deserialize::{self, Queryable};
use diesel::dsl::sql;
use diesel::row::NamedRow;
use diesel::sqlite::Sqlite;
use diesel::*;

Expand Down Expand Up @@ -141,7 +142,10 @@ pub fn get_table_data(
} else {
format!("PRAGMA TABLE_INFO('{}')", &table.sql_name)
};
let mut result = sql::<pragma_table_info::SqlType>(&query).load(conn)?;

// See: https://github.com/diesel-rs/diesel/issues/3579 as to why we use a direct
// `sql_query` with `QueryableByName` instead of using `sql::<pragma_table_info::SqlType>`.
let mut result = sql_query(query).load::<ColumnInformation>(conn)?;
match column_sorting {
ColumnSorting::OrdinalPosition => {}
ColumnSorting::Name => {
Expand All @@ -153,16 +157,23 @@ pub fn get_table_data(
Ok(result)
}

impl<ST> Queryable<ST, Sqlite> for ColumnInformation
where
(i32, String, String, bool, Option<String>, bool, i32): FromStaticSqlRow<ST, Sqlite>,
{
type Row = (i32, String, String, bool, Option<String>, bool, i32);

fn build(row: Self::Row) -> deserialize::Result<Self> {
Ok(ColumnInformation::new(
row.1, row.2, None, !row.3, None, None,
))
impl QueryableByName<Sqlite> for ColumnInformation {
fn build<'a>(row: &impl NamedRow<'a, Sqlite>) -> deserialize::Result<Self> {
let column_name =
NamedRow::get::<diesel::dsl::SqlTypeOf<pragma_table_info::name>, _>(row, "name")?;
let type_name =
NamedRow::get::<diesel::dsl::SqlTypeOf<pragma_table_info::type_name>, _>(row, "type")?;
let notnull: bool =
NamedRow::get::<diesel::dsl::SqlTypeOf<pragma_table_info::notnull>, _>(row, "notnull")?;

Ok(Self {
column_name,
type_name,
type_schema: None,
nullable: !notnull,
max_length: None,
comment: None,
})
}
}

Expand Down

0 comments on commit 22b5608

Please sign in to comment.