Skip to content

Commit 212a984

Browse files
ORDER BY clause push-down (#22)
* If possible, push order by clause to the remote server so that we get the ordered result set from the foreign server itself. * mention supported push downs in the docs.
1 parent 5119856 commit 212a984

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ Which would yield something like:
4747
the rowid option is required. As are the names key and value for the columns.
4848

4949

50+
## Pushdowning
51+
52+
#### ORDER BY push-down
53+
`etcd_fdw` now also supports order by push-down. If possible, push order by
54+
clause to the remote server so that we get the ordered result set from the
55+
foreign server itself.
56+
57+
#### LIMIT push-down
58+
`etcd_fdw` now also supports limit offset push-down. Wherever possible,
59+
perform LIMIT operations on the remote server.
60+
61+
5062
Usage
5163
-----
5264

src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use etcd_client::{Client, ConnectOptions, TlsOptions, Identity, Certificate, Error, DeleteOptions, GetOptions, KeyValue, PutOptions};
1+
use etcd_client::{Client, ConnectOptions, TlsOptions, Identity, Certificate, Error, DeleteOptions, GetOptions, KeyValue, PutOptions, SortTarget, SortOrder};
22
use std::time::Duration;
33
use pgrx::pg_sys::panic::ErrorReport;
44
use pgrx::PgSqlErrorCode;
@@ -86,6 +86,9 @@ pub enum EtcdFdwError {
8686
#[error("Invalid option '{0}' with value '{1}'")]
8787
InvalidOption(String, String),
8888

89+
#[error("Invalid sort field value '{0}'")]
90+
InvalidSortField(String),
91+
8992
#[error("{0}")]
9093
OptionsError(#[from] OptionsError),
9194
}
@@ -237,7 +240,7 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
237240
&mut self,
238241
_quals: &[Qual],
239242
columns: &[Column],
240-
_sorts: &[Sort],
243+
sort: &[Sort],
241244
limit: &Option<Limit>,
242245
options: &std::collections::HashMap<String, String>,
243246
) -> Result<(), EtcdFdwError> {
@@ -284,6 +287,30 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
284287
get_options = get_options.with_serializable();
285288
}
286289

290+
// XXX Support for WHERE clause push-downs is pending
291+
// etcd doesn't have anything like WHERE clause because it
292+
// a NOSQL database.
293+
// But may be we can still support some simple WHERE
294+
// conditions like '<', '>=', 'LIKE', '=' by mapping them
295+
// to key, range_end and prefix options.
296+
297+
// sort pushdown
298+
if let Some(first_sort) = sort.first() {
299+
let field_name = first_sort.field.to_ascii_uppercase();
300+
301+
if let Some(target) = SortTarget::from_str_name(&field_name) {
302+
let order = if first_sort.reversed {
303+
SortOrder::Descend
304+
} else {
305+
SortOrder::Ascend
306+
};
307+
308+
get_options = get_options.with_sort(target, order);
309+
} else {
310+
return Err(EtcdFdwError::InvalidSortField(first_sort.field.clone()));
311+
}
312+
}
313+
287314
// preference order : prefix > key_start > default "\0"
288315
// samllest possible valid key '\0'
289316
let key = prefix.clone()

0 commit comments

Comments
 (0)