Pre: flatten the representation of VALUES.

A single vec that's traversed in chunks is more efficient than multiple
vecs… and this ensures that each sub-vec is the same size.
This commit is contained in:
Richard Newman 2017-06-02 13:03:16 -07:00 committed by Richard Newman
parent 06bb8e99a7
commit 63574af7ac

View file

@ -157,9 +157,13 @@ pub enum TableOrSubquery {
pub enum Values { pub enum Values {
/// Like "VALUES (0, 1), (2, 3), ...". /// Like "VALUES (0, 1), (2, 3), ...".
Unnamed(Vec<Vec<TypedValue>>), /// The vector must be of a length that is a multiple of the given size.
Unnamed(usize, Vec<TypedValue>),
/// Like "SELECT 0 AS x, SELECT 0 AS y WHERE 0 UNION ALL VALUES (0, 1), (2, 3), ...". /// Like "SELECT 0 AS x, SELECT 0 AS y WHERE 0 UNION ALL VALUES (0, 1), (2, 3), ...".
Named(Vec<Variable>, Vec<Vec<TypedValue>>), /// The vector of values must be of a length that is a multiple of the length
/// of the vector of names.
Named(Vec<Variable>, Vec<TypedValue>),
} }
pub enum FromClause { pub enum FromClause {
@ -220,7 +224,13 @@ fn push_column(qb: &mut QueryBuilder, col: &Column) -> BuildQueryResult {
/// without producing an intermediate string sequence. /// without producing an intermediate string sequence.
macro_rules! interpose { macro_rules! interpose {
( $name: pat, $across: expr, $body: block, $inter: block ) => { ( $name: pat, $across: expr, $body: block, $inter: block ) => {
let mut seq = $across.iter(); interpose_iter!($name, $across.iter(), $body, $inter)
}
}
macro_rules! interpose_iter {
( $name: pat, $across: expr, $body: block, $inter: block ) => {
let mut seq = $across;
if let Some($name) = seq.next() { if let Some($name) = seq.next() {
$body; $body;
for $name in seq { for $name in seq {
@ -439,20 +449,20 @@ impl QueryFragment for Values {
} }
let values = match self { let values = match self {
&Values::Named(_, ref values) => values, &Values::Named(ref names, ref values) => values.chunks(names.len()),
&Values::Unnamed(ref values) => values, &Values::Unnamed(ref size, ref values) => values.chunks(*size),
}; };
out.push_sql("VALUES "); out.push_sql("VALUES ");
interpose!(outer, values, interpose_iter!(outer, values,
{ out.push_sql("("); { out.push_sql("(");
interpose!(inner, outer, interpose!(inner, outer,
{ out.push_typed_value(inner)? }, { out.push_typed_value(inner)? },
{ out.push_sql(", ") }); { out.push_sql(", ") });
out.push_sql(")"); out.push_sql(")");
}, },
{ out.push_sql(", ") }); { out.push_sql(", ") });
Ok(()) Ok(())
} }
} }