mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-08-25 07:28:39 +00:00
test: add Parquet footer compatibility coverage
Signed-off-by: jeremyhi <fengjiachun@gmail.com>
This commit is contained in:
@@ -37,6 +37,7 @@ from pathlib import Path
|
||||
|
||||
|
||||
VERSION_RE = re.compile(r"v[0-9]+\.[0-9]+\.[0-9]+")
|
||||
PARQUET_FOOTER_CASE_FILTER = "^parquet_copy_footer_compatibility$"
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
@@ -175,6 +176,22 @@ def run_for_version(
|
||||
preserve_state=preserve_state,
|
||||
)
|
||||
|
||||
parquet_base_command = [
|
||||
*base_command,
|
||||
"--topology",
|
||||
"standalone",
|
||||
"--test-filter",
|
||||
PARQUET_FOOTER_CASE_FILTER,
|
||||
"--expect-cases",
|
||||
"1",
|
||||
]
|
||||
run_compat(
|
||||
base_command=parquet_base_command,
|
||||
preview_title=f"Preview {from_version} -> current (standalone Parquet footer)",
|
||||
compatibility_title=f"Compatibility {from_version} -> current (standalone Parquet footer)",
|
||||
preserve_state=preserve_state,
|
||||
)
|
||||
|
||||
|
||||
def run_downgrade_for_version(
|
||||
*,
|
||||
@@ -206,6 +223,27 @@ def run_downgrade_for_version(
|
||||
preserve_state=preserve_state,
|
||||
)
|
||||
|
||||
parquet_base_command = [
|
||||
str(runner),
|
||||
"compat",
|
||||
"--from-bins-dir",
|
||||
str(current_bins_dir),
|
||||
"--to-version",
|
||||
to_version,
|
||||
"--topology",
|
||||
"standalone",
|
||||
"--test-filter",
|
||||
PARQUET_FOOTER_CASE_FILTER,
|
||||
"--expect-cases",
|
||||
"1",
|
||||
]
|
||||
run_compat(
|
||||
base_command=parquet_base_command,
|
||||
preview_title=f"Preview current -> {to_version} (standalone Parquet footer)",
|
||||
compatibility_title=f"Compatibility current -> {to_version} (standalone Parquet footer)",
|
||||
preserve_state=preserve_state,
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
args = parse_args()
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
name = "parquet_copy_footer_compatibility"
|
||||
reason = "Verify both directions: current imports legacy Parquet without greptime.table_name, and v1.1.4 imports current Parquet with the footer key."
|
||||
introduced_by = "PR #8766"
|
||||
topologies = ["standalone"]
|
||||
from_range = ["*"]
|
||||
to_range = ["*"]
|
||||
features = ["copy", "parquet"]
|
||||
owner = "query"
|
||||
namespace = "parquet_copy_footer_compatibility"
|
||||
@@ -0,0 +1,11 @@
|
||||
CREATE TABLE parquet_copy_footer_source(
|
||||
ts TIMESTAMP TIME INDEX,
|
||||
host STRING PRIMARY KEY,
|
||||
val INT
|
||||
);
|
||||
|
||||
INSERT INTO parquet_copy_footer_source VALUES
|
||||
('2024-02-09 00:00:00+0000', 'host_a', 1),
|
||||
('2024-02-09 00:01:00+0000', 'host_b', 2);
|
||||
|
||||
COPY parquet_copy_footer_source TO '${SQLNESS_HOME}/parquet_copy_footer_compatibility/source.parquet' WITH (format='parquet');
|
||||
@@ -0,0 +1,20 @@
|
||||
CREATE TABLE parquet_copy_footer_target(
|
||||
ts TIMESTAMP TIME INDEX,
|
||||
host STRING PRIMARY KEY,
|
||||
val INT
|
||||
);
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
COPY parquet_copy_footer_target FROM '${SQLNESS_HOME}/parquet_copy_footer_compatibility/source.parquet' WITH (format='parquet');
|
||||
|
||||
Affected Rows: 2
|
||||
|
||||
SELECT ts, host, val FROM parquet_copy_footer_target ORDER BY ts, host;
|
||||
|
||||
+---------------------+--------+-----+
|
||||
| ts | host | val |
|
||||
+---------------------+--------+-----+
|
||||
| 2024-02-09T00:00:00 | host_a | 1 |
|
||||
| 2024-02-09T00:01:00 | host_b | 2 |
|
||||
+---------------------+--------+-----+
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE parquet_copy_footer_target(
|
||||
ts TIMESTAMP TIME INDEX,
|
||||
host STRING PRIMARY KEY,
|
||||
val INT
|
||||
);
|
||||
|
||||
COPY parquet_copy_footer_target FROM '${SQLNESS_HOME}/parquet_copy_footer_compatibility/source.parquet' WITH (format='parquet');
|
||||
|
||||
SELECT ts, host, val FROM parquet_copy_footer_target ORDER BY ts, host;
|
||||
@@ -29,6 +29,7 @@ use crate::util;
|
||||
const COMMENT_PREFIX: &str = "--";
|
||||
const INTERCEPTOR_PREFIX: &str = "-- SQLNESS";
|
||||
const QUERY_DELIMITER: char = ';';
|
||||
const SQLNESS_HOME_TEMPLATE: &str = "${SQLNESS_HOME}";
|
||||
|
||||
#[derive(Debug, Clone, Copy, ValueEnum, PartialEq, Eq)]
|
||||
enum CompatTopology {
|
||||
@@ -564,6 +565,13 @@ enum CompatPhase {
|
||||
Verify,
|
||||
}
|
||||
|
||||
fn expand_sqlness_home(sql: &str, sqlness_home: Option<&str>) -> String {
|
||||
match sqlness_home {
|
||||
Some(sqlness_home) => sql.replace(SQLNESS_HOME_TEMPLATE, sqlness_home),
|
||||
None => sql.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an interceptor registry matching the ordinary sqlness runner.
|
||||
fn create_interceptor_registry() -> Registry {
|
||||
let mut interceptor_registry: Registry = Default::default();
|
||||
@@ -851,6 +859,8 @@ impl ParsedStatement {
|
||||
db.compat_prepare_query_context(&context).await;
|
||||
run_namespace_prelude(db, namespace, &context).await?;
|
||||
let sql = self.concat_query_lines();
|
||||
let sqlness_home = std::env::var("SQLNESS_HOME").ok();
|
||||
let sql = expand_sqlness_home(&sql, sqlness_home.as_deref());
|
||||
let mut results = Vec::new();
|
||||
|
||||
for sql in sql.split(TEMPLATE_DELIMITER) {
|
||||
@@ -942,7 +952,37 @@ fn simple_diff(expected: &str, actual: &str) -> String {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::trim_trailing_blank_lines;
|
||||
use super::{ParsedStatement, expand_sqlness_home, trim_trailing_blank_lines};
|
||||
|
||||
#[test]
|
||||
fn test_expand_sqlness_home_for_execution_only() {
|
||||
let mut statement = ParsedStatement::new();
|
||||
statement.append_query_line(
|
||||
"COPY source TO '${SQLNESS_HOME}/compat/source.parquet' WITH (format='parquet');",
|
||||
);
|
||||
|
||||
let execution_sql = expand_sqlness_home(
|
||||
&statement.concat_query_lines(),
|
||||
Some("/tmp/sqlness-compat/copy"),
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
execution_sql,
|
||||
"COPY source TO '/tmp/sqlness-compat/copy/compat/source.parquet' WITH (format='parquet');"
|
||||
);
|
||||
assert_eq!(
|
||||
statement.display_text(),
|
||||
"COPY source TO '${SQLNESS_HOME}/compat/source.parquet' WITH (format='parquet');\n\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_expand_sqlness_home_without_value_leaves_execution_sql_unchanged() {
|
||||
let sql =
|
||||
"COPY source FROM '${SQLNESS_HOME}/compat/source.parquet' WITH (format='parquet');";
|
||||
|
||||
assert_eq!(expand_sqlness_home(sql, None), sql);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trim_trailing_blank_lines_preserves_single_final_newline() {
|
||||
|
||||
Reference in New Issue
Block a user