Skip to content

Commit a1a7c64

Browse files
Tümay Tuzcusuchapalaver
authored andcommitted
store: Use double quotation format for parsed sql tables matched with prelude CTE
Fixes SQL-266 Signed-off-by: Tümay Tuzcu <[email protected]>
1 parent ee44541 commit a1a7c64

File tree

2 files changed

+39
-16
lines changed

2 files changed

+39
-16
lines changed

store/postgres/src/sql/formatter.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,29 @@
11
use sqlparser::ast::{ObjectName, Statement, TableFactor, VisitMut, VisitorMut};
22
use std::ops::ControlFlow;
33

4+
use super::Schema;
5+
46
pub struct Formatter<'a> {
57
prelude: &'a str,
8+
schema: &'a Schema,
69
}
710

811
impl<'a> Formatter<'a> {
9-
pub fn new(prelude: &'a str) -> Self {
10-
Self { prelude }
12+
pub fn new(prelude: &'a str, schema: &'a Schema) -> Self {
13+
Self { prelude, schema }
1114
}
1215

1316
fn prepend_prefix_to_object_name_mut(&self, name: &mut ObjectName) {
14-
let table_identifier: &mut Vec<_> = &mut name.0;
17+
let table_identifier = &mut name.0;
1518
// remove all but the last identifier
1619
table_identifier.drain(0..table_identifier.len() - 1);
20+
21+
// Ensure schema tables has quotation to match up with prelude generated cte.
22+
if let Some(table_name) = table_identifier.last_mut() {
23+
if self.schema.contains_key(&table_name.value) {
24+
table_name.quote_style = Some('"');
25+
}
26+
}
1727
}
1828

1929
pub fn format(&mut self, statement: &mut Statement) -> String {
@@ -42,9 +52,11 @@ impl VisitorMut for Formatter<'_> {
4252

4353
#[cfg(test)]
4454
mod test {
55+
use std::collections::HashSet;
56+
4557
use super::*;
4658
use crate::sql::constants::SQL_DIALECT;
47-
const CTE_PREFIX: &str = "WITH swap AS (
59+
const CTE_PREFIX: &str = "WITH \"swap\" AS (
4860
SELECT
4961
id,
5062
amount_in,
@@ -57,7 +69,17 @@ mod test {
5769

5870
#[test]
5971
fn format_sql() {
60-
let mut formatter = Formatter::new(CTE_PREFIX);
72+
let mut schema = Schema::new();
73+
schema.insert(
74+
"swap".to_string(),
75+
HashSet::from_iter(
76+
["id", "amount_in", "amount_out", "token_in", "token_out"]
77+
.into_iter()
78+
.map(|s| s.to_string()),
79+
),
80+
);
81+
82+
let mut formatter = Formatter::new(CTE_PREFIX, &schema);
6183

6284
let sql = "SELECT token_in, SUM(amount_in) AS amount FROM unknown.swap GROUP BY token_in";
6385

@@ -71,7 +93,8 @@ mod test {
7193
result,
7294
format!(
7395
"{} SELECT to_jsonb(sub.*) AS data FROM ( {} ) AS sub",
74-
CTE_PREFIX, "SELECT token_in, SUM(amount_in) AS amount FROM swap GROUP BY token_in"
96+
CTE_PREFIX,
97+
"SELECT token_in, SUM(amount_in) AS amount FROM \"swap\" GROUP BY token_in"
7598
)
7699
);
77100
}

store/postgres/src/sql/parser.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ impl Parser {
8484
let mut validator = Validator::new(&self.schema);
8585
validator.validate_statements(&statements)?;
8686

87-
let mut formatter = Formatter::new(&self.prelude);
87+
let mut formatter = Formatter::new(&self.prelude, &self.schema);
8888

8989
let statement = statements
9090
.get_mut(0)
@@ -131,34 +131,34 @@ mod test {
131131

132132
const SQL_QUERY: &str = "
133133
with tokens as (
134-
select * from (values
134+
select * from (values
135135
('0x0000000000000000000000000000000000000000','ETH','Ethereum',18),
136136
('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48','USDC','USD Coin',6)
137137
) as t(address,symbol,name,decimals)
138138
)
139139
140-
select
140+
select
141141
date,
142142
t.symbol,
143143
SUM(amount)/pow(10,t.decimals) as amount
144-
from (select
144+
from (select
145145
date(to_timestamp(block_timestamp) at time zone 'utc') as date,
146146
token,
147147
amount
148-
from swap_multi as sm
148+
from swap_multi as sm
149149
,unnest(sm.amounts_in,sm.tokens_in) as smi(amount,token)
150150
union all
151-
select
151+
select
152152
date(to_timestamp(block_timestamp) at time zone 'utc') as date,
153153
token,
154154
amount
155-
from sgd1.swap_multi as sm
155+
from sgd1.swap_multi as sm
156156
,unnest(sm.amounts_out,sm.tokens_out) as smo(amount,token)
157157
) as tp
158158
inner join tokens as t on t.address = '0x' || encode(tp.token,'hex')
159159
group by tp.date,t.symbol,t.decimals
160-
order by tp.date desc ,amount desc
161-
160+
order by tp.date desc ,amount desc
161+
162162
";
163163

164164
fn test_layout() -> Layout {
@@ -185,7 +185,7 @@ mod test {
185185
assert_eq!(
186186
query,
187187
r#"WITH "swap_multi" AS (SELECT concat('0x', encode("id", 'hex')) AS "id", concat('0x', encode("sender", 'hex')) AS "sender", "amounts_in", "tokens_in", "amounts_out", "tokens_out", "referral_code", "block_number", "block_timestamp", concat('0x', encode("transaction_hash", 'hex')) AS "transaction_hash", "block$" FROM "sgd0815"."swap_multi"),
188-
"token" AS (SELECT "id", concat('0x', encode("address", 'hex')) AS "address", "symbol", "name", "decimals", "block_range" FROM "sgd0815"."token" WHERE "block_range" @> 2147483647) SELECT to_jsonb(sub.*) AS data FROM ( WITH tokens AS (SELECT * FROM (VALUES ('0x0000000000000000000000000000000000000000', 'ETH', 'Ethereum', 18), ('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', 'USDC', 'USD Coin', 6)) AS t (address, symbol, name, decimals)) SELECT date, t.symbol, SUM(amount) / pow(10, t.decimals) AS amount FROM (SELECT date(to_timestamp(block_timestamp) AT TIME ZONE 'utc') AS date, token, amount FROM swap_multi AS sm, UNNEST(sm.amounts_in, sm.tokens_in) AS smi (amount, token) UNION ALL SELECT date(to_timestamp(block_timestamp) AT TIME ZONE 'utc') AS date, token, amount FROM swap_multi AS sm, UNNEST(sm.amounts_out, sm.tokens_out) AS smo (amount, token)) AS tp JOIN tokens AS t ON t.address = '0x' || encode(tp.token, 'hex') GROUP BY tp.date, t.symbol, t.decimals ORDER BY tp.date DESC, amount DESC ) AS sub"#
188+
"token" AS (SELECT "id", concat('0x', encode("address", 'hex')) AS "address", "symbol", "name", "decimals", "block_range" FROM "sgd0815"."token" WHERE "block_range" @> 2147483647) SELECT to_jsonb(sub.*) AS data FROM ( WITH tokens AS (SELECT * FROM (VALUES ('0x0000000000000000000000000000000000000000', 'ETH', 'Ethereum', 18), ('0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', 'USDC', 'USD Coin', 6)) AS t (address, symbol, name, decimals)) SELECT date, t.symbol, SUM(amount) / pow(10, t.decimals) AS amount FROM (SELECT date(to_timestamp(block_timestamp) AT TIME ZONE 'utc') AS date, token, amount FROM "swap_multi" AS sm, UNNEST(sm.amounts_in, sm.tokens_in) AS smi (amount, token) UNION ALL SELECT date(to_timestamp(block_timestamp) AT TIME ZONE 'utc') AS date, token, amount FROM "swap_multi" AS sm, UNNEST(sm.amounts_out, sm.tokens_out) AS smo (amount, token)) AS tp JOIN tokens AS t ON t.address = '0x' || encode(tp.token, 'hex') GROUP BY tp.date, t.symbol, t.decimals ORDER BY tp.date DESC, amount DESC ) AS sub"#
189189
);
190190
}
191191
}

0 commit comments

Comments
 (0)