-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
We implement several string-related functions. This required adding another pass to the transpiler, so we could rewrite the AST.
- Loading branch information
Showing
10 changed files
with
344 additions
and
99 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//! A simple tree-walker that renames functions to their Snowflake equivalents. | ||
use std::collections::HashMap; | ||
|
||
use derive_visitor::VisitorMut; | ||
|
||
use crate::ast::{FunctionName, Identifier}; | ||
|
||
// A `phf_map!` of BigQuery function names to Snowflake function names. Use | ||
// this for simple renaming. | ||
static FUNCTION_NAMES: phf::Map<&'static str, &'static str> = phf::phf_map! { | ||
"REGEXP_EXTRACT" => "REGEXP_SUBSTR", | ||
"SHA256" => "SHA2_BINARY", // Second argument defaults to SHA256. | ||
}; | ||
|
||
/// A Snowflake UDF (user-defined function). | ||
pub struct Udf { | ||
pub decl: &'static str, | ||
pub sql: &'static str, | ||
} | ||
|
||
impl Udf { | ||
/// Generate the SQL to create this UDF. | ||
pub fn to_sql(&self) -> String { | ||
format!( | ||
"CREATE OR REPLACE TEMP FUNCTION {} AS $$\n{}\n$$\n", | ||
self.decl, self.sql | ||
) | ||
} | ||
} | ||
|
||
/// A `phf_map!` of BigQuery UDF names to Snowflake UDFs. Use this when we | ||
/// actually need to create a UDF as a helper function. | ||
static UDFS: phf::Map<&'static str, &'static Udf> = phf::phf_map! { | ||
"TO_HEX" => &Udf { decl: "TO_HEX(b BINARY) RETURNS STRING", sql: "HEX_ENCODE(b, 0)" }, | ||
}; | ||
|
||
#[derive(Default, VisitorMut)] | ||
#[visitor(FunctionName(enter))] | ||
pub struct RenameFunctions { | ||
// UDFs that we need to create, if we haven't already. | ||
pub udfs: HashMap<String, &'static Udf>, | ||
} | ||
|
||
impl RenameFunctions { | ||
fn enter_function_name(&mut self, function_name: &mut FunctionName) { | ||
if let FunctionName::Function { function } = function_name { | ||
let name = function.unescaped_bigquery().to_ascii_uppercase(); | ||
if let Some(snowflake_name) = FUNCTION_NAMES.get(&name) { | ||
// Rename the function. | ||
let orig_ident = function_name.function_identifier(); | ||
*function_name = FunctionName::Function { | ||
function: Identifier { | ||
token: orig_ident.token.with_token_str(snowflake_name), | ||
text: snowflake_name.to_string(), | ||
}, | ||
}; | ||
} else if let Some(udf) = UDFS.get(&name) { | ||
// We'll need a UDF, so add it to our list it if isn't already | ||
// there. | ||
self.udfs.insert(name, udf); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
-- COALESCE | ||
|
||
CREATE OR REPLACE TABLE __result1 AS | ||
SELECT | ||
-- This is not supported on BigQuery. | ||
-- | ||
-- COALESCE() AS coalesce_empty, | ||
-- | ||
-- This is supported by BigQuery, but not by other databases. We can remove | ||
-- it in the transpiler if absolutely necessary, but it's probably better to | ||
-- make it an error. | ||
-- | ||
-- COALESCE(1) AS coalesce_one, | ||
COALESCE(1, 2) AS coalesce_two, | ||
COALESCE(NULL, 2) AS coalesce_two_null, | ||
COALESCE(NULL, 2, 3) AS coalesce_three_null; | ||
|
||
CREATE OR REPLACE TABLE __expected1 ( | ||
coalesce_two INT64, | ||
coalesce_two_null INT64, | ||
coalesce_three_null INT64, | ||
); | ||
INSERT INTO __expected1 VALUES | ||
(1, 2, 2); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
-- pending: sqlite3 No SHA256 function | ||
|
||
CREATE OR REPLACE TABLE __result1 AS | ||
SELECT | ||
to_hex(sha256('hi')) AS hi, | ||
to_hex(sha256(null)) AS null_arg; | ||
|
||
CREATE OR REPLACE TABLE __expected1 ( | ||
hi STRING, | ||
null_arg STRING, | ||
); | ||
INSERT INTO __expected1 VALUES | ||
('8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4', NULL); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
-- LOWER, UPPER, TRIM, CONCAT | ||
CREATE OR REPLACE TABLE __result1 AS | ||
SELECT | ||
LOWER('FOO') AS lower, | ||
UPPER('foo') AS upper, | ||
TRIM(' foo ') AS trim, | ||
CONCAT('foo', 'bar') AS concat, | ||
CONCAT('x', 1) concat_casted, | ||
CONCAT('x', NULL) concat_null; | ||
|
||
CREATE OR REPLACE TABLE __expected1 ( | ||
lower STRING, | ||
upper STRING, | ||
trim STRING, | ||
concat STRING, | ||
concat_casted STRING, | ||
concat_null STRING, | ||
); | ||
INSERT INTO __expected1 VALUES | ||
('foo', 'FOO', 'foo', 'foobar', 'x1', NULL); | ||
|