Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion crates/rupg-analyze/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ fn hex(bytes: &[u8], out: &mut String) {
}
}

/// A value as a list of its kind and its parts, or `null`. A float keeps its bits, and a `numeric` keeps the bytes of its binary form.
/// A value as a list of its kind and its parts, or `null`. A float keeps its bits, and a `numeric` and a `tsvector` keep the bytes of their binary form.
fn write_value(value: &Value, out: &mut String) {
match value {
Value::Null => out.push_str("null"),
Expand Down Expand Up @@ -426,6 +426,13 @@ fn write_value(value: &Value, out: &mut String) {
}
out.push_str("))");
}
Value::TsVector(lexemes) => {
let mut bytes = Vec::new();
rupg_types::tsvector_send(lexemes, &mut bytes);
out.push_str("(tsvector ");
hex(&bytes, out);
out.push(')');
}
Value::Range(range) => write_range(range, out),
Value::Multirange(ranges) => {
out.push_str("(multirange");
Expand Down Expand Up @@ -776,6 +783,12 @@ fn value_of(item: &Item) -> Result<Value> {
.map_err(|_| bad("the bytes of a numeric"))?;
Value::Numeric(value)
}
"tsvector" => {
let bytes = bytes_of(part(0)?)?;
let value = rupg_types::tsvector_recv(&mut Recv::new(&bytes))
.map_err(|_| bad("the bytes of a tsvector"))?;
Value::TsVector(value)
}
"oid" => Value::Oid(number(part(0)?)?),
"char" => Value::Char(number(part(0)?)?),
"text" => match parts.first() {
Expand Down Expand Up @@ -911,6 +924,13 @@ mod tests {
),
(Value::Range(Box::new(Range::empty())), oid::DATERANGE),
(Value::Multirange(Vec::new()), oid::INT4MULTIRANGE),
(Value::TsVector(Vec::new()), oid::TSVECTOR),
(
Value::TsVector(
rupg_types::tsvector_parse("'it''s':3A a b:1,2C").expect("tsvector"),
),
oid::TSVECTOR,
),
(
Value::Multirange(vec![
Range {
Expand Down
4 changes: 4 additions & 0 deletions crates/rupg-func/src/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ enum Family {
Range,
/// The multirange types, which compare as `multirange_cmp` does.
Multirange,
/// `tsvector`, which compares as `tsvector_cmp` does.
TsVector,
}

/// The family of a type, or `None` for a type that has no comparison here.
Expand Down Expand Up @@ -81,6 +83,7 @@ fn family(ty: u32) -> Option<Family> {
ty if builtin::range_subtype(ty).is_some() => Family::Range,
oid::ANYMULTIRANGE => Family::Multirange,
ty if builtin::multirange_range(ty).is_some() => Family::Multirange,
oid::TSVECTOR => Family::TsVector,
_ => match builtin::type_by_oid(ty) {
Some(row) if row.category == b'A' && row.elem != 0 => Family::Array,
_ => return None,
Expand Down Expand Up @@ -151,6 +154,7 @@ pub fn compare(left: u32, a: &Value, right: u32, b: &Value) -> Result<Ordering>
};
multirange::multirange_order(sub, x, y)?
}
(Value::TsVector(x), Value::TsVector(y)) => rupg_types::tsvector_cmp(x, y).cmp(&0),
_ => return Err(bad_value()),
})
}
Expand Down
8 changes: 8 additions & 0 deletions crates/rupg-func/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ pub fn output_supported(ty: u32) -> bool {
| oid::CIRCLE
| oid::PG_SNAPSHOT
| oid::TXID_SNAPSHOT
| oid::TSVECTOR
) || RegKind::from_oid(ty).is_some()
|| is_row_type(ty)
}
Expand Down Expand Up @@ -185,6 +186,10 @@ pub fn output(ty: u32, value: &Value, session: &dyn Session, out: &mut Vec<u8>)
if let Value::Record(record) = value {
return record_out(record, session, out);
}
if let Value::TsVector(lexemes) = value {
types::tsvector_deparse(lexemes, out);
return Ok(());
}
if let (Some(kind), Value::Bytea(v)) = (types::GeoKind::from_oid(ty), value) {
types::geo_out(kind, v, session.extra_float_digits(), out);
return Ok(());
Expand Down Expand Up @@ -518,6 +523,7 @@ fn input_value(
oid::NAME => Value::text(types::name_in(text)),
oid::INT2 => Value::Int2(types::int2_in(text)?),
oid::INT4 => Value::Int4(types::int4_in(text)?),
oid::TSVECTOR => Value::TsVector(types::tsvector_parse(text)?),
oid::INT8 => Value::Int8(types::int8_in(text)?),
oid::OID => Value::Oid(types::oid_in(text)?),
oid::MONEY => Value::Int8(types::cash_in(text)?),
Expand Down Expand Up @@ -774,6 +780,7 @@ fn receive_from(ty: u32, recv: &mut Recv<'_>, typmod: i32) -> std::result::Resul
oid::VARCHAR => Value::text(types::varchar_in(recv.text()?, typmod)?),
oid::BPCHAR => Value::text(types::bpchar_in(recv.text()?, typmod)?),
oid::OID => Value::Oid(recv.u32()?),
oid::TSVECTOR => Value::TsVector(types::tsvector_recv(recv)?),
ty if RegKind::from_oid(ty).is_some() => Value::Oid(recv.u32()?),
oid::JSON => Value::text(types::json_in(recv.text()?)?),
oid::JSONB => Value::Text(types::jsonb_recv(recv.rest())?),
Expand Down Expand Up @@ -883,6 +890,7 @@ pub fn send(ty: u32, value: &Value, out: &mut Vec<u8>) -> Result<()> {
(_, Value::Record(record)) => record_send(record, out)?,
(_, Value::Range(range)) => range_send(ty, range, out)?,
(_, Value::Multirange(ranges)) => multirange_send(ty, ranges, out)?,
(_, Value::TsVector(lexemes)) => types::tsvector_send(lexemes, out),
(_, Value::Null) => return Err(Error::internal("the send function got a null value")),
_ => return Err(not_yet(format!("binary output of type {}", type_name(ty)))),
}
Expand Down
2 changes: 2 additions & 0 deletions crates/rupg-func/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ mod snapshot;
mod srf;
mod stat;
mod text;
mod tsvector;
mod updatable;
mod zones;

Expand Down Expand Up @@ -280,6 +281,7 @@ fn by_src(src: &str) -> Option<Kernel> {
.or_else(|| network::by_src(src))
.or_else(|| range::by_src(src))
.or_else(|| multirange::by_src(src))
.or_else(|| tsvector::by_src(src))
.or_else(|| activity::by_src(src))
.or_else(|| replication::by_src(src))
.or_else(|| shared::by_src(src))
Expand Down
3 changes: 2 additions & 1 deletion crates/rupg-func/src/srf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! The set-returning functions that a query can call in `FROM` or in its target list: `generate_series` of the integer types, `unnest`, `generate_subscripts`, `string_to_table`, `regexp_matches`, `regexp_split_to_table`, `pg_options_to_table`, `aclexplode`, `range_minus_multi`, `multirange_unnest`, `multirange_minus_multi`, `pg_get_keywords`, `pg_show_all_settings`, `pg_stat_get_activity`, `pg_stat_get_backend_idset`, `pg_prepared_statement`, `pg_hba_file_rules`, `pg_ident_file_mappings`, the functions of the views of replication, of progress and of the prepared transactions, the functions of the statistics of the whole server that give rows, the functions of the views of asynchronous I/O, shared memory, extended statistics, replication origins, recovery, publications and cursors, and the functions of the views of the time zones.
//! The set-returning functions that a query can call in `FROM` or in its target list: `generate_series` of the integer types, `unnest`, `generate_subscripts`, `string_to_table`, `regexp_matches`, `regexp_split_to_table`, `pg_options_to_table`, `aclexplode`, `range_minus_multi`, `multirange_unnest`, `multirange_minus_multi`, `unnest` of a `tsvector`, `pg_get_keywords`, `pg_show_all_settings`, `pg_stat_get_activity`, `pg_stat_get_backend_idset`, `pg_prepared_statement`, `pg_hba_file_rules`, `pg_ident_file_mappings`, the functions of the views of replication, of progress and of the prepared transactions, the functions of the statistics of the whole server that give rows, the functions of the views of asynchronous I/O, shared memory, extended statistics, replication origins, recovery, publications and cursors, and the functions of the views of the time zones.
//!
//! A set kernel gives all the rows of the call at once, as a function of PostgreSQL in the materialize mode gives a tuplestore. Each row has one value for each column of the result: one value for a function of a scalar type, or one value for each `OUT` parameter.

Expand Down Expand Up @@ -34,6 +34,7 @@ pub fn set_kernel(func: u32) -> Option<SetKernel> {
"range_minus_multi" => crate::range::range_minus_multi,
"multirange_unnest" => crate::multirange::unnest,
"multirange_minus_multi" => crate::multirange::minus_multi,
"tsvector_unnest" => crate::tsvector::unnest,
"pg_get_keywords" => keywords,
"pg_get_wait_events" => wait_events,
"show_all_settings" => all_settings,
Expand Down
Loading
Loading