From 7fe3670a9691aeb2e5bac181d8f62b9384b523bf Mon Sep 17 00:00:00 2001 From: tobilg Date: Tue, 22 Sep 2026 16:42:08 +0200 Subject: [PATCH 1/8] feat: add SAP HANA dialect and source semantics (#276) Co-authored-by: Torsten Glunde --- CHANGELOG.md | 15 + Makefile | 3 + README.md | 4 +- crates/polyglot-sql-ffi/src/dialects.rs | 3 +- crates/polyglot-sql-ffi/tests/ffi_tests.rs | 23 +- crates/polyglot-sql-python/README.md | 2 +- .../python/polyglot_sql/__init__.py | 30 + .../python/polyglot_sql/__init__.pyi | 15 + crates/polyglot-sql-python/src/dialects.rs | 1 + crates/polyglot-sql-python/src/expr_types.rs | 15 + .../tests/test_dialects.py | 1 + .../tests/test_expression.py | 17 + .../tests/test_transpile.py | 10 + crates/polyglot-sql-wasm/Cargo.toml | 3 +- crates/polyglot-sql-wasm/src/lib.rs | 17 +- crates/polyglot-sql/Cargo.toml | 3 +- crates/polyglot-sql/README.md | 2 +- crates/polyglot-sql/src/ast_mutation.rs | 2 + crates/polyglot-sql/src/ast_transforms.rs | 10 +- crates/polyglot-sql/src/dialects/hana.rs | 39 + crates/polyglot-sql/src/dialects/mod.rs | 84 + .../src/dialects/normalization/statements.rs | 1 + crates/polyglot-sql/src/expressions.rs | 294 +- crates/polyglot-sql/src/format_tokens.rs | 51 + crates/polyglot-sql/src/function_registry.rs | 329 + crates/polyglot-sql/src/generator.rs | 1004 ++- crates/polyglot-sql/src/lineage.rs | 1 + .../src/optimizer/annotate_types.rs | 2 +- .../src/optimizer/normalize_identifiers.rs | 7 +- .../src/optimizer/set_operation_types.rs | 1 + crates/polyglot-sql/src/parser.rs | 1325 +++- crates/polyglot-sql/src/traversal.rs | 11 +- crates/polyglot-sql/src/validation.rs | 13 +- .../polyglot-sql/tests/common/test_runner.rs | 1 + .../tests/custom_fixtures/hana/ddl.json | 66 + .../tests/custom_fixtures/hana/dml.json | 51 + .../tests/custom_fixtures/hana/functions.json | 136 + .../tests/custom_fixtures/hana/identity.json | 163 + .../tests/custom_fixtures/hana/select.json | 128 + .../tests/custom_fixtures/hana/types.json | 39 + crates/polyglot-sql/tests/dialect_matrix.rs | 421 + docs/hana/README.md | 148 + docs/hana/cloud-reference.json | 6824 +++++++++++++++++ docs/hana/functions.json | 1795 +++++ docs/hana/statements.json | 1042 +++ packages/go/integration_test.go | 16 + packages/playground/src/lib/constants.ts | 1 + packages/sdk/README.md | 1 + packages/sdk/src/ast/types/guards.ts | 25 +- packages/sdk/src/ast/visitor/visitor.test.ts | 29 + packages/sdk/src/index.ts | 1 + 51 files changed, 14181 insertions(+), 44 deletions(-) create mode 100644 crates/polyglot-sql/src/dialects/hana.rs create mode 100644 crates/polyglot-sql/tests/custom_fixtures/hana/ddl.json create mode 100644 crates/polyglot-sql/tests/custom_fixtures/hana/dml.json create mode 100644 crates/polyglot-sql/tests/custom_fixtures/hana/functions.json create mode 100644 crates/polyglot-sql/tests/custom_fixtures/hana/identity.json create mode 100644 crates/polyglot-sql/tests/custom_fixtures/hana/select.json create mode 100644 crates/polyglot-sql/tests/custom_fixtures/hana/types.json create mode 100644 docs/hana/README.md create mode 100644 docs/hana/cloud-reference.json create mode 100644 docs/hana/functions.json create mode 100644 docs/hana/statements.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 05cf2c33..911e4dbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to this project are documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning. +## [Unreleased] + +### Added + +- Initial SAP HANA Cloud and Platform dialect support, based on + [PR #276](https://github.com/tobilg/polyglot/pull/276): source-aware functions and + types, JSON operations and query serialization, UPSERT, range/hash partitioning, + hierarchy queries, calculation-view parameters, regex operations, hints, and + locking clauses. HANA is discoverable through Rust, WASM, Python, Go/FFI, and + the TypeScript SDK. The [coverage guide](docs/hana/README.md) records supported + forms and remaining reference gaps. +- Verified HANA scalar translations and explicit errors for unverified conversions, + including preservation of decimal truncation, string positions, type domains, + UTC meaning, and timestamp precision. + ## [0.12.1] - 2026-09-21 ### Added diff --git a/Makefile b/Makefile index f1150570..4528482d 100644 --- a/Makefile +++ b/Makefile @@ -238,6 +238,9 @@ test-rust-lib: # Check capabilities separately so Cargo feature unification cannot mask dependencies. test-rust-feature-gates: + cargo check -p polyglot-sql --no-default-features --features dialect-hana + cargo check -p polyglot-sql --no-default-features --features generate,dialect-hana + cargo check -p polyglot-sql --no-default-features --features transpile,dialect-hana cargo check -p polyglot-sql --no-default-features @for feature in generate transpile builder ast-tools semantic openlineage diff planner time \ function-catalog-clickhouse function-catalog-duckdb function-catalog-all-dialects; do \ diff --git a/README.md b/README.md index 12539a34..3cac1580 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,9 @@ Release notes are tracked in [`CHANGELOG.md`](CHANGELOG.md). | MySQL | Oracle | PostgreSQL | Presto | Redshift | | RisingWave | SingleStore | Snowflake | Solr | Spark | | SQLite | StarRocks | Tableau | Teradata | TiDB | -| Trino | TSQL | DataFusion | Generic SQL | | +| Trino | TSQL | DataFusion | Generic SQL | SAP HANA | + +SAP HANA coverage and translation limits are documented in [the HANA support guide](docs/hana/README.md). ## Quick Start diff --git a/crates/polyglot-sql-ffi/src/dialects.rs b/crates/polyglot-sql-ffi/src/dialects.rs index 87331aa4..de46a4f5 100644 --- a/crates/polyglot-sql-ffi/src/dialects.rs +++ b/crates/polyglot-sql-ffi/src/dialects.rs @@ -3,7 +3,7 @@ use polyglot_sql::dialects::DialectType; use std::os::raw::c_char; use std::ptr; -const DIALECTS: [DialectType; 34] = [ +const DIALECTS: [DialectType; 35] = [ DialectType::Generic, DialectType::PostgreSQL, DialectType::MySQL, @@ -38,6 +38,7 @@ const DIALECTS: [DialectType; 34] = [ DialectType::Dremio, DialectType::Exasol, DialectType::DataFusion, + DialectType::HANA, ]; /// Return supported dialect names as JSON. diff --git a/crates/polyglot-sql-ffi/tests/ffi_tests.rs b/crates/polyglot-sql-ffi/tests/ffi_tests.rs index 970c2935..08db2506 100644 --- a/crates/polyglot-sql-ffi/tests/ffi_tests.rs +++ b/crates/polyglot-sql-ffi/tests/ffi_tests.rs @@ -2050,7 +2050,7 @@ fn test_dialect_list_and_count() { let list: Vec = serde_json::from_str(&json).expect("invalid dialect list json"); let count = polyglot_dialect_count(); assert_eq!(list.len() as i32, count); - assert_eq!(count, 34); + assert_eq!(count, 35); let unique: BTreeSet<&str> = list.iter().map(String::as_str).collect(); assert_eq!(unique.len(), list.len()); assert!(list.iter().any(|d| d == "generic")); @@ -2176,3 +2176,24 @@ fn test_public_api_matches_capability_contract() { declared_available ); } + +#[test] +fn test_hana_round_trip_and_unsupported_conversion() { + let sql = c("SELECT * FROM t FOR JSON ('arraywrap' = 'NO')"); + let hana = c("hana"); + let duckdb = c("duckdb"); + let (status, output, error) = consume_result(polyglot_transpile( + sql.as_ptr(), + hana.as_ptr(), + hana.as_ptr(), + )); + assert_eq!(status, 0, "{error:?}"); + assert!(output.unwrap().contains("FOR JSON")); + let (status, _, error) = consume_result(polyglot_transpile( + sql.as_ptr(), + hana.as_ptr(), + duckdb.as_ptr(), + )); + assert_ne!(status, 0); + assert!(error.unwrap().contains("HANA")); +} diff --git a/crates/polyglot-sql-python/README.md b/crates/polyglot-sql-python/README.md index 1a6c33aa..aafe8159 100644 --- a/crates/polyglot-sql-python/README.md +++ b/crates/polyglot-sql-python/README.md @@ -329,7 +329,7 @@ All functions are exported from `polyglot_sql`. Current dialect names returned by `polyglot_sql.dialects()`: -`athena`, `bigquery`, `clickhouse`, `cockroachdb`, `datafusion`, `databricks`, `doris`, `dremio`, `drill`, `druid`, `duckdb`, `dune`, `exasol`, `fabric`, `generic`, `hive`, `materialize`, `mysql`, `oracle`, `postgres`, `presto`, `redshift`, `risingwave`, `singlestore`, `snowflake`, `solr`, `spark`, `sqlite`, `starrocks`, `tableau`, `teradata`, `tidb`, `trino`, `tsql`. +`athena`, `bigquery`, `clickhouse`, `cockroachdb`, `datafusion`, `databricks`, `doris`, `dremio`, `drill`, `druid`, `duckdb`, `dune`, `exasol`, `fabric`, `generic`, `hana`, `hive`, `materialize`, `mysql`, `oracle`, `postgres`, `presto`, `redshift`, `risingwave`, `singlestore`, `snowflake`, `solr`, `spark`, `sqlite`, `starrocks`, `tableau`, `teradata`, `tidb`, `trino`, `tsql`. ## Error Handling diff --git a/crates/polyglot-sql-python/python/polyglot_sql/__init__.py b/crates/polyglot-sql-python/python/polyglot_sql/__init__.py index b7860e97..e7d8a77f 100644 --- a/crates/polyglot-sql-python/python/polyglot_sql/__init__.py +++ b/crates/polyglot-sql-python/python/polyglot_sql/__init__.py @@ -596,6 +596,21 @@ def dense_rank(): FromTimeZone, FromUnixtime, Function, + HanaFunction, + HanaAggregateFunction, + HanaRegex, + HanaJson, + HanaJsonColumn, + HanaUpsert, + HanaPartition, + HanaStorageProperty, + HanaHierarchy, + HanaPlaceholder, + HanaTableFunction, + HanaCall, + HanaHint, + HanaGrouping, + HanaTimezone, FunctionEmits, GapFill, Generate, @@ -1302,6 +1317,21 @@ def dense_rank(): "Alias", "Cast", "Function", + "HanaFunction", + "HanaAggregateFunction", + "HanaRegex", + "HanaJson", + "HanaJsonColumn", + "HanaUpsert", + "HanaPartition", + "HanaStorageProperty", + "HanaHierarchy", + "HanaPlaceholder", + "HanaTableFunction", + "HanaCall", + "HanaHint", + "HanaGrouping", + "HanaTimezone", "AggregateFunction", "WindowFunction", "From", diff --git a/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi b/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi index 67ea46da..5c8792b8 100644 --- a/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi +++ b/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi @@ -855,6 +855,21 @@ class FromBase(Expression): ... class FromTimeZone(Expression): ... class FromUnixtime(Expression): ... class Function(Expression): ... +class HanaFunction(Expression): ... +class HanaAggregateFunction(Expression): ... +class HanaRegex(Expression): ... +class HanaJson(Expression): ... +class HanaJsonColumn(Expression): ... +class HanaUpsert(Expression): ... +class HanaPartition(Expression): ... +class HanaStorageProperty(Expression): ... +class HanaHierarchy(Expression): ... +class HanaPlaceholder(Expression): ... +class HanaTableFunction(Expression): ... +class HanaCall(Expression): ... +class HanaHint(Expression): ... +class HanaGrouping(Expression): ... +class HanaTimezone(Expression): ... class FunctionEmits(Expression): ... class GapFill(Expression): ... class Generate(Expression): ... diff --git a/crates/polyglot-sql-python/src/dialects.rs b/crates/polyglot-sql-python/src/dialects.rs index 028fbda3..97840f0e 100644 --- a/crates/polyglot-sql-python/src/dialects.rs +++ b/crates/polyglot-sql-python/src/dialects.rs @@ -16,6 +16,7 @@ const DIALECT_NAMES: &[&str] = &[ "exasol", "fabric", "generic", + "hana", "hive", "materialize", "mysql", diff --git a/crates/polyglot-sql-python/src/expr_types.rs b/crates/polyglot-sql-python/src/expr_types.rs index 83dc2766..6ef8dc58 100644 --- a/crates/polyglot-sql-python/src/expr_types.rs +++ b/crates/polyglot-sql-python/src/expr_types.rs @@ -140,6 +140,21 @@ define_expression_subclasses!( Exists, MemberOf, Function, + HanaFunction, + HanaAggregateFunction, + HanaRegex, + HanaJson, + HanaJsonColumn, + HanaUpsert, + HanaPartition, + HanaStorageProperty, + HanaHierarchy, + HanaPlaceholder, + HanaTableFunction, + HanaCall, + HanaHint, + HanaGrouping, + HanaTimezone, AggregateFunction, WindowFunction, From, diff --git a/crates/polyglot-sql-python/tests/test_dialects.py b/crates/polyglot-sql-python/tests/test_dialects.py index 85cbfb48..07414ed3 100644 --- a/crates/polyglot-sql-python/tests/test_dialects.py +++ b/crates/polyglot-sql-python/tests/test_dialects.py @@ -17,6 +17,7 @@ "exasol", "fabric", "generic", + "hana", "hive", "materialize", "mysql", diff --git a/crates/polyglot-sql-python/tests/test_expression.py b/crates/polyglot-sql-python/tests/test_expression.py index 7d8c3832..577c9ab4 100644 --- a/crates/polyglot-sql-python/tests/test_expression.py +++ b/crates/polyglot-sql-python/tests/test_expression.py @@ -3,6 +3,23 @@ import polyglot_sql +def test_hana_expression_subclasses_and_accessors(): + expression = polyglot_sql.parse_one( + "SELECT LOCATE(value, 'a', 1, 2), JSON_VALUE(payload, '$.n') FROM records", + dialect="hana", + ) + locate = expression.find("hana_function") + assert isinstance(locate, polyglot_sql.HanaFunction) + assert locate.name == "LOCATE" + assert len(locate.expressions) == 4 + assert isinstance(locate.expressions[0], polyglot_sql.Column) + assert locate.expressions[0].name == "value" + json_value = expression.find("hana_json") + assert isinstance(json_value, polyglot_sql.HanaJson) + assert json_value.name == "JSON_VALUE" + assert json_value.this.name == "payload" + + def test_parse_one_returns_expression_object(): expr = polyglot_sql.parse_one("SELECT a FROM t WHERE b = 1", dialect="postgres") diff --git a/crates/polyglot-sql-python/tests/test_transpile.py b/crates/polyglot-sql-python/tests/test_transpile.py index 4bfd5068..741a581c 100644 --- a/crates/polyglot-sql-python/tests/test_transpile.py +++ b/crates/polyglot-sql-python/tests/test_transpile.py @@ -188,3 +188,13 @@ def run(_): results = list(executor.map(run, range(32))) assert all(result == results[0] for result in results) + + +def test_hana_native_clauses_and_source_semantics(): + sql = "SELECT * FROM t FOR JSON ('arraywrap' = 'NO')" + assert polyglot_sql.transpile(sql, read="hana", write="hana") == [sql] + assert polyglot_sql.transpile( + "SELECT LOCATE('abcabc', 'bc')", read="hana", write="duckdb" + ) == ["SELECT STRPOS('abcabc', 'bc')"] + with pytest.raises(polyglot_sql.TranspileError): + polyglot_sql.transpile(sql, read="hana", write="duckdb") diff --git a/crates/polyglot-sql-wasm/Cargo.toml b/crates/polyglot-sql-wasm/Cargo.toml index 5669a150..b7921011 100644 --- a/crates/polyglot-sql-wasm/Cargo.toml +++ b/crates/polyglot-sql-wasm/Cargo.toml @@ -73,7 +73,7 @@ all-dialects = [ "dialect-singlestore", "dialect-cockroachdb", "dialect-tidb", "dialect-druid", "dialect-solr", "dialect-tableau", "dialect-dune", "dialect-fabric", "dialect-drill", - "dialect-dremio", "dialect-exasol", "dialect-datafusion", + "dialect-dremio", "dialect-exasol", "dialect-datafusion", "dialect-hana", ] dialect-postgresql = ["polyglot-sql/dialect-postgresql"] dialect-mysql = ["polyglot-sql/dialect-mysql"] @@ -108,6 +108,7 @@ dialect-drill = ["polyglot-sql/dialect-drill"] dialect-dremio = ["polyglot-sql/dialect-dremio"] dialect-exasol = ["polyglot-sql/dialect-exasol"] dialect-datafusion = ["polyglot-sql/dialect-datafusion"] +dialect-hana = ["polyglot-sql/dialect-hana"] function-catalog-clickhouse = [ "dialect-clickhouse", "semantic", diff --git a/crates/polyglot-sql-wasm/src/lib.rs b/crates/polyglot-sql-wasm/src/lib.rs index 0e5e3e8e..d310ae71 100644 --- a/crates/polyglot-sql-wasm/src/lib.rs +++ b/crates/polyglot-sql-wasm/src/lib.rs @@ -851,6 +851,8 @@ fn get_dialects_internal() -> Vec<&'static str> { dialects.push("exasol"); #[cfg(feature = "dialect-datafusion")] dialects.push("datafusion"); + #[cfg(feature = "dialect-hana")] + dialects.push("hana"); dialects } @@ -2927,11 +2929,24 @@ mod tests { let dialects: Vec = serde_json::from_str(&result).unwrap(); let unique: std::collections::BTreeSet<&str> = dialects.iter().map(String::as_str).collect(); - assert_eq!(dialects.len(), 34); + assert_eq!(dialects.len(), 35); assert_eq!(unique.len(), dialects.len()); assert!(unique.contains("generic")); assert!(unique.contains("postgresql")); assert!(unique.contains("datafusion")); + assert!(unique.contains("hana")); + } + + #[test] + #[cfg(feature = "dialect-hana")] + fn test_hana_discovery_and_native_parse() { + let dialects: Vec = serde_json::from_str(&get_dialects()).unwrap(); + assert!(dialects.iter().any(|dialect| dialect == "hana")); + let dialect = + polyglot_sql::dialects::Dialect::get(polyglot_sql::dialects::DialectType::HANA); + let sql = "SELECT * FROM t FOR JSON ('arraywrap' = 'NO')"; + let ast = dialect.parse(sql).unwrap(); + assert_eq!(dialect.generate(&ast[0]).unwrap(), sql); } #[test] diff --git a/crates/polyglot-sql/Cargo.toml b/crates/polyglot-sql/Cargo.toml index 29cceb09..6b1090dc 100644 --- a/crates/polyglot-sql/Cargo.toml +++ b/crates/polyglot-sql/Cargo.toml @@ -47,7 +47,7 @@ all-dialects = [ "dialect-singlestore", "dialect-cockroachdb", "dialect-tidb", "dialect-druid", "dialect-solr", "dialect-tableau", "dialect-dune", "dialect-fabric", "dialect-drill", - "dialect-dremio", "dialect-exasol", "dialect-datafusion", + "dialect-dremio", "dialect-exasol", "dialect-datafusion", "dialect-hana", ] dialect-postgresql = [] dialect-mysql = [] @@ -82,6 +82,7 @@ dialect-drill = [] dialect-dremio = [] dialect-exasol = [] dialect-datafusion = [] +dialect-hana = [] function-catalog-clickhouse = [ "semantic", "dep:polyglot-sql-function-catalogs", diff --git a/crates/polyglot-sql/README.md b/crates/polyglot-sql/README.md index 348eeb48..408cb420 100644 --- a/crates/polyglot-sql/README.md +++ b/crates/polyglot-sql/README.md @@ -488,7 +488,7 @@ assert_eq!(err.line(), None); ## Supported Dialects -Athena, BigQuery, ClickHouse, CockroachDB, DataFusion, Databricks, Doris, Dremio, Drill, Druid, DuckDB, Dune, Exasol, Fabric, Generic SQL, Hive, Materialize, MySQL, Oracle, PostgreSQL, Presto, Redshift, RisingWave, SingleStore, Snowflake, Solr, Spark, SQLite, StarRocks, Tableau, Teradata, TiDB, Trino, TSQL +Athena, BigQuery, ClickHouse, CockroachDB, DataFusion, Databricks, Doris, Dremio, Drill, Druid, DuckDB, Dune, Exasol, Fabric, Generic SQL, SAP HANA, Hive, Materialize, MySQL, Oracle, PostgreSQL, Presto, Redshift, RisingWave, SingleStore, Snowflake, Solr, Spark, SQLite, StarRocks, Tableau, Teradata, TiDB, Trino, TSQL ## Feature Flags diff --git a/crates/polyglot-sql/src/ast_mutation.rs b/crates/polyglot-sql/src/ast_mutation.rs index af217504..f9e6e6f9 100644 --- a/crates/polyglot-sql/src/ast_mutation.rs +++ b/crates/polyglot-sql/src/ast_mutation.rs @@ -410,6 +410,7 @@ pub(crate) fn append_window( pub(crate) fn append_lock(expression: &mut Expression, kind: LockKind) -> Result<()> { as_select_mut(expression, "lock")?.locks.push(Lock { + ignore_locked: false, update: match kind { LockKind::Update => Some(Box::new(Expression::Boolean(BooleanLiteral { value: true, @@ -453,6 +454,7 @@ pub(crate) fn create_table_as( temporary, or_replace: replace, table_modifier: None, + hana_storage: false, as_select: Some(query), as_select_parenthesized: false, on_commit: None, diff --git a/crates/polyglot-sql/src/ast_transforms.rs b/crates/polyglot-sql/src/ast_transforms.rs index 780e2caf..a7bbc05c 100644 --- a/crates/polyglot-sql/src/ast_transforms.rs +++ b/crates/polyglot-sql/src/ast_transforms.rs @@ -473,6 +473,9 @@ pub fn get_table_names(expr: &Expression) -> Vec { names.push(name); } } + Expression::HanaUpsert(upsert) => { + push_table_ref_name(&upsert.table, &cte_aliases, &mut names); + } Expression::Insert(insert) => { push_table_ref_name(&insert.table, &cte_aliases, &mut names); } @@ -532,12 +535,7 @@ pub fn get_identifiers(expr: &Expression) -> Vec<&Expression> { /// Collect all function call nodes in the expression tree. pub fn get_functions(expr: &Expression) -> Vec<&Expression> { - expr.find_all(|e| { - matches!( - e, - Expression::Function(_) | Expression::AggregateFunction(_) - ) - }) + expr.find_all(crate::traversal::is_function) } /// Collect all literal value nodes in the expression tree. diff --git a/crates/polyglot-sql/src/dialects/hana.rs b/crates/polyglot-sql/src/dialects/hana.rs new file mode 100644 index 00000000..78a3d94c --- /dev/null +++ b/crates/polyglot-sql/src/dialects/hana.rs @@ -0,0 +1,39 @@ +//! SAP HANA Cloud and Platform SQL dialect. +//! +//! Registration is based on Torsten Glunde's contribution in PR #276. +//! Syntax and semantic handling live in the shared parser, AST, and generator. + +use super::{DialectImpl, DialectType}; +#[cfg(feature = "generate")] +use crate::generator::{GeneratorConfig, IdentifierQuoteStyle, NormalizeFunctions}; +use crate::tokens::{TokenType, TokenizerConfig}; + +pub struct HanaDialect; + +impl DialectImpl for HanaDialect { + fn dialect_type(&self) -> DialectType { + DialectType::HANA + } + + fn tokenizer_config(&self) -> TokenizerConfig { + let mut config = TokenizerConfig::default(); + config.identifiers.insert('"', '"'); + config.nested_comments = false; + config + .keywords + .insert("UNKNOWN".to_owned(), TokenType::Null); + config + } + + #[cfg(feature = "generate")] + fn generator_config(&self) -> GeneratorConfig { + GeneratorConfig { + dialect: Some(DialectType::HANA), + identifier_quote: '"', + identifier_quote_style: IdentifierQuoteStyle::DOUBLE_QUOTE, + normalize_functions: NormalizeFunctions::None, + alter_table_include_column_keyword: false, + ..Default::default() + } + } +} diff --git a/crates/polyglot-sql/src/dialects/mod.rs b/crates/polyglot-sql/src/dialects/mod.rs index 61cdc84c..c8f7b8bd 100644 --- a/crates/polyglot-sql/src/dialects/mod.rs +++ b/crates/polyglot-sql/src/dialects/mod.rs @@ -51,6 +51,8 @@ mod dune; mod exasol; #[cfg(feature = "dialect-fabric")] mod fabric; +#[cfg(feature = "dialect-hana")] +mod hana; #[cfg(feature = "dialect-hive")] mod hive; #[cfg(feature = "dialect-materialize")] @@ -120,6 +122,8 @@ pub use dune::DuneDialect; pub use exasol::ExasolDialect; #[cfg(feature = "dialect-fabric")] pub use fabric::FabricDialect; +#[cfg(feature = "dialect-hana")] +pub use hana::HanaDialect; #[cfg(feature = "dialect-hive")] pub use hive::HiveDialect; #[cfg(feature = "dialect-materialize")] @@ -274,6 +278,8 @@ pub enum DialectType { Exasol, /// Apache DataFusion -- Arrow-based query engine with modern SQL extensions. DataFusion, + /// SAP HANA Cloud and SAP HANA Platform SQL. + HANA, } impl DialectType { @@ -330,6 +336,7 @@ impl std::fmt::Display for DialectType { DialectType::Dremio => write!(f, "dremio"), DialectType::Exasol => write!(f, "exasol"), DialectType::DataFusion => write!(f, "datafusion"), + DialectType::HANA => write!(f, "hana"), } } } @@ -373,6 +380,7 @@ impl std::str::FromStr for DialectType { "dremio" => Ok(DialectType::Dremio), "exasol" => Ok(DialectType::Exasol), "datafusion" | "arrow-datafusion" | "arrow_datafusion" => Ok(DialectType::DataFusion), + "hana" | "saphana" | "sap_hana" => Ok(DialectType::HANA), _ => Err(crate::error::Error::parse( format!("Unknown dialect: {}", s), 0, @@ -688,6 +696,7 @@ where // semantics even though all physical children are visible to traversal APIs. fn uses_generated_dispatch(expression: &Expression) -> bool { match expression { + Expression::CreateTable(create) if create.hana_storage => true, Expression::Select(select) => { select.joins.is_empty() && select.with.is_none() @@ -747,6 +756,20 @@ where | Expression::Like(_) | Expression::ILike(_) | Expression::Function(_) + | Expression::HanaFunction(_) + | Expression::HanaAggregateFunction(_) + | Expression::HanaRegex(_) + | Expression::HanaJson(_) + | Expression::HanaJsonColumn(_) + | Expression::HanaPartition(_) + | Expression::HanaStorageProperty(_) + | Expression::HanaHierarchy(_) + | Expression::HanaPlaceholder(_) + | Expression::HanaTableFunction(_) + | Expression::HanaCall(_) + | Expression::HanaHint(_) + | Expression::HanaGrouping(_) + | Expression::HanaTimezone(_) | Expression::Lead(_) | Expression::Lag(_) | Expression::Array(_) @@ -1048,6 +1071,12 @@ where // First recursively transform children, then apply the transform function let expr = match expr { Expression::Select(mut select) => { + if let Some(options) = &mut select.hana_options { + options.hints = std::mem::take(&mut options.hints) + .into_iter() + .map(|hint| transform_recursive(hint, transform_fn)) + .collect::>>()?; + } select.expressions = select .expressions .into_iter() @@ -1998,6 +2027,18 @@ where Expression::UnixToTime(e) } + Expression::HanaUpsert(mut upsert) => { + upsert.table = transform_table_ref_recursive(upsert.table, transform_fn)?; + upsert.source = transform_recursive(upsert.source, transform_fn)?; + if let Some(partition) = upsert.partition.take() { + upsert.partition = Some(transform_recursive(partition, transform_fn)?); + } + if let Some(condition) = upsert.condition.take() { + upsert.condition = Some(transform_recursive(condition, transform_fn)?); + } + Expression::HanaUpsert(upsert) + } + // CreateTable: recurse into column defaults, on_update expressions, and data types Expression::CreateTable(mut ct) => { for col in &mut ct.columns { @@ -2387,6 +2428,7 @@ cached_dialect!(CACHED_DRILL, DrillDialect, "dialect-drill"); cached_dialect!(CACHED_DREMIO, DremioDialect, "dialect-dremio"); cached_dialect!(CACHED_EXASOL, ExasolDialect, "dialect-exasol"); cached_dialect!(CACHED_DATAFUSION, DataFusionDialect, "dialect-datafusion"); +cached_dialect!(CACHED_HANA, HanaDialect, "dialect-hana"); fn configs_for_dialect_type(dt: DialectType) -> DialectConfigs { /// Clone configs from a cached static and pair with a fresh transform closure. @@ -2469,6 +2511,8 @@ fn configs_for_dialect_type(dt: DialectType) -> DialectConfigs { DialectType::Exasol => from_cache!(CACHED_EXASOL, ExasolDialect), #[cfg(feature = "dialect-datafusion")] DialectType::DataFusion => from_cache!(CACHED_DATAFUSION, DataFusionDialect), + #[cfg(feature = "dialect-hana")] + DialectType::HANA => from_cache!(CACHED_HANA, HanaDialect), _ => from_cache!(CACHED_GENERIC, GenericDialect), } } @@ -3465,6 +3509,46 @@ impl Dialect { expressions .into_iter() .map(|expr| { + // Validate source-specific HANA semantics before target transforms + // can erase a cast or rebuild a SELECT without its native clauses. + // The same generator checks protect standalone AST generation. + if self.dialect_type == DialectType::HANA && target != DialectType::HANA { + for node in expr.dfs() { + let protected = match node { + Expression::HanaFunction(_) + | Expression::HanaAggregateFunction(_) + | Expression::HanaRegex(_) + | Expression::HanaJson(_) + | Expression::HanaJsonColumn(_) + | Expression::HanaUpsert(_) + | Expression::HanaPartition(_) + | Expression::HanaHierarchy(_) + | Expression::HanaGrouping(_) + | Expression::HanaTimezone(_) + | Expression::HanaPlaceholder(_) + | Expression::HanaTableFunction(_) + | Expression::HanaCall(_) + | Expression::HanaHint(_) + | Expression::HanaStorageProperty(_) + | Expression::CreateTable(_) + | Expression::AlterTable(_) => true, + Expression::Cast(c) => matches!(c.to, DataType::Hana { .. }), + Expression::Select(s) => { + s.hana_options.is_some() || s.locks.iter().any(|l| l.ignore_locked) + } + Expression::DataType(DataType::Hana { .. }) => true, + _ => false, + }; + if protected { + target_dialect.generate_with_transpile_options( + node, + self.dialect_type, + opts, + )?; + } + } + } + // DuckDB source: normalize VARCHAR/CHAR to TEXT (DuckDB doesn't support // VARCHAR length constraints). This emulates Python sqlglot's DuckDB parser // where VARCHAR_LENGTH = None and VARCHAR maps to TEXT. diff --git a/crates/polyglot-sql/src/dialects/normalization/statements.rs b/crates/polyglot-sql/src/dialects/normalization/statements.rs index 10e43291..6a8a2115 100644 --- a/crates/polyglot-sql/src/dialects/normalization/statements.rs +++ b/crates/polyglot-sql/src/dialects/normalization/statements.rs @@ -908,6 +908,7 @@ pub(super) fn transform_select_into( temporary: is_temp, or_replace: false, table_modifier: None, + hana_storage: false, as_select: Some(Expression::Select(new_select)), as_select_parenthesized: false, on_commit: None, diff --git a/crates/polyglot-sql/src/expressions.rs b/crates/polyglot-sql/src/expressions.rs index c88b6b6b..965162e1 100644 --- a/crates/polyglot-sql/src/expressions.rs +++ b/crates/polyglot-sql/src/expressions.rs @@ -177,6 +177,22 @@ pub enum Expression { // Functions Function(Box), + /// A SAP HANA built-in retaining source semantics for independent generation. + HanaFunction(Box), + HanaAggregateFunction(Box), + HanaRegex(Box), + HanaJson(Box), + HanaJsonColumn(Box), + HanaUpsert(Box), + HanaPartition(Box), + HanaStorageProperty(Box), + HanaHierarchy(Box), + HanaPlaceholder(Box), + HanaTableFunction(Box), + HanaCall(Box), + HanaHint(Box), + HanaGrouping(Box), + HanaTimezone(Box), AggregateFunction(Box), WindowFunction(Box), @@ -1145,6 +1161,8 @@ impl Expression { | Expression::PipeOperator(_) // DML + | Expression::HanaUpsert(_) + | Expression::HanaCall(_) | Expression::Insert(_) | Expression::Update(_) | Expression::Delete(_) @@ -1319,8 +1337,10 @@ impl Expression { Expression::Column(c) => c.inferred_type.as_ref(), Expression::Dot(dot) => dot.inferred_type.as_ref(), - Expression::Function(f) => f.inferred_type.as_ref(), - Expression::AggregateFunction(f) => f.inferred_type.as_ref(), + Expression::Function(f) | Expression::HanaFunction(f) => f.inferred_type.as_ref(), + Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => { + f.inferred_type.as_ref() + } Expression::WindowFunction(f) => f.inferred_type.as_ref(), Expression::Case(c) => c.inferred_type.as_ref(), Expression::Array(a) => a.inferred_type.as_ref(), @@ -1553,8 +1573,10 @@ impl Expression { Expression::Column(c) => c.inferred_type = Some(dt), Expression::Dot(dot) => dot.inferred_type = Some(dt), - Expression::Function(f) => f.inferred_type = Some(dt), - Expression::AggregateFunction(f) => f.inferred_type = Some(dt), + Expression::Function(f) | Expression::HanaFunction(f) => f.inferred_type = Some(dt), + Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => { + f.inferred_type = Some(dt) + } Expression::WindowFunction(f) => f.inferred_type = Some(dt), Expression::Case(c) => c.inferred_type = Some(dt), Expression::Array(a) => a.inferred_type = Some(dt), @@ -1917,6 +1939,21 @@ impl Expression { Expression::Exists(_) => "exists", Expression::MemberOf(_) => "member_of", Expression::Function(_) => "function", + Expression::HanaFunction(_) => "hana_function", + Expression::HanaAggregateFunction(_) => "hana_aggregate_function", + Expression::HanaRegex(_) => "hana_regex", + Expression::HanaJson(_) => "hana_json", + Expression::HanaJsonColumn(_) => "hana_json_column", + Expression::HanaUpsert(_) => "hana_upsert", + Expression::HanaPartition(_) => "hana_partition", + Expression::HanaStorageProperty(_) => "hana_storage_property", + Expression::HanaHierarchy(_) => "hana_hierarchy", + Expression::HanaGrouping(_) => "hana_grouping", + Expression::HanaTimezone(_) => "hana_timezone", + Expression::HanaPlaceholder(_) => "hana_placeholder", + Expression::HanaTableFunction(_) => "hana_table_function", + Expression::HanaCall(_) => "hana_call", + Expression::HanaHint(_) => "hana_hint", Expression::AggregateFunction(_) => "aggregate_function", Expression::WindowFunction(_) => "window_function", Expression::From(_) => "from", @@ -2777,6 +2814,10 @@ impl Expression { /// Returns the primary child expression (".this" in sqlglot). pub fn get_this(&self) -> Option<&Expression> { match self { + Expression::HanaJson(json) => Some(&json.input), + Expression::HanaRegex(regex) => Some(®ex.subject), + Expression::HanaHierarchy(hierarchy) => Some(&hierarchy.source), + Expression::HanaUpsert(upsert) => Some(&upsert.source), // Unary ops Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this), // UnaryFunc variants @@ -3068,8 +3109,14 @@ impl Expression { pub fn get_expressions(&self) -> &[Expression] { match self { Expression::Select(s) => &s.expressions, - Expression::Function(f) => &f.args, - Expression::AggregateFunction(f) => &f.args, + Expression::Function(f) | Expression::HanaFunction(f) => &f.args, + Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => &f.args, + Expression::HanaTimezone(f) => &f.arguments, + Expression::HanaTableFunction(f) => &f.arguments, + Expression::HanaCall(f) => &f.arguments, + Expression::HanaGrouping(g) => &g.expressions, + Expression::HanaJson(j) => &j.columns, + Expression::HanaJsonColumn(c) => &c.columns, Expression::From(f) => &f.expressions, Expression::GroupBy(g) => &g.expressions, Expression::In(i) => &i.expressions, @@ -3096,8 +3143,12 @@ impl Expression { Expression::Table(t) => &t.name.name, Expression::Literal(lit) => lit.value_str(), Expression::Star(_) => "*", - Expression::Function(f) => &f.name, - Expression::AggregateFunction(f) => &f.name, + Expression::Function(f) | Expression::HanaFunction(f) => &f.name, + Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => &f.name, + Expression::HanaTimezone(f) => &f.name, + Expression::HanaJson(j) => &j.name, + Expression::HanaHierarchy(h) => &h.name, + Expression::HanaRegex(r) => &r.operation, Expression::Alias(a) => a.this.get_name(), Expression::Boolean(b) => { if b.value { @@ -3165,7 +3216,9 @@ impl Expression { | Expression::BitwiseXor(op) => { op.trailing_comments.iter().map(|s| s.as_str()).collect() } - Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(), + Expression::Function(f) | Expression::HanaFunction(f) => { + f.trailing_comments.iter().map(|s| s.as_str()).collect() + } Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(), _ => Vec::new(), } @@ -3693,6 +3746,9 @@ pub struct Select { /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER) #[serde(default, skip_serializing_if = "Vec::is_empty")] pub for_json: Vec, + /// HANA result serialization and trailing query hints. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub hana_options: Option, /// Leading comments before the statement #[serde(default)] pub leading_comments: Vec, @@ -3752,6 +3808,7 @@ impl Select { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), + hana_options: None, leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, @@ -4885,6 +4942,205 @@ pub struct Exists { pub not: bool, } +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaUpsert { + pub table: TableRef, + pub partition: Option, + pub columns: Vec, + pub source: Expression, + pub condition: Option, + pub primary_key: bool, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaPartition { + pub method: String, + pub columns: Vec, + pub partitions: Option, + pub ranges: Vec, + pub primary_key_check: Option, + pub properties: Vec, + pub subpartition: Option>, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaPartitionRange { + pub name: Option, + pub kind: String, + pub values: Vec, + pub dynamic: bool, + pub direction: Option, + pub threshold: Option, + pub interval: Option<(Expression, Option)>, + pub properties: Vec, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaStorageProperty { + pub name: String, + pub values: Vec, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaHierarchy { + pub name: String, + pub source: Expression, + pub start: Option, + pub siblings: Vec, + pub depth: Option, + pub multiparent: Option, + pub orphan: Option, + pub cycle: Option, + pub cache: Option, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaPlaceholder { + pub name: Identifier, + pub value: Expression, +} + +/// Qualified HANA table/calculation-view call; identifier quoting is structural. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaTableFunction { + pub name: Vec, + pub arguments: Vec, +} + +/// HANA JSON path operations retain default and error behavior across AST serialization. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaJson { + pub name: String, + pub input: Expression, + pub path: Expression, + pub columns: Vec, + pub options: HanaJsonOptions, +} + +#[derive( + polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize, +)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaJsonOptions { + pub returning: Option, + pub wrapper: Option, + pub on_empty: Option, + pub on_error: Option, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaBehavior { + /// ERROR, NULL, DEFAULT, EMPTY ARRAY, or EMPTY OBJECT. + pub kind: String, + pub value: Option, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaJsonColumn { + pub name: Option, + pub data_type: Option, + pub path: Option, + pub ordinality: bool, + pub format_json: bool, + pub encoding: Option, + pub columns: Vec, + pub options: HanaJsonOptions, +} + +/// Procedure invocation, including library member calls and asynchronous execution. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaCall { + pub name: Vec, + pub member: Option, + pub arguments: Vec, + pub asynchronous: bool, + pub hints: Vec, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaHint { + pub name: Identifier, + pub arguments: Option>, + pub remote: bool, + pub cascade: bool, +} + +/// HANA PCRE predicate/function grammar. Arguments remain traversable. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaRegex { + pub operation: String, + pub negated: bool, + pub pattern: Expression, + pub subject: Expression, + pub flag: Option, + pub start: Option, + pub occurrence: Option, + pub group: Option, + pub replacement: Option, + pub position_after: Option, +} + +/// Native HANA SELECT clauses, including serialization with no options. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaSelectOptions { + #[serde(default)] + pub total_rowcount: bool, + pub serialization: Option, + pub collation: Option, + pub hints: Vec, +} + +/// HANA grouping-set selection and result delivery options. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaGrouping { + pub kind: String, + pub expressions: Vec, + pub best: Option, + pub limit: Option, + pub offset: Option, + pub subtotal: bool, + pub balance: bool, + pub total: bool, + pub structured: bool, + pub overview: bool, + pub prefix: Option, + pub multiple_resultsets: bool, +} + +/// Time-zone conversion using a HANA time-zone dataset and error policy. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaTimezone { + pub name: String, + pub arguments: Vec, + pub on_error: Option, +} + +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaSerialization { + /// JSON or XML, validated by the HANA parser. + pub format: String, + pub options: Vec<(String, String)>, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub returning: Option, +} + /// Represent a scalar function call (e.g. `UPPER(name)`, `COALESCE(a, b)`). /// /// This is the generic function node. Well-known aggregates, window functions, @@ -5953,6 +6209,11 @@ pub enum DataType { oracle_type: OracleDataType, }, + /// A HANA type whose domain or syntax is not represented by a common type. + Hana { + hana_type: HanaDataType, + }, + // String Char { length: Option, @@ -6103,6 +6364,14 @@ pub enum DataType { Unknown, } +/// Source-specific HANA type, retained until a target is selected. +#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(TS))] +pub struct HanaDataType { + pub name: String, + pub parameters: Vec, +} + impl DataType { /// Canonical unsigned names and their bit-width aliases. Parser entry points /// and legacy Custom-type normalization share this mapping. @@ -7635,6 +7904,10 @@ pub struct CreateTable { /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake) #[serde(default, skip_serializing_if = "Option::is_none")] pub table_modifier: Option, + /// The storage modifier was parsed from HANA rather than another dialect. + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub hana_storage: bool, + pub as_select: Option, /// Whether the AS SELECT was wrapped in parentheses #[serde(default)] @@ -7763,6 +8036,7 @@ impl CreateTable { temporary: false, or_replace: false, table_modifier: None, + hana_storage: false, as_select: None, as_select_parenthesized: false, on_commit: None, @@ -12384,6 +12658,8 @@ pub struct Schema { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct Lock { + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub ignore_locked: bool, #[serde(default)] pub update: Option>, #[serde(default)] diff --git a/crates/polyglot-sql/src/format_tokens.rs b/crates/polyglot-sql/src/format_tokens.rs index 0a655de8..66fa9371 100644 --- a/crates/polyglot-sql/src/format_tokens.rs +++ b/crates/polyglot-sql/src/format_tokens.rs @@ -165,3 +165,54 @@ mod tests { assert_eq!(convert_format_tokens("", TEST_MAPPING), None); } } + +/// Verified HANA datetime tokens shared by the percent-format function families. +/// Unknown alphabetic tokens, precision masks, and unterminated quoted literals +/// are rejected rather than copied into a different format language. +#[cfg(feature = "generate")] +pub(crate) fn hana_datetime_format(input: &str, mysql_style: bool) -> Option { + let mut cursor = FormatTokenCursor::new(input); + let mut result = String::new(); + while let Some(ch) = cursor.peek() { + if ch == '"' { + cursor.next_char(); + loop { + let ch = cursor.next_char()?; + if ch == '"' { + break; + } + if ch == '%' { + result.push('%'); + } + result.push(ch); + } + continue; + } + let mut matched = false; + for (source, target) in [ + ("HH24", "%H"), + ("YYYY", "%Y"), + ("MM", "%m"), + ("DD", "%d"), + ("MI", if mysql_style { "%i" } else { "%M" }), + ("SS", if mysql_style { "%s" } else { "%S" }), + ] { + if cursor.consume_prefix(source, true) { + result.push_str(target); + matched = true; + break; + } + } + if !matched { + if ch.is_ascii_alphabetic() || ch.is_ascii_digit() { + return None; + } + cursor.next_char(); + if ch == '%' { + result.push('%'); + } + result.push(ch); + } + } + Some(result) +} diff --git a/crates/polyglot-sql/src/function_registry.rs b/crates/polyglot-sql/src/function_registry.rs index 15510937..f1d44d1e 100644 --- a/crates/polyglot-sql/src/function_registry.rs +++ b/crates/polyglot-sql/src/function_registry.rs @@ -2243,6 +2243,11 @@ pub(crate) fn is_aggregate_function_name_for_dialect( ) -> bool { let upper = name.to_uppercase(); is_aggregate_function_name(name) + || (dialect == Some(DialectType::HANA) + && matches!( + upper.as_str(), + "AUTO_CORR" | "CROSS_CORR" | "CORR_SPEARMAN" | "DFT" | "NTH_VALUE" | "VAR" + )) || (matches!(dialect, Some(DialectType::DuckDB)) && DUCKDB_AGGREGATE_FUNCTION_NAME_SET.contains(upper.as_str())) } @@ -3061,3 +3066,327 @@ mod tests { ); } } + +/// HANA calls with source-specific semantics or argument grammar. +pub(crate) fn hana_uses_source_node(name: &str) -> bool { + (is_hana_builtin(name) + || matches!( + name, + "HIERARCHY" | "HIERARCHY_SPANTREE" | "CONTAINS" | "FUZZY" + )) + && !matches!( + name, + "COUNT" + | "SUM" + | "MIN" + | "MAX" + | "AVG" + | "CAST" + | "EXTRACT" + | "TRIM" + | "ROW_NUMBER" + | "RANK" + | "DENSE_RANK" + | "LEAD" + | "LAG" + | "NTILE" + | "CUME_DIST" + | "PERCENT_RANK" + ) +} + +/// Built-ins inventoried from HANA Platform 2.0 SPS 08 and Cloud QRC 2/2026. +/// Recognition is separate from target support: a known name is never evidence +/// that a target implements the same operation. +pub(crate) fn is_hana_builtin(name: &str) -> bool { + const NAMES: &[&str] = &[ + "ABAP_ALPHANUM", + "ABAP_DF16RAW_TO_SMALLDECIMAL", + "ABAP_DF34RAW_TO_DECIMAL", + "ABAP_LOWER", + "ABAP_NUMC", + "ABAP_UPPER", + "ABS", + "ACOS", + "ADD_DAYS", + "ADD_MONTHS", + "ADD_MONTHS_LAST", + "ADD_NANO100", + "ADD_SECONDS", + "ADD_WORKDAYS", + "ADD_YEARS", + "AI", + "AI_TEXT_COMPLETION", + "ALLOW_PRECISION_LOSS", + "ASCII", + "ASIN", + "ATAN", + "ATAN2", + "AUTO_CORR", + "AVG", + "BINNING", + "BINTOHEX", + "BINTONHEX", + "BINTOSTR", + "BITAND", + "BITCOUNT", + "BITNOT", + "BITOR", + "BITSET", + "BITUNSET", + "BITXOR", + "CARDINALITY", + "CAST", + "CEIL", + "CHAR", + "COALESCE", + "CONCAT", + "CONCAT_NAZ", + "CONVERT_CURRENCY", + "CONVERT_UNIT", + "CORR", + "CORR_SPEARMAN", + "COS", + "COSH", + "COSINE_SIMILARITY", + "COT", + "COUNT", + "CROSS_CORR", + "CUBIC_SPLINE_APPROX", + "CUME_DIST", + "CURRENT_CONNECTION", + "CURRENT_DATABASE", + "CURRENT_DATE", + "CURRENT_IDENTITY_VALUE", + "CURRENT_MVCC_SNAPSHOT_TIMESTAMP", + "CURRENT_OBJECT_SCHEMA", + "CURRENT_ROLEGROUP", + "CURRENT_SCHEMA", + "CURRENT_SITE_ID", + "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "CURRENT_TRANSACTION_ISOLATION_LEVEL", + "CURRENT_UPDATE_STATEMENT_SEQUENCE", + "CURRENT_UPDATE_TRANSACTION", + "CURRENT_USER", + "CURRENT_USERGROUP", + "CURRENT_USER_ID", + "CURRENT_UTCDATE", + "CURRENT_UTCTIME", + "CURRENT_UTCTIMESTAMP", + "DAYNAME", + "DAYOFMONTH", + "DAYOFYEAR", + "DAYS_BETWEEN", + "DENSE_RANK", + "DFT", + "ESCAPE_DOUBLE_QUOTES", + "ESCAPE_SINGLE_QUOTES", + "EXP", + "EXPRESSION_MACRO", + "EXTRACT", + "FIRST_VALUE", + "FLOOR", + "GENERATE_PASSWORD", + "GET_DELTA_LAKE_TABLE_CHANGES", + "GET_DELTA_LAKE_TABLE_VERSION", + "GREATEST", + "GROUPING", + "GROUPING_ID", + "GROUP_SCORE", + "HAMMING_DISTANCE", + "HASH_MD5", + "HASH_SHA256", + "HEXTOBIN", + "HEXTONUM", + "HOUR", + "IFNULL", + "INDEXING_ERROR_CODE", + "INDEXING_ERROR_MESSAGE", + "INDEXING_STATUS", + "INITCAP", + "ISOWEEK", + "IS_SQL_INJECTION_SAFE", + "JSON", + "JSON_QUERY", + "JSON_TABLE", + "JSON_VALUE", + "L2DISTANCE", + "L2NORM", + "L2NORMALIZE", + "LAG", + "LANGUAGE", + "LAST_DAY", + "LAST_VALUE", + "LCASE", + "LEAD", + "LEAST", + "LEFT", + "LENGTH", + "LINEAR_APPROX", + "LN", + "LOCALTOUTC", + "LOCATE", + "LOCATE_REGEXPR", + "LOG", + "LOWER", + "LPAD", + "LTRIM", + "MAP", + "MAX", + "MEDIAN", + "MEMBER_AT", + "MIMETYPE", + "MIN", + "MINUTE", + "MOD", + "MONTH", + "MONTHNAME", + "MONTHS_BETWEEN", + "NANO100_BETWEEN", + "NCHAR", + "NDIV0", + "NEWUID", + "NEXT_DAY", + "NORMALIZE", + "NOW", + "NTH_VALUE", + "NTILE", + "NULLIF", + "NUMTOHEX", + "OCCURRENCES_REGEXPR", + "PARSE_CERTIFICATES", + "PARSE_JSON", + "PARTITION_ALLOCATION", + "PARTITION_HASH", + "PERCENTILE_CONT", + "PERCENTILE_DISC", + "PERCENT_RANK", + "PLAINTEXT", + "POWER", + "QUARTER", + "RAND", + "RANDOM_PARTITION", + "RAND_SECURE", + "RANK", + "RECORD_COMMIT_TIMESTAMP", + "RECORD_ID", + "REPLACE", + "REPLACE_REGEXPR", + "RESULT_CACHE_ID", + "RESULT_CACHE_REFRESH_TIME", + "RIGHT", + "ROUND", + "ROW_NUMBER", + "RPAD", + "RTRIM", + "SCORE", + "SECOND", + "SECONDS_BETWEEN", + "SERIES_DISAGGREGATE", + "SERIES_ELEMENT_TO_PERIOD", + "SERIES_FILTER", + "SERIES_GENERATE", + "SERIES_PERIOD_TO_ELEMENT", + "SERIES_ROUND", + "SESSION_CONTEXT", + "SESSION_USER", + "SIGN", + "SIN", + "SINH", + "SOUNDEX", + "SQL", + "SQRT", + "STATEMENT_EXECUTION_HOST", + "STATEMENT_EXECUTION_PORT", + "STDDEV", + "STDDEV_POP", + "STDDEV_SAMP", + "STRING_AGG", + "STRTOBIN", + "SUBARRAY", + "SUBSTR", + "SUBSTRING", + "SUBSTRING_REGEXPR", + "SUBSTR_AFTER", + "SUBSTR_BEFORE", + "SUBSTR_REGEXPR", + "SUBVECTOR", + "SUM", + "SYSUUID", + "TAN", + "TANH", + "TO_ALPHANUM", + "TO_ARRAY", + "TO_BIGINT", + "TO_BINARY", + "TO_BLOB", + "TO_BOOLEAN", + "TO_CLOB", + "TO_DATE", + "TO_DATS", + "TO_DECIMAL", + "TO_DOUBLE", + "TO_FIXEDCHAR", + "TO_HALF_VECTOR", + "TO_INT", + "TO_INTEGER", + "TO_NCLOB", + "TO_NVARCHAR", + "TO_REAL", + "TO_REAL_VECTOR", + "TO_SECONDDATE", + "TO_SMALLDECIMAL", + "TO_SMALLINT", + "TO_TIME", + "TO_TIMESTAMP", + "TO_TINYINT", + "TO_VARBINARY", + "TO_VARCHAR", + "TRIM", + "TRIM_ARRAY", + "UCASE", + "UMINUS", + "UNICODE", + "UPPER", + "UTCTOLOCAL", + "VALIDATE_USERGROUP_CONNECT_RESTRICTION", + "VALIDATE_USERGROUP_CONNECT_RESTRICTION_DETAILS", + "VAR", + "VAR_POP", + "VAR_SAMP", + "VECTOR_EMBEDDING", + "WEEK", + "WEEKDAY", + "WEIGHTED_AVG", + "WIDTH_BUCKET", + "WORKDAYS_BETWEEN", + "XMLEXTRACT", + "XMLEXTRACTVALUE", + "XMLTABLE", + "YEAR", + "YEARS_BETWEEN", + ]; + NAMES.binary_search(&name).is_ok() + || matches!( + name, + "SERIES_GENERATE_INTEGER" + | "SERIES_GENERATE_DECIMAL" + | "SERIES_GENERATE_DATE" + | "SERIES_GENERATE_TIME" + | "SERIES_GENERATE_TIMESTAMP" + | "SUBSTR_REGEXPR" + | "SERIES_DISAGGREGATE_BIGINT" + | "SERIES_DISAGGREGATE_DATE" + | "SERIES_DISAGGREGATE_DECIMAL" + | "SERIES_DISAGGREGATE_INTEGER" + | "SERIES_DISAGGREGATE_SECONDDATE" + | "SERIES_DISAGGREGATE_SMALLDECIMAL" + | "SERIES_DISAGGREGATE_SMALLINT" + | "SERIES_DISAGGREGATE_TIME" + | "SERIES_DISAGGREGATE_TIMESTAMP" + | "SERIES_DISAGGREGATE_TINYINT" + | "ST_GEOMFROMTEXT" + | "ST_GEOMFROMWKB" + ) +} diff --git a/crates/polyglot-sql/src/generator.rs b/crates/polyglot-sql/src/generator.rs index cfb57ee1..c58bb010 100644 --- a/crates/polyglot-sql/src/generator.rs +++ b/crates/polyglot-sql/src/generator.rs @@ -2547,6 +2547,35 @@ impl Generator { } fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> { + if self.config.dialect == Some(DialectType::HANA) + && matches!( + expr, + Expression::Raw(_) + | Expression::Command(_) + | Expression::ILike(_) + | Expression::DateAdd(_) + | Expression::DateSub(_) + | Expression::DateDiff(_) + | Expression::TimestampAdd(_) + | Expression::TimestampSub(_) + | Expression::TimestampDiff(_) + | Expression::StrToDate(_) + | Expression::StrToTime(_) + | Expression::TimeToStr(_) + | Expression::ToNumber(_) + | Expression::Substring(_) + | Expression::StrPosition(_) + | Expression::CurrentDate(_) + | Expression::CurrentTime(_) + | Expression::CurrentTimestamp(_) + ) + { + return Err(self.hana_unsupported(format!( + "{} requires a verified conversion to HANA semantics", + expr.variant_name() + ))); + } + match expr { Expression::Select(select) => self.generate_select(select), Expression::Union(union) => self.generate_union(union), @@ -2579,6 +2608,90 @@ impl Generator { Expression::Collation(coll) => self.generate_collation(coll), Expression::Case(case) => self.generate_case(case), Expression::Function(func) => self.generate_function(func), + Expression::HanaFunction(func) => self.generate_hana_function(func), + Expression::HanaGrouping(grouping) => self.generate_hana_grouping(grouping), + Expression::HanaTimezone(timezone) => self.generate_hana_timezone(timezone), + Expression::HanaRegex(regex) => self.generate_hana_regex(regex), + Expression::HanaJson(json) => self.generate_hana_json(json), + Expression::HanaJsonColumn(column) => self.generate_hana_json_column(column), + Expression::HanaUpsert(upsert) => self.generate_hana_upsert(upsert), + Expression::HanaHierarchy(hierarchy) => self.generate_hana_hierarchy(hierarchy), + Expression::HanaCall(call) => self.generate_hana_call(call), + Expression::HanaHint(hint) => { + if self.config.dialect != Some(DialectType::HANA) { + return Err( + self.hana_unsupported("HANA optimizer hint has no verified target mapping") + ); + } + self.generate_identifier(&hint.name)?; + if let Some(arguments) = &hint.arguments { + self.write("("); + for (i, arg) in arguments.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(arg)?; + } + self.write(")"); + } + if hint.remote { + self.write(" REMOTE"); + } + if hint.cascade { + self.write(" CASCADE"); + } + Ok(()) + } + Expression::HanaTableFunction(function) => { + for (i, name) in function.name.iter().enumerate() { + if i > 0 { + self.write("."); + } + self.generate_identifier(name)?; + } + self.write("("); + for (i, argument) in function.arguments.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(argument)?; + } + self.write(")"); + Ok(()) + } + Expression::HanaPlaceholder(placeholder) => { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported( + "HANA calculation-view PLACEHOLDER has no verified target mapping", + )); + } + self.write("PLACEHOLDER."); + self.generate_identifier(&placeholder.name)?; + self.write(" => "); + self.generate_expression(&placeholder.value) + } + Expression::HanaPartition(partition) => self.generate_hana_partition(partition, false), + Expression::HanaStorageProperty(property) => { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self + .hana_unsupported("HANA storage property has no verified target mapping")); + } + self.write(&property.name); + for value in &property.values { + self.write(" "); + self.generate_expression(value)?; + } + Ok(()) + } + Expression::HanaAggregateFunction(func) => { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported(format!( + "HANA aggregate {} has no verified target mapping", + func.name + ))); + } + self.generate_aggregate_function(func) + } Expression::FunctionEmits(fe) => self.generate_function_emits(fe), Expression::AggregateFunction(func) => self.generate_aggregate_function(func), Expression::WindowFunction(wf) => self.generate_window_function(wf), @@ -4665,6 +4778,15 @@ impl Generator { } fn generate_select(&mut self, select: &Select) -> Result<()> { + if (select.hana_options.is_some() || select.locks.iter().any(|lock| lock.ignore_locked)) + && self.config.dialect != Some(DialectType::HANA) + { + return Err(crate::error::Error::unsupported( + "HANA SELECT serialization or hints have no verified target mapping", + self.config.dialect.unwrap_or_default().to_string(), + )); + } + use crate::dialects::DialectType; if let Some(resolved_select) = self.resolve_tsql_null_ordering_for_select(select) { @@ -5043,6 +5165,8 @@ impl Generator { self.write_formatted_comment(comment); } } + } else if self.config.dialect == Some(DialectType::HANA) { + self.write(" FROM DUMMY"); } // JOINs - handle nested join structure for pretty printing @@ -5748,6 +5872,14 @@ impl Generator { } } + if select + .hana_options + .as_ref() + .is_some_and(|o| o.total_rowcount) + { + self.write(" TOTAL ROWCOUNT"); + } + // FOR UPDATE/SHARE locks // Skip locking clauses for dialects that don't support them if self.config.locking_reads_supported { @@ -5762,6 +5894,47 @@ impl Generator { } } + if let Some(options) = &select.hana_options { + if let Some(serialization) = &options.serialization { + self.write(" FOR "); + self.write(&serialization.format); + if !serialization.options.is_empty() { + self.write(" ("); + for (i, (key, value)) in serialization.options.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_string_literal(key)?; + self.write(" = "); + self.generate_string_literal(value)?; + } + self.write(")"); + } + } + if let Some(returning) = options + .serialization + .as_ref() + .and_then(|s| s.returning.as_ref()) + { + self.write(" RETURNS "); + self.generate_data_type(returning)?; + } + if let Some(collation) = &options.collation { + self.write(" WITH COLLATION "); + self.generate_identifier(collation)?; + } + if !options.hints.is_empty() { + self.write(" WITH HINT ("); + for (i, hint) in options.hints.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(hint)?; + } + self.write(")"); + } + } + // FOR XML clause (T-SQL) if !select.for_xml.is_empty() { if self.config.pretty { @@ -8477,6 +8650,18 @@ impl Generator { // ==================== DDL Generation ==================== fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> { + if ct.hana_storage + && self.config.dialect != Some(DialectType::HANA) + && ct.table_modifier.as_ref().is_some_and(|m| { + m.split_whitespace() + .any(|part| matches!(part, "COLUMN" | "ROW" | "LOCAL" | "GLOBAL")) + }) + { + return Err( + self.hana_unsupported("HANA table storage/scope has no verified target mapping") + ); + } + // Athena: Determine if this is Hive-style DDL or Trino-style DML // CREATE TABLE AS SELECT uses Trino (double quotes) // CREATE TABLE (without AS SELECT) and CREATE EXTERNAL TABLE use Hive (backticks) @@ -8553,7 +8738,13 @@ impl Generator { self.write_keyword("OR REPLACE"); } - if ct.temporary { + if ct.temporary + && !(self.config.dialect == Some(DialectType::HANA) + && ct + .table_modifier + .as_ref() + .is_some_and(|m| m.contains("TEMPORARY"))) + { self.write_space(); // Oracle uses GLOBAL TEMPORARY TABLE syntax if matches!(self.config.dialect, Some(DialectType::Oracle)) { @@ -11745,7 +11936,10 @@ impl Generator { AlterTableAction::AddColumns { columns, cascade } => { // Oracle uses ADD (...) without COLUMNS keyword // Hive/Spark uses ADD COLUMNS (...) - let is_oracle = matches!(self.config.dialect, Some(DialectType::Oracle)); + let is_oracle = matches!( + self.config.dialect, + Some(DialectType::Oracle | DialectType::HANA) + ); if is_oracle { self.write_keyword("ADD"); } else { @@ -18050,6 +18244,37 @@ impl Generator { } fn generate_cast(&mut self, cast: &Cast) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + if let DataType::Hana { hana_type } = &cast.to { + if hana_type.name == "DECIMAL" { + let mut args = vec![cast.this.clone()]; + args.extend( + hana_type + .parameters + .iter() + .map(|n| Expression::number(i64::from(*n))), + ); + if hana_type.parameters.len() == 1 { + args.push(Expression::number(0)); + } + return self.generate_hana_function(&Function::new("TO_DECIMAL", args)); + } + if hana_type.name == "TINYINT" + && matches!( + self.config.dialect, + Some(DialectType::Trino | DialectType::Presto | DialectType::PostgreSQL) + ) + { + if Self::hana_integer(&cast.this).is_some_and(|n| (0..=255).contains(&n)) { + self.write("CAST("); + self.generate_expression(&cast.this)?; + self.write(" AS SMALLINT)"); + return Ok(()); + } + } + } + } + use crate::dialects::DialectType; // SingleStore uses :> syntax @@ -18582,7 +18807,762 @@ impl Generator { Ok(()) } + fn generate_hana_partition( + &mut self, + partition: &HanaPartition, + subpartition: bool, + ) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported("HANA partitioning has no verified target mapping")); + } + self.write(if subpartition { + "SUBPARTITION BY " + } else { + "PARTITION BY " + }); + self.write(&partition.method); + if !partition.columns.is_empty() { + self.write(" ("); + for (i, column) in partition.columns.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(column)?; + } + self.write(")"); + } + if let Some(check) = partition.primary_key_check { + self.write(if check { + " PRIMARY KEY CHECK" + } else { + " NO PRIMARY KEY CHECK" + }); + } + if let Some(count) = &partition.partitions { + self.write(" PARTITIONS "); + self.generate_expression(count)?; + } + if !partition.ranges.is_empty() { + self.write(" ("); + for (i, range) in partition.ranges.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.write("PARTITION "); + if let Some(name) = &range.name { + self.generate_identifier(name)?; + self.write(" "); + } + match range.kind.as_str() { + "OTHERS" => self.write("OTHERS"), + "RANGE" if range.values.len() == 2 => { + self.generate_expression(&range.values[0])?; + self.write(" <= VALUES < "); + self.generate_expression(&range.values[1])?; + } + "LESS" | "AT_LEAST" | "VALUE" if range.values.len() == 1 => { + self.write(match range.kind.as_str() { + "LESS" => "VALUES < ", + "AT_LEAST" => "VALUES >= ", + _ => "VALUES = ", + }); + self.generate_expression(&range.values[0])?; + } + _ => return Err(self.hana_unsupported("Invalid HANA partition range AST")), + } + if range.dynamic { + self.write(" DYNAMIC"); + } + if let Some(direction) = &range.direction { + self.write(" "); + self.write(direction); + } + if let Some(threshold) = &range.threshold { + self.write(" THRESHOLD "); + self.generate_expression(threshold)?; + } + if let Some((value, unit)) = &range.interval { + self.write(" INTERVAL "); + self.generate_expression(value)?; + if let Some(unit) = unit { + self.write(" "); + self.write(unit); + } + } + for property in &range.properties { + self.write(" "); + self.generate_expression(property)?; + } + } + self.write(")"); + } + for property in &partition.properties { + self.write(" "); + self.generate_expression(property)?; + } + if let Some(sub) = &partition.subpartition { + self.write(" "); + self.generate_hana_partition(sub, true)?; + } + Ok(()) + } + + fn generate_hana_call(&mut self, call: &HanaCall) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err( + self.hana_unsupported("HANA CALL requires a verified target procedure signature") + ); + } + self.write("CALL "); + for (i, name) in call.name.iter().enumerate() { + if i > 0 { + self.write("."); + } + self.generate_identifier(name)?; + } + if let Some(member) = &call.member { + self.write(":"); + self.generate_identifier(member)?; + } + self.write("("); + for (i, argument) in call.arguments.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(argument)?; + } + self.write(")"); + if call.asynchronous { + self.write(" ASYNC"); + } + if !call.hints.is_empty() { + self.write(" WITH HINT ("); + for (i, hint) in call.hints.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(hint)?; + } + self.write(")"); + } + Ok(()) + } + + fn generate_hana_json(&mut self, json: &HanaJson) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported( + "HANA JSON path and error semantics have no verified target mapping", + )); + } + self.write(&json.name); + self.write("("); + self.generate_expression(&json.input)?; + self.write(", "); + self.generate_expression(&json.path)?; + if !json.columns.is_empty() { + self.generate_hana_json_columns(&json.columns)?; + } + self.generate_hana_json_options(&json.options)?; + self.write(")"); + Ok(()) + } + + fn generate_hana_json_columns(&mut self, columns: &[Expression]) -> Result<()> { + self.write(" COLUMNS ("); + for (i, column) in columns.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(column)?; + } + self.write(")"); + Ok(()) + } + + fn generate_hana_json_column(&mut self, column: &HanaJsonColumn) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err( + self.hana_unsupported("HANA JSON_TABLE column has no verified target mapping") + ); + } + if let Some(name) = &column.name { + self.generate_identifier(name)?; + } else { + self.write("NESTED"); + } + if column.ordinality { + self.write(" FOR ORDINALITY"); + } + if let Some(data_type) = &column.data_type { + self.write(" "); + self.generate_data_type(data_type)?; + } + if column.format_json { + self.write(" FORMAT JSON"); + } + if let Some(encoding) = &column.encoding { + self.write(" ENCODING "); + self.write(encoding); + } + if let Some(path) = &column.path { + self.write(" PATH "); + self.generate_expression(path)?; + } + if !column.columns.is_empty() { + self.generate_hana_json_columns(&column.columns)?; + } + self.generate_hana_json_options(&column.options) + } + + fn generate_hana_json_options(&mut self, options: &HanaJsonOptions) -> Result<()> { + if let Some(returning) = &options.returning { + self.write(" RETURNING "); + self.generate_data_type(returning)?; + } + if let Some(wrapper) = &options.wrapper { + self.write(" "); + self.write(wrapper); + self.write(" WRAPPER"); + } + for (behavior, suffix) in [ + (&options.on_empty, " ON EMPTY"), + (&options.on_error, " ON ERROR"), + ] { + if let Some(behavior) = behavior { + self.write(" "); + self.write(&behavior.kind); + if let Some(value) = &behavior.value { + self.write(" "); + self.generate_expression(value)?; + } + self.write(suffix); + } + } + Ok(()) + } + + fn generate_hana_hierarchy(&mut self, hierarchy: &HanaHierarchy) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported("HANA hierarchy has no verified target mapping")); + } + self.write(&hierarchy.name); + self.write("(SOURCE "); + self.generate_expression(&hierarchy.source)?; + if let Some(start) = &hierarchy.start { + self.write(" START WHERE "); + self.generate_expression(start)?; + } + if !hierarchy.siblings.is_empty() { + self.write(" SIBLING ORDER BY "); + for (i, order) in hierarchy.siblings.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_ordered(order)?; + } + } + if let Some(depth) = &hierarchy.depth { + self.write(" DEPTH "); + self.generate_expression(depth)?; + } + for (keyword, option) in [ + ("MULTIPARENT", &hierarchy.multiparent), + ("ORPHAN", &hierarchy.orphan), + ("CYCLE", &hierarchy.cycle), + ] { + if let Some(option) = option { + self.write(" "); + self.write(keyword); + if !option.is_empty() { + self.write(" "); + self.write(option); + } + } + } + if let Some(cache) = &hierarchy.cache { + self.write(" "); + self.write(cache); + } + self.write(")"); + Ok(()) + } + + fn generate_hana_upsert(&mut self, upsert: &HanaUpsert) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported( + "HANA UPSERT requires target-specific key and update semantics", + )); + } + self.write("UPSERT "); + self.generate_table(&upsert.table)?; + if let Some(partition) = &upsert.partition { + self.write(" PARTITION ("); + self.generate_expression(partition)?; + self.write(")"); + } + if !upsert.columns.is_empty() { + self.write(" ("); + for (i, column) in upsert.columns.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_identifier(column)?; + } + self.write(")"); + } + self.write(" "); + self.generate_expression(&upsert.source)?; + if let Some(condition) = &upsert.condition { + self.write(" WHERE "); + self.generate_expression(condition)?; + } + if upsert.primary_key { + self.write(" WITH PRIMARY KEY"); + } + Ok(()) + } + + fn generate_hana_regex(&mut self, regex: &HanaRegex) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported("HANA PCRE operation has no verified target mapping")); + } + let predicate = regex.operation == "LIKE_REGEXPR"; + if predicate { + self.generate_expression(®ex.subject)?; + self.write(if regex.negated { + " NOT LIKE_REGEXPR " + } else { + " LIKE_REGEXPR " + }); + } else { + self.write(®ex.operation); + self.write("("); + if let Some(after) = regex.position_after { + self.write(if after { "AFTER " } else { "START " }); + } + } + self.generate_expression(®ex.pattern)?; + if let Some(flag) = ®ex.flag { + self.write(" FLAG "); + self.generate_expression(flag)?; + } + if !predicate { + self.write(" IN "); + self.generate_expression(®ex.subject)?; + } + for (keyword, argument) in [ + (" WITH ", ®ex.replacement), + (" FROM ", ®ex.start), + (" OCCURRENCE ", ®ex.occurrence), + (" GROUP ", ®ex.group), + ] { + if let Some(argument) = argument { + self.write(keyword); + self.generate_expression(argument)?; + } + } + if !predicate { + self.write(")"); + } + Ok(()) + } + + fn hana_integer(expr: &Expression) -> Option { + match expr { + Expression::Literal(l) => match l.as_ref() { + Literal::Number(n) => n.parse().ok(), + _ => None, + }, + Expression::Neg(n) => Self::hana_integer(&n.this)?.checked_neg(), + _ => None, + } + } + + fn hana_exact_numeric(expr: &Expression) -> bool { + match expr { + Expression::Literal(l) => { + matches!(l.as_ref(), Literal::Number(n) if !n.contains(['e', 'E'])) + } + Expression::Neg(n) => Self::hana_exact_numeric(&n.this), + Expression::Cast(c) => { + matches!( + &c.to, + DataType::Decimal { + precision: Some(_), + .. + } + ) || matches!(&c.to, DataType::Hana { hana_type } if hana_type.name == "DECIMAL" && !hana_type.parameters.is_empty()) + } + _ => false, + } + } + + fn hana_portable_string(expr: &Expression) -> bool { + // HANA indexes CESU-8/UTF-16 units; these targets index Unicode code + // points. Unknown/binary/supplementary-character inputs need another mapping. + matches!(expr, Expression::Literal(l) if matches!(l.as_ref(), Literal::String(s) | Literal::NationalString(s) if s.chars().all(|c| (c as u32) <= 0xffff))) + } + + fn hana_unsupported(&self, feature: impl Into) -> crate::error::Error { + crate::error::Error::unsupported( + feature, + self.config.dialect.unwrap_or_default().to_string(), + ) + } + + fn generate_hana_grouping(&mut self, grouping: &HanaGrouping) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err( + self.hana_unsupported("HANA grouping-set selection and result delivery options") + ); + } + self.write(&grouping.kind); + for (keyword, value) in [ + (" BEST ", &grouping.best), + (" LIMIT ", &grouping.limit), + (" OFFSET ", &grouping.offset), + ] { + if let Some(value) = value { + self.write(keyword); + self.generate_expression(value)?; + } + } + for (enabled, keyword) in [ + (grouping.subtotal, " WITH SUBTOTAL"), + (grouping.balance, " WITH BALANCE"), + (grouping.total, " WITH TOTAL"), + (grouping.structured, " STRUCTURED RESULT"), + (grouping.overview, " WITH OVERVIEW"), + ] { + if enabled { + self.write(keyword); + } + } + if let Some(prefix) = &grouping.prefix { + self.write(" PREFIX "); + self.generate_expression(prefix)?; + } + if grouping.multiple_resultsets { + self.write(" MULTIPLE RESULTSETS"); + } + self.write(" ("); + for (i, expression) in grouping.expressions.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(expression)?; + } + self.write(")"); + Ok(()) + } + + fn generate_hana_timezone(&mut self, timezone: &HanaTimezone) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported("HANA timezone datasets and conversion error policy")); + } + self.write(&timezone.name); + self.write("("); + for (i, argument) in timezone.arguments.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(argument)?; + } + if let Some(behavior) = &timezone.on_error { + self.write(" "); + self.write(&behavior.kind); + if let Some(value) = &behavior.value { + self.write(" "); + self.generate_expression(value)?; + } + self.write(" ON ERROR"); + } + self.write(")"); + Ok(()) + } + + fn generate_hana_function(&mut self, function: &Function) -> Result<()> { + if function.quoted { + let mut identifier = Identifier::new(&function.name); + identifier.quoted = true; + self.generate_identifier(&identifier)?; + self.write("("); + for (i, arg) in function.args.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(arg)?; + } + self.write(")"); + return Ok(()); + } + if self.config.dialect == Some(DialectType::HANA) { + return self.generate_function(function); + } + let name = function.name.to_ascii_uppercase(); + let args = &function.args; + let target = self.config.dialect.unwrap_or_default(); + let trino = matches!( + target, + DialectType::Trino | DialectType::Presto | DialectType::Athena | DialectType::Dune + ); + let postgres = matches!( + target, + DialectType::PostgreSQL + | DialectType::CockroachDB + | DialectType::Materialize + | DialectType::RisingWave + ); + let duckdb = target == DialectType::DuckDB; + + // These calls are retained as source nodes until generation so parsing, + // JSON serialization, and native transpilation cannot lose HANA semantics. + if matches!(name.as_str(), "COALESCE" | "IFNULL") && args.len() >= 2 { + return self.generate_vararg_func("COALESCE", args); + } + if name == "LOCATE" && (2..=4).contains(&args.len()) && (trino || postgres || duckdb) { + let start = if args.len() >= 3 { + Self::hana_integer(&args[2]) + } else { + Some(1) + }; + let occurrence = if args.len() == 4 { + Self::hana_integer(&args[3]) + } else { + Some(1) + }; + if let (Some(start), Some(occurrence)) = (start, occurrence) { + if start >= 0 + && occurrence > 0 + && (trino || occurrence == 1) + && args[..2].iter().all(Self::hana_portable_string) + && (!matches!(&args[1], Expression::Literal(l) if matches!(l.as_ref(), Literal::String(s) | Literal::NationalString(s) if s.is_empty())) + || (start <= 1 && occurrence == 1)) + { + let haystack = self.generate_to_string(&args[0])?; + let needle = self.generate_to_string(&args[1])?; + let start = start.max(1); + let searched = if start == 1 { + haystack + } else { + format!("SUBSTR({haystack}, {start})") + }; + let found = if trino && occurrence != 1 { + format!("STRPOS({searched}, {needle}, {occurrence})") + } else { + format!("STRPOS({searched}, {needle})") + }; + if start == 1 { + self.write(&found); + } else { + self.write(&format!( + "CASE WHEN {found} = 0 THEN 0 ELSE {found} + {} END", + start - 1 + )); + } + return Ok(()); + } + } + } + if matches!(name.as_str(), "SUBSTRING" | "SUBSTR") + && (2..=3).contains(&args.len()) + && (trino || postgres || duckdb) + && Self::hana_portable_string(&args[0]) + { + // Constant bounds avoid changing NULL propagation or evaluating a + // volatile bound more than once. Dynamic/binary cases need a typed mapping. + if let Some(start) = Self::hana_integer(&args[1]) { + let length = args.get(2).map(Self::hana_integer); + if !matches!(length, Some(None)) { + let mut lowered = vec![args[0].clone(), Expression::number(start.max(1))]; + if let Some(Some(length)) = length { + lowered.push(Expression::number(length.max(0))); + } + return self.generate_vararg_func("SUBSTRING", &lowered); + } + } + } + if name == "TO_DECIMAL" && args.len() == 3 && (trino || postgres || duckdb) { + if let (Some(precision), Some(scale)) = + (Self::hana_integer(&args[1]), Self::hana_integer(&args[2])) + { + if (1..=38).contains(&precision) && (0..=precision).contains(&scale) { + // Require numeric input evidence. Casting an unknown string + // before truncation can round away digits or change format rules. + let numeric = Self::hana_exact_numeric(&args[0]); + if numeric { + let value = self.generate_to_string(&args[0])?; + let truncate = if trino { "TRUNCATE" } else { "TRUNC" }; + self.write(&format!( + "CAST({truncate}({value}, {scale}) AS DECIMAL({precision}, {scale}))" + )); + return Ok(()); + } + } + } + } + if matches!( + name.as_str(), + "TO_DATE" | "TO_TIMESTAMP" | "TO_VARCHAR" | "TO_NVARCHAR" + ) && args.len() == 2 + && (trino || duckdb) + && (name != "TO_TIMESTAMP" || target == DialectType::Trino) + { + if let Expression::Literal(literal) = &args[1] { + if let Literal::String(mask) = literal.as_ref() { + if let Some(mask) = crate::format_tokens::hana_datetime_format(mask, trino) { + let formatting = matches!(name.as_str(), "TO_VARCHAR" | "TO_NVARCHAR"); + let known_datetime = matches!(&args[0], Expression::Cast(c) if matches!(c.to, DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. })) + || matches!(&args[0], Expression::Cast(c) if matches!(&c.to, DataType::Hana { hana_type } if matches!(hana_type.name.as_str(), "TIMESTAMP" | "TIME" | "SECONDDATE"))) + || matches!(&args[0], Expression::Literal(l) if matches!(l.as_ref(), Literal::Date(_) | Literal::Timestamp(_))); + if !formatting || known_datetime { + let value = self.generate_to_string(&args[0])?; + let mask = self.generate_to_string(&Expression::string(mask))?; + if formatting { + let function = if trino { "DATE_FORMAT" } else { "STRFTIME" }; + self.write(&format!("{function}({value}, {mask})")); + } else { + let function = if trino { "DATE_PARSE" } else { "STRPTIME" }; + let result_type = if name == "TO_DATE" { + "DATE" + } else if trino { + "TIMESTAMP(7)" + } else { + "TIMESTAMP" + }; + self.write(&format!( + "CAST({function}({value}, {mask}) AS {result_type})" + )); + } + return Ok(()); + } + } + } + } + } + if matches!( + name.as_str(), + "CURRENT_UTCDATE" | "CURRENT_UTCTIME" | "CURRENT_UTCTIMESTAMP" + ) && (trino || postgres || duckdb) + { + let precision = if args.is_empty() { + Some(3) + } else if args.len() == 1 { + Self::hana_integer(&args[0]) + } else { + None + }; + if let Some(precision) = precision { + if (0..=7).contains(&precision) + && (target == DialectType::Trino || name == "CURRENT_UTCDATE") + { + let utc = if trino && name == "CURRENT_UTCTIMESTAMP" { + format!("CURRENT_TIMESTAMP({precision}) AT TIME ZONE 'UTC'") + } else { + "CURRENT_TIMESTAMP AT TIME ZONE 'UTC'".to_owned() + }; + let data_type = match name.as_str() { + "CURRENT_UTCDATE" => "DATE".to_owned(), + "CURRENT_UTCTIME" => "TIME(0)".to_owned(), + _ => format!("TIMESTAMP({precision})"), + }; + self.write(&format!("CAST({utc} AS {data_type})")); + return Ok(()); + } + } + } + Err(self.hana_unsupported(format!( + "HANA {name}: no verified mapping for these arguments" + ))) + } + + fn generate_hana_data_type(&mut self, data_type: &HanaDataType) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + let target = self.config.dialect.unwrap_or_default(); + match (data_type.name.as_str(), data_type.parameters.as_slice()) { + ("TIMESTAMP", []) if target == DialectType::Trino => { + self.write("TIMESTAMP(7)"); + return Ok(()); + } + ("TIME", []) if target == DialectType::Trino => { + self.write("TIME(0)"); + return Ok(()); + } + ("FLOAT", [] | [1..=53]) + if matches!( + target, + DialectType::Trino + | DialectType::Presto + | DialectType::DuckDB + | DialectType::PostgreSQL + ) => + { + let real = data_type.parameters.first().is_some_and(|p| *p <= 24); + self.write(if real { + "REAL" + } else if target == DialectType::PostgreSQL { + "DOUBLE PRECISION" + } else { + "DOUBLE" + }); + return Ok(()); + } + ("TINYINT", []) + if matches!(target, DialectType::DuckDB | DialectType::ClickHouse) => + { + return self.generate_data_type(&DataType::UInt8); + } + ("DECIMAL", [p, s]) if (1..=38).contains(p) && s <= p => { + return self.generate_data_type(&DataType::Decimal { + precision: Some(*p), + scale: Some(*s), + }); + } + _ => {} + } + return Err(crate::error::Error::unsupported( + format!( + "HANA {} has no lossless type mapping for this target", + data_type.name + ), + self.config.dialect.unwrap_or_default().to_string(), + )); + } + self.write(&data_type.name); + if !data_type.parameters.is_empty() { + self.write("("); + for (i, parameter) in data_type.parameters.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.write(¶meter.to_string()); + } + self.write(")"); + } + Ok(()) + } + fn generate_function(&mut self, func: &Function) -> Result<()> { + if self.config.dialect == Some(DialectType::HANA) + && !func.quoted + && matches!( + func.name.to_ascii_uppercase().as_str(), + "DATE_ADD" + | "DATE_SUB" + | "DATE_DIFF" + | "DATEADD" + | "DATEDIFF" + | "STRFTIME" + | "STRPTIME" + | "DATE_PARSE" + | "DATE_FORMAT" + ) + { + return Err(self.hana_unsupported(format!( + "{} requires a verified conversion to HANA semantics", + func.name + ))); + } // Normalize function name based on dialect settings let normalized_name = if func.name.eq_ignore_ascii_case("GROUPING") && func.args.len() > 1 @@ -26192,6 +27172,7 @@ impl Generator { } } } + DataType::Hana { hana_type } => self.generate_hana_data_type(hana_type)?, DataType::Oracle { oracle_type } => { self.write_oracle_data_type(oracle_type)?; } @@ -26779,6 +27760,10 @@ impl Generator { } => { // Dialect-specific array syntax match self.config.dialect { + Some(DialectType::HANA) => { + self.generate_data_type(element_type)?; + self.write(" ARRAY"); + } Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::DuckDB) => { @@ -29821,6 +30806,12 @@ impl Generator { /// Handles MySQL/PostgreSQL: GENERATED ALWAYS AS (expr) STORED|VIRTUAL /// Handles TSQL: AS (expr) [PERSISTED] [NOT NULL] fn generate_computed_column_inline(&mut self, cc: &ComputedColumn) -> Result<()> { + if self.config.dialect == Some(DialectType::HANA) { + self.write("GENERATED ALWAYS AS "); + self.generate_expression(&cc.expression)?; + return Ok(()); + } + let computed_expr = if matches!( self.config.dialect, Some(DialectType::TSQL) | Some(DialectType::Fabric) @@ -33993,6 +34984,9 @@ impl Generator { } fn generate_lock(&mut self, e: &Lock) -> Result<()> { + if e.ignore_locked && self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported("HANA IGNORE LOCKED has no verified target mapping")); + } // Python: FOR UPDATE|FOR SHARE [OF tables] [NOWAIT|WAIT n] if e.update.is_some() { if e.key.is_some() { @@ -34005,6 +34999,9 @@ impl Generator { self.write_keyword("FOR KEY SHARE"); } else { self.write_keyword("FOR SHARE"); + if self.config.dialect == Some(DialectType::HANA) { + self.write(" LOCK"); + } } } if !e.expressions.is_empty() { @@ -34016,6 +35013,9 @@ impl Generator { self.generate_expression(expr)?; } } + if e.ignore_locked { + self.write(" IGNORE LOCKED"); + } // Handle wait option following Python sqlglot convention: // - Boolean(true) -> NOWAIT // - Boolean(false) -> SKIP LOCKED diff --git a/crates/polyglot-sql/src/lineage.rs b/crates/polyglot-sql/src/lineage.rs index ffbbcece..451555d2 100644 --- a/crates/polyglot-sql/src/lineage.rs +++ b/crates/polyglot-sql/src/lineage.rs @@ -373,6 +373,7 @@ fn lineage_normalized_expression(sql: &Expression) -> Expression { .map(|query| attach_with_to_query(query.clone(), create.with_cte.clone())) .unwrap_or_else(|| sql.clone()), Expression::CreateView(create) => lineage_normalized_expression(&create.query), + Expression::HanaUpsert(upsert) => lineage_normalized_expression(&upsert.source), Expression::Insert(insert) => insert .query .as_ref() diff --git a/crates/polyglot-sql/src/optimizer/annotate_types.rs b/crates/polyglot-sql/src/optimizer/annotate_types.rs index ace29527..a40a45a5 100644 --- a/crates/polyglot-sql/src/optimizer/annotate_types.rs +++ b/crates/polyglot-sql/src/optimizer/annotate_types.rs @@ -927,7 +927,7 @@ impl<'a> TypeAnnotator<'a> { } // Function - Expression::Function(f) => { + Expression::Function(f) | Expression::HanaFunction(f) => { for arg in &mut f.args { self.annotate_in_place(arg); } diff --git a/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs b/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs index f78774b1..505af754 100644 --- a/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +++ b/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs @@ -33,9 +33,10 @@ impl Default for NormalizationStrategy { pub fn get_normalization_strategy(dialect: Option) -> NormalizationStrategy { match dialect { // Uppercase dialects - Some(DialectType::Oracle) | Some(DialectType::Snowflake) | Some(DialectType::Exasol) => { - NormalizationStrategy::Uppercase - } + Some(DialectType::Oracle) + | Some(DialectType::Snowflake) + | Some(DialectType::Exasol) + | Some(DialectType::HANA) => NormalizationStrategy::Uppercase, // Case-sensitive dialects Some(DialectType::MySQL) | Some(DialectType::ClickHouse) => { NormalizationStrategy::CaseSensitive diff --git a/crates/polyglot-sql/src/optimizer/set_operation_types.rs b/crates/polyglot-sql/src/optimizer/set_operation_types.rs index 45f1f095..fd1a3ad1 100644 --- a/crates/polyglot-sql/src/optimizer/set_operation_types.rs +++ b/crates/polyglot-sql/src/optimizer/set_operation_types.rs @@ -329,6 +329,7 @@ fn family(dialect: DialectType) -> Family { Doris | StarRocks => Family::Standard, Drill | Dremio => Family::Limited, Exasol => Family::Standard, + HANA => Family::Limited, Druid | Solr | Tableau => Family::Limited, } } diff --git a/crates/polyglot-sql/src/parser.rs b/crates/polyglot-sql/src/parser.rs index 2bab9243..1acd5c95 100644 --- a/crates/polyglot-sql/src/parser.rs +++ b/crates/polyglot-sql/src/parser.rs @@ -28,6 +28,7 @@ use crate::guard::{ ComplexityGuardOptions, TokenGuardStats, }; use crate::tokens::{ParserToken, Span, Token, TokenType, Tokenizer, TokenizerConfig}; +use crate::traversal::ExpressionWalk; use std::collections::HashSet; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, LazyLock, OnceLock}; @@ -1102,7 +1103,16 @@ impl Parser { } let start_pos = self.current; match self.with_parser_depth(|parser| parser.parse_statement_inner()) { - Ok(expr) => Ok(expr), + Ok(expr) => { + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && expr + .dfs() + .any(|node| matches!(node, Expression::Raw(_) | Expression::Command(_))) + { + return Err(self.parse_error("HANA syntax requires structured parsing; raw statement fallback is not supported")); + } + Ok(expr) + } Err(err) if self.should_fallback_clickhouse_statement_error(start_pos, &err) => { self.current = start_pos; self.fallback_to_command(start_pos) @@ -1223,6 +1233,11 @@ impl Parser { } let statement_start = self.current; + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && self.check_identifier("UPSERT") + { + return self.parse_hana_upsert(); + } match self.peek().token_type { // Handle hint comment /*+ ... */ before a statement - convert to regular comment @@ -3016,6 +3031,10 @@ impl Parser { (limit, offset) }; + let hana_total_rowcount = self.config.dialect == Some(crate::dialects::DialectType::HANA) + && limit.is_some() + && self.match_text_seq(&["TOTAL", "ROWCOUNT"]); + // Parse FETCH FIRST/NEXT clause let fetch = if self.match_token(TokenType::Fetch) { Some(self.parse_fetch()?) @@ -3028,6 +3047,7 @@ impl Parser { // Parse FOR UPDATE/SHARE locks or FOR XML/JSON (T-SQL) let (locks, for_xml, for_json) = self.parse_locks_and_for_xml()?; + let hana_options = self.parse_hana_select_options(hana_total_rowcount)?; let option = if matches!( self.config.dialect, @@ -3089,6 +3109,7 @@ impl Parser { locks, for_xml, for_json, + hana_options, leading_comments, post_select_comments, kind, @@ -4286,6 +4307,7 @@ impl Parser { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), + hana_options: None, leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, @@ -5244,6 +5266,19 @@ impl Parser { version: None, span: None, }) + } else if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && self.match_token(TokenType::LParen) + { + let arguments = if self.check(TokenType::RParen) { + Vec::new() + } else { + self.parse_function_arguments()? + }; + self.expect(TokenType::RParen)?; + Expression::HanaTableFunction(Box::new(HanaTableFunction { + name: vec![first_ident, second_ident, third_ident], + arguments, + })) } else if self.match_token(TokenType::LParen) { // catalog.schema.function() - table-valued function let args = if self.check(TokenType::RParen) { @@ -5300,6 +5335,19 @@ impl Parser { span: None, }) } + } else if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && self.match_token(TokenType::LParen) + { + let arguments = if self.check(TokenType::RParen) { + Vec::new() + } else { + self.parse_function_arguments()? + }; + self.expect(TokenType::RParen)?; + Expression::HanaTableFunction(Box::new(HanaTableFunction { + name: vec![first_ident, second_ident], + arguments, + })) } else if self.match_token(TokenType::LParen) { // schema.function() - table-valued function let args = if self.check(TokenType::RParen) { @@ -5358,7 +5406,11 @@ impl Parser { } } else if self.match_token(TokenType::LParen) { // Handle JSON_TABLE specially - it has COLUMNS clause syntax - if first_name.eq_ignore_ascii_case("JSON_TABLE") { + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && first_name.eq_ignore_ascii_case("JSON_TABLE") + { + self.parse_hana_json("JSON_TABLE")? + } else if first_name.eq_ignore_ascii_case("JSON_TABLE") { // Parse the JSON expression (use parse_bitwise to avoid consuming FORMAT) let this = self .parse_bitwise()? @@ -5430,6 +5482,13 @@ impl Parser { error_handling, empty_handling, })) + } else if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && matches!( + first_name.to_ascii_uppercase().as_str(), + "HIERARCHY" | "HIERARCHY_SPANTREE" + ) + { + self.parse_hana_hierarchy(&first_name.to_ascii_uppercase())? } else if first_name.eq_ignore_ascii_case("XMLTABLE") { // Handle XMLTABLE specially - it has COLUMNS clause syntax // XMLTABLE([XMLNAMESPACES(...),] '/xpath' PASSING xml_doc COLUMNS ...) @@ -5473,6 +5532,10 @@ impl Parser { span: None, inferred_type: None, })) + } else if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && crate::function_registry::is_hana_builtin(&first_name.to_ascii_uppercase()) + { + self.parse_typed_function(&first_name, &first_name.to_ascii_uppercase(), false)? } else { // Simple table function like UNNEST(), GAP_FILL(), etc. let args = if self.check(TokenType::RParen) { @@ -8373,7 +8436,13 @@ impl Parser { loop { // Check for GROUPING SETS, CUBE, ROLLUP - let expr = if self.check_identifier("GROUPING") + let expr = if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && (self.check(TokenType::Cube) + || self.check(TokenType::Rollup) + || (self.check_identifier("GROUPING") && self.check_next_identifier("SETS"))) + { + self.parse_hana_grouping()? + } else if self.check_identifier("GROUPING") && self .peek_nth(1) .map_or(false, |t| t.text.eq_ignore_ascii_case("SETS")) @@ -8381,7 +8450,8 @@ impl Parser { self.skip(); self.skip(); true - } { + } + { // GROUPING SETS (...) self.expect(TokenType::LParen)?; let args = self.parse_grouping_sets_args()?; @@ -8514,7 +8584,13 @@ impl Parser { loop { // Check for nested GROUPING SETS, CUBE, ROLLUP - let expr = if self.check_identifier("GROUPING") + let expr = if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && (self.check(TokenType::Cube) + || self.check(TokenType::Rollup) + || (self.check_identifier("GROUPING") && self.check_next_identifier("SETS"))) + { + self.parse_hana_grouping()? + } else if self.check_identifier("GROUPING") && self .peek_nth(1) .map_or(false, |t| t.text.eq_ignore_ascii_case("SETS")) @@ -8522,7 +8598,8 @@ impl Parser { self.skip(); self.skip(); true - } { + } + { // Nested GROUPING SETS (...) self.expect(TokenType::LParen)?; let inner_args = self.parse_grouping_sets_args()?; @@ -9071,6 +9148,12 @@ impl Parser { let mut for_json = Vec::new(); loop { + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && self.check(TokenType::For) + && (self.check_next_identifier("JSON") || self.check_next_identifier("XML")) + { + break; + } let (update, key) = if self.match_keywords(&[TokenType::For, TokenType::Update]) { // FOR UPDATE ( @@ -9095,6 +9178,11 @@ impl Parser { // FOR SHARE self.skip(); // consume FOR self.skip(); // consume SHARE + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && !self.match_keyword("LOCK") + { + return Err(self.parse_error("HANA requires FOR SHARE LOCK")); + } (None, None) } else if self.check_identifier("LOCK") && self.check_next(TokenType::In) { // LOCK IN SHARE MODE (MySQL) -> converted to FOR SHARE @@ -9175,7 +9263,10 @@ impl Parser { None }; + let ignore_locked = self.config.dialect == Some(crate::dialects::DialectType::HANA) + && self.match_text_seq(&["IGNORE", "LOCKED"]); locks.push(Lock { + ignore_locked, update, expressions, wait, @@ -9186,6 +9277,835 @@ impl Parser { Ok((locks, for_xml, for_json)) } + fn parse_hana_json(&mut self, name: &str) -> Result { + let input = self.parse_bitwise_or()?; + self.expect(TokenType::Comma)?; + let path = self.parse_bitwise_or()?; + let columns = if name == "JSON_TABLE" { + self.parse_hana_json_columns()? + } else { + Vec::new() + }; + let options = self.parse_hana_json_options(name == "JSON_QUERY", name != "JSON_TABLE")?; + self.expect(TokenType::RParen)?; + Ok(Expression::HanaJson(Box::new(HanaJson { + name: name.to_owned(), + input, + path, + columns, + options, + }))) + } + + fn parse_hana_json_columns(&mut self) -> Result> { + self.with_parser_depth(|parser| parser.parse_hana_json_columns_inner()) + } + + fn parse_hana_json_columns_inner(&mut self) -> Result> { + if !self.match_keyword("COLUMNS") { + return Err(self.parse_error("Expected COLUMNS in JSON_TABLE")); + } + self.expect(TokenType::LParen)?; + let mut result = Vec::new(); + loop { + let nested = self.match_keyword("NESTED"); + let name = if nested { + None + } else { + Some(self.expect_identifier_or_keyword_with_quoted()?) + }; + let ordinality = !nested && self.match_text_seq(&["FOR", "ORDINALITY"]); + let data_type = if !nested && !ordinality { + Some(self.parse_data_type()?) + } else { + None + }; + let format_json = !nested && self.match_text_seq(&["FORMAT", "JSON"]); + let encoding = if format_json && self.match_keyword("ENCODING") { + if !self.match_texts(&["UTF8", "UTF16", "UTF32"]) { + return Err(self.parse_error("Expected UTF8, UTF16, or UTF32")); + } + Some(self.previous_text().to_ascii_uppercase()) + } else { + None + }; + let path = if !ordinality { + if !self.match_keyword("PATH") { + return Err(self.parse_error("Expected PATH in JSON_TABLE column")); + } + Some(self.parse_bitwise_or()?) + } else { + None + }; + let columns = if nested { + self.parse_hana_json_columns()? + } else { + Vec::new() + }; + let options = if !nested && !ordinality { + self.parse_hana_json_options(format_json, false)? + } else { + HanaJsonOptions::default() + }; + result.push(Expression::HanaJsonColumn(Box::new(HanaJsonColumn { + name, + data_type, + path, + ordinality, + format_json, + encoding, + columns, + options, + }))); + if !self.match_token(TokenType::Comma) { + break; + } + } + self.expect(TokenType::RParen)?; + Ok(result) + } + + fn parse_hana_json_options( + &mut self, + query: bool, + returning_allowed: bool, + ) -> Result { + let returning = if returning_allowed && self.match_token(TokenType::Returning) { + Some(self.parse_data_type()?) + } else { + None + }; + let wrapper = if query + && (self.check(TokenType::With) || self.peek_text().eq_ignore_ascii_case("WITHOUT")) + { + let mut value = self.advance_text()?.to_ascii_uppercase(); + if value == "WITH" && self.match_texts(&["CONDITIONAL", "UNCONDITIONAL"]) { + value.push(' '); + value.push_str(&self.previous_text().to_ascii_uppercase()); + } + if self.match_keyword("ARRAY") { + value.push_str(" ARRAY"); + } + if !self.match_keyword("WRAPPER") { + return Err(self.parse_error("Expected WRAPPER")); + } + Some(value) + } else { + None + }; + let mut options = HanaJsonOptions { + returning, + wrapper, + ..Default::default() + }; + while self.peek_text().eq_ignore_ascii_case("ERROR") + || self.check(TokenType::Null) + || self.check(TokenType::Default) + || (query && self.peek_text().eq_ignore_ascii_case("EMPTY")) + { + let kind = self.advance_text()?.to_ascii_uppercase(); + let (kind, value) = if kind == "DEFAULT" { + if query { + return Err(self.parse_error("JSON_QUERY has no DEFAULT behavior")); + } + (kind, Some(self.parse_bitwise_or()?)) + } else if kind == "EMPTY" { + if !self.match_texts(&["ARRAY", "OBJECT"]) { + return Err(self.parse_error("Expected ARRAY or OBJECT")); + } + ( + format!("EMPTY {}", self.previous_text().to_ascii_uppercase()), + None, + ) + } else { + (kind, None) + }; + self.expect(TokenType::On)?; + let empty = self.match_keyword("EMPTY"); + if !empty && !self.match_keyword("ERROR") { + return Err(self.parse_error("Expected EMPTY or ERROR after ON")); + } + let field = if empty { + &mut options.on_empty + } else { + &mut options.on_error + }; + if field.is_some() { + return Err(self.parse_error("Duplicate JSON behavior clause")); + } + *field = Some(HanaBehavior { kind, value }); + } + Ok(options) + } + + fn parse_hana_hierarchy(&mut self, name: &str) -> Result { + if !self.match_keyword("SOURCE") { + return Err(self.parse_error("Expected SOURCE in HANA hierarchy")); + } + let source = if self.match_token(TokenType::LParen) { + let source = self.parse_statement()?; + self.expect(TokenType::RParen)?; + Expression::Paren(Box::new(Paren { + this: source, + trailing_comments: Vec::new(), + })) + } else { + Expression::Table(Box::new(self.parse_table_ref()?)) + }; + let start = if self.match_keyword("START") { + self.expect(TokenType::Where)?; + Some(self.parse_expression()?) + } else { + None + }; + let siblings = if self.match_keyword("SIBLING") { + self.expect(TokenType::Order)?; + self.expect(TokenType::By)?; + self.parse_order_by_list()? + } else { + Vec::new() + }; + let depth = if self.match_keyword("DEPTH") { + Some(self.parse_primary()?) + } else { + None + }; + let multiparent = if self.match_keyword("MULTIPARENT") { + if self.match_keyword("ERROR") { + Some("ERROR".to_owned()) + } else if self.match_text_seq(&["LEAVES", "ONLY"]) { + Some("LEAVES ONLY".to_owned()) + } else { + Some(String::new()) + } + } else { + None + }; + let orphan = if self.match_keyword("ORPHAN") { + if !self.match_texts(&["IGNORE", "ERROR", "ADOPT", "ROOT"]) { + return Err(self.parse_error("Expected HANA ORPHAN handling")); + } + Some(self.previous_text().to_ascii_uppercase()) + } else { + None + }; + let cycle = if self.match_keyword("CYCLE") { + if !self.match_texts(&["BREAKUP", "ERROR"]) { + return Err(self.parse_error("Expected HANA CYCLE handling")); + } + Some(self.previous_text().to_ascii_uppercase()) + } else { + None + }; + let cache = if self.match_keyword("CACHE") { + Some( + if self.match_keyword("FORCE") { + "CACHE FORCE" + } else { + "CACHE" + } + .to_owned(), + ) + } else if self.match_text_seq(&["NO", "CACHE"]) { + Some("NO CACHE".to_owned()) + } else { + None + }; + if depth.is_some() && orphan.is_some() { + return Err(self.parse_error("HANA DEPTH and ORPHAN cannot be combined")); + } + if name == "HIERARCHY_SPANTREE" + && (multiparent.is_some() || orphan.is_some() || cycle.is_some()) + { + return Err( + self.parse_error("HIERARCHY_SPANTREE has no MULTIPARENT, ORPHAN, or CYCLE clauses") + ); + } + self.expect(TokenType::RParen)?; + Ok(Expression::HanaHierarchy(Box::new(HanaHierarchy { + name: name.to_owned(), + source, + start, + siblings, + depth, + multiparent, + orphan, + cycle, + cache, + }))) + } + + fn parse_hana_upsert(&mut self) -> Result { + self.skip(); // UPSERT + let table = self.parse_table_ref()?; + let partition = if self.match_token(TokenType::Partition) { + self.expect(TokenType::LParen)?; + let partition = self.parse_expression()?; + self.expect(TokenType::RParen)?; + Some(partition) + } else { + None + }; + let columns = if self.match_token(TokenType::LParen) { + let columns = self.parse_identifier_list()?; + self.expect(TokenType::RParen)?; + columns + } else { + Vec::new() + }; + let values = self.check(TokenType::Values); + let source = if values { + self.parse_values()? + } else { + self.parse_statement()? + }; + let condition = if values && self.match_token(TokenType::Where) { + Some(self.parse_expression()?) + } else { + None + }; + let primary_key = if values && condition.is_none() && self.match_token(TokenType::With) { + if !self.match_text_seq(&["PRIMARY", "KEY"]) && !self.match_token(TokenType::PrimaryKey) + { + return Err(self.parse_error("Expected PRIMARY KEY after UPSERT WITH")); + } + true + } else { + false + }; + Ok(Expression::HanaUpsert(Box::new(HanaUpsert { + table, + partition, + columns, + source, + condition, + primary_key, + }))) + } + + fn parse_hana_partition(&mut self) -> Result { + if !self.match_token(TokenType::PartitionBy) { + self.expect(TokenType::Partition)?; + self.expect(TokenType::By)?; + } + Ok(Expression::HanaPartition(Box::new( + self.parse_hana_partition_spec()?, + ))) + } + + fn parse_hana_partition_spec(&mut self) -> Result { + self.with_parser_depth(|parser| parser.parse_hana_partition_spec_inner()) + } + + fn parse_hana_partition_spec_inner(&mut self) -> Result { + let method = self.expect_identifier_or_keyword()?.to_ascii_uppercase(); + if !matches!(method.as_str(), "HASH" | "ROUNDROBIN" | "RANGE") { + return Err(self.parse_error("Expected HASH, ROUNDROBIN, or RANGE partitioning")); + } + let columns = if method != "ROUNDROBIN" { + self.expect(TokenType::LParen)?; + let columns = self.parse_expression_list()?; + self.expect(TokenType::RParen)?; + columns + } else { + Vec::new() + }; + let primary_key_check = + if self.check(TokenType::PrimaryKey) || self.peek_text().eq_ignore_ascii_case("NO") { + let enabled = !self.match_keyword("NO"); + self.expect(TokenType::PrimaryKey)?; + self.match_token(TokenType::Key); + self.expect(TokenType::Check)?; + Some(enabled) + } else { + None + }; + let mut ranges = Vec::new(); + let partitions = if method == "RANGE" { + self.expect(TokenType::LParen)?; + loop { + self.expect(TokenType::Partition)?; + let name = if self.check(TokenType::QuotedIdentifier) + || (self.is_identifier_token() + && !self.peek_text().eq_ignore_ascii_case("OTHERS")) + { + Some(self.expect_identifier_or_keyword_with_quoted()?) + } else { + None + }; + let (kind, values) = if self.match_keyword("OTHERS") { + ("OTHERS", Vec::new()) + } else if self.match_token(TokenType::Values) { + let kind = if self.match_token(TokenType::Lt) { + "LESS" + } else if self.match_token(TokenType::Gte) { + "AT_LEAST" + } else if self.match_token(TokenType::Eq) { + "VALUE" + } else { + return Err(self.parse_error("Expected <, >=, or = after VALUES")); + }; + (kind, vec![self.parse_bitwise_or()?]) + } else { + let lower = self.parse_bitwise_or()?; + self.expect(TokenType::Lte)?; + self.expect(TokenType::Values)?; + self.expect(TokenType::Lt)?; + ("RANGE", vec![lower, self.parse_bitwise_or()?]) + }; + let dynamic = self.match_keyword("DYNAMIC"); + let direction = if dynamic + && self.match_texts(&["INCREASING", "DECREASING", "BIDIRECTIONAL"]) + { + Some(self.previous_text().to_ascii_uppercase()) + } else { + None + }; + let threshold = if dynamic && self.match_keyword("THRESHOLD") { + Some(self.parse_primary()?) + } else { + None + }; + let interval = + if dynamic && threshold.is_none() && self.match_token(TokenType::Interval) { + let value = self.parse_primary()?; + let unit = if self.match_texts(&["YEAR", "MONTH", "HOUR"]) { + Some(self.previous_text().to_ascii_uppercase()) + } else { + None + }; + Some((value, unit)) + } else { + None + }; + if dynamic && kind != "OTHERS" { + return Err(self.parse_error("DYNAMIC applies only to OTHERS")); + } + let mut properties = Vec::new(); + while let Some(property) = self.parse_hana_storage_property()? { + properties.push(property); + } + ranges.push(HanaPartitionRange { + name, + kind: kind.to_owned(), + values, + dynamic, + direction, + threshold, + interval, + properties, + }); + if !self.match_token(TokenType::Comma) { + break; + } + } + self.expect(TokenType::RParen)?; + None + } else { + if !self.match_keyword("PARTITIONS") { + return Err(self.parse_error("Expected PARTITIONS")); + } + Some(self.parse_primary()?) + }; + let mut properties = Vec::new(); + while let Some(property) = self.parse_hana_storage_property()? { + properties.push(property); + } + let subpartition = if self.match_keyword("SUBPARTITION") { + self.expect(TokenType::By)?; + Some(Box::new(self.parse_hana_partition_spec()?)) + } else { + None + }; + Ok(HanaPartition { + method, + columns, + partitions, + ranges, + primary_key_check, + properties, + subpartition, + }) + } + + fn parse_hana_storage_property(&mut self) -> Result> { + let mut words = Vec::new(); + let mut values = Vec::new(); + let name = self.peek_text().to_ascii_uppercase(); + match name.as_str() { + "COLUMN" | "PAGE" if self.check_next_identifier("LOADABLE") => { + self.skip(); + self.skip(); + words.extend([name, "LOADABLE".to_owned()]); + } + "INSERT" | "LOGGING" => { + self.skip(); + words.push(name); + if !self.match_texts(&["ON", "OFF"]) { + return Err(self.parse_error("Expected ON or OFF")); + } + words.push(self.previous_text().to_ascii_uppercase()); + } + "AUTO" if self.check_next_identifier("MERGE") => { + self.skip(); + self.skip(); + words.extend(["AUTO".to_owned(), "MERGE".to_owned()]); + } + "NO" if self.check_next_identifier("AUTO") => { + self.skip(); + self.skip(); + if !self.match_keyword("MERGE") { + return Err(self.parse_error("Expected MERGE")); + } + words.extend(["NO".to_owned(), "AUTO".to_owned(), "MERGE".to_owned()]); + } + "UNLOAD" if self.check_next_identifier("PRIORITY") => { + self.skip(); + self.skip(); + words.extend(["UNLOAD".to_owned(), "PRIORITY".to_owned()]); + values.push(self.parse_primary()?); + } + "PERSISTENT" if self.check_next_identifier("MEMORY") => { + self.skip(); + self.skip(); + words.extend(["PERSISTENT".to_owned(), "MEMORY".to_owned()]); + if !self.match_texts(&["ON", "OFF"]) { + return Err(self.parse_error("Expected ON or OFF")); + } + words.push(self.previous_text().to_ascii_uppercase()); + } + "GROUP" => { + self.skip(); + words.push(name); + if !self.match_texts(&["NAME", "TYPE", "SUBTYPE"]) { + return Err(self.parse_error("Expected NAME, TYPE, or SUBTYPE")); + } + words.push(self.previous_text().to_ascii_uppercase()); + values.push(self.parse_primary()?); + } + "RECORD" + if self.check_next(TokenType::Commit) || self.check_next_identifier("COMMIT") => + { + self.skip(); + self.skip(); + if !self.match_keyword("TIMESTAMP") { + return Err(self.parse_error("Expected TIMESTAMP")); + } + words.extend([ + "RECORD".to_owned(), + "COMMIT".to_owned(), + "TIMESTAMP".to_owned(), + ]); + } + _ => return Ok(None), + } + Ok(Some(Expression::HanaStorageProperty(Box::new( + HanaStorageProperty { + name: words.join(" "), + values, + }, + )))) + } + + fn parse_hana_regex( + &mut self, + operation: &str, + subject: Option, + ) -> Result { + let predicate = subject.is_some(); + let position_after = + if operation == "LOCATE_REGEXPR" && self.match_texts(&["START", "AFTER"]) { + Some(self.previous_text().eq_ignore_ascii_case("AFTER")) + } else { + None + }; + let pattern = self.parse_bitwise_or()?; + let flag = if self.match_keyword("FLAG") { + Some(self.parse_bitwise_or()?) + } else { + None + }; + let subject = if let Some(subject) = subject { + subject + } else { + self.expect(TokenType::In)?; + self.parse_bitwise_or()? + }; + let replacement = if !predicate && self.match_token(TokenType::With) { + Some(self.parse_bitwise_or()?) + } else { + None + }; + let start = if !predicate && self.match_token(TokenType::From) { + Some(self.parse_bitwise_or()?) + } else { + None + }; + let occurrence = if !predicate && self.match_keyword("OCCURRENCE") { + if self.match_token(TokenType::All) { + Some(Expression::Var(Box::new(Var { + this: "ALL".to_owned(), + }))) + } else { + Some(self.parse_bitwise_or()?) + } + } else { + None + }; + let group = if !predicate && self.match_token(TokenType::Group) { + Some(self.parse_bitwise_or()?) + } else { + None + }; + if replacement.is_some() && operation != "REPLACE_REGEXPR" + || group.is_some() + && !matches!( + operation, + "SUBSTRING_REGEXPR" | "SUBSTR_REGEXPR" | "LOCATE_REGEXPR" + ) + || occurrence.is_some() && operation == "OCCURRENCES_REGEXPR" + { + return Err(self + .parse_error("Clause is not supported by this HANA regular-expression operation")); + } + if !predicate { + self.expect(TokenType::RParen)?; + } + Ok(Expression::HanaRegex(Box::new(HanaRegex { + operation: operation.to_owned(), + negated: false, + pattern, + subject, + flag, + start, + occurrence, + group, + replacement, + position_after, + }))) + } + + fn parse_hana_grouping(&mut self) -> Result { + self.with_parser_depth(|parser| parser.parse_hana_grouping_inner()) + } + + fn parse_hana_grouping_inner(&mut self) -> Result { + let kind = if self.match_text_seq(&["GROUPING", "SETS"]) { + "GROUPING SETS".to_owned() + } else { + self.advance_text()?.to_ascii_uppercase() + }; + let best = if self.match_keyword("BEST") { + Some(self.parse_hana_grouping_integer(true)?) + } else { + None + }; + let limit = if self.match_token(TokenType::Limit) { + Some(self.parse_hana_grouping_integer(false)?) + } else { + None + }; + let offset = if limit.is_some() && self.match_token(TokenType::Offset) { + Some(self.parse_hana_grouping_integer(false)?) + } else { + None + }; + let subtotal = self.match_text_seq(&["WITH", "SUBTOTAL"]); + let balance = self.match_text_seq(&["WITH", "BALANCE"]); + let total = self.match_text_seq(&["WITH", "TOTAL"]); + let structured = self.match_text_seq(&["STRUCTURED", "RESULT"]); + let overview = structured && self.match_text_seq(&["WITH", "OVERVIEW"]); + let prefix = if structured && self.match_keyword("PREFIX") { + Some(Expression::string(self.expect(TokenType::String)?.text)) + } else { + None + }; + let multiple_resultsets = + prefix.is_none() && self.match_text_seq(&["MULTIPLE", "RESULTSETS"]); + self.expect(TokenType::LParen)?; + let expressions = self.parse_grouping_sets_args()?; + self.expect(TokenType::RParen)?; + if best.is_none() + && limit.is_none() + && !subtotal + && !balance + && !total + && !structured + && !multiple_resultsets + { + return Ok(Self::make_unquoted_function(&kind, expressions)); + } + Ok(Expression::HanaGrouping(Box::new(HanaGrouping { + kind, + expressions, + best, + limit, + offset, + subtotal, + balance, + total, + structured, + overview, + prefix, + multiple_resultsets, + }))) + } + + fn parse_hana_grouping_integer(&mut self, signed: bool) -> Result { + let negative = signed && self.match_token(TokenType::Dash); + if signed && !negative { + self.match_token(TokenType::Plus); + } + let value = self.expect(TokenType::Number)?.text; + if value.parse::().is_err() { + return Err(self.parse_error("Expected an integer grouping-set option")); + } + Ok(Expression::Literal(Box::new(Literal::Number( + if negative { format!("-{value}") } else { value }, + )))) + } + + fn parse_hana_timezone(&mut self, name: &str) -> Result { + let mut arguments = Vec::new(); + let mut on_error = None; + loop { + let behavior = self.peek_text().to_ascii_uppercase(); + if behavior == "DEFAULT" + || (matches!(behavior.as_str(), "NULL" | "ERROR") && self.check_next(TokenType::On)) + { + self.skip(); + let value = if behavior == "DEFAULT" { + Some(Expression::string(self.expect(TokenType::String)?.text)) + } else { + None + }; + self.expect(TokenType::On)?; + if !self.match_keyword("ERROR") { + return Err(self.parse_error("Expected ON ERROR")); + } + on_error = Some(HanaBehavior { + kind: behavior, + value, + }); + break; + } + arguments.push(self.parse_expression()?); + if self.match_token(TokenType::Comma) { + continue; + } + if self.check(TokenType::RParen) { + break; + } + if !matches!( + self.peek_text().to_ascii_uppercase().as_str(), + "DEFAULT" | "NULL" | "ERROR" + ) { + return Err(self.parse_error("Expected comma or timezone error clause")); + } + } + self.expect(TokenType::RParen)?; + if !(1..=4).contains(&arguments.len()) { + return Err(self.parse_error("HANA timezone conversion expects one to four arguments")); + } + Ok(Expression::HanaTimezone(Box::new(HanaTimezone { + name: name.to_owned(), + arguments, + on_error, + }))) + } + + fn parse_hana_select_options( + &mut self, + total_rowcount: bool, + ) -> Result> { + if self.config.dialect != Some(crate::dialects::DialectType::HANA) { + return Ok(None); + } + let mut serialization = None; + if self.check(TokenType::For) + && (self.check_next_identifier("JSON") || self.check_next_identifier("XML")) + { + self.skip(); + let format = self.advance_text()?.to_ascii_uppercase(); + let mut options = Vec::new(); + if self.match_token(TokenType::LParen) { + loop { + let key = self.expect(TokenType::String)?.text; + self.expect(TokenType::Eq)?; + let value = self.expect(TokenType::String)?.text; + options.push((key, value)); + if !self.match_token(TokenType::Comma) { + break; + } + } + self.expect(TokenType::RParen)?; + } + let returning = if self.match_keyword("RETURNS") { + Some(self.parse_data_type()?) + } else { + None + }; + serialization = Some(HanaSerialization { + format, + options, + returning, + }); + } + let collation = if self.check(TokenType::With) && self.check_next_identifier("COLLATION") { + self.skip(); + self.skip(); + Some(self.expect_identifier_or_keyword_with_quoted()?) + } else { + None + }; + let hints = self.parse_hana_hints()?; + Ok( + (total_rowcount || serialization.is_some() || collation.is_some() || !hints.is_empty()) + .then_some(HanaSelectOptions { + total_rowcount, + serialization, + collation, + hints, + }), + ) + } + + fn parse_hana_hints(&mut self) -> Result> { + let mut hints = Vec::new(); + if self.check(TokenType::With) && self.check_next_identifier("HINT") { + self.skip(); + self.skip(); + self.expect(TokenType::LParen)?; + loop { + let name = self.expect_identifier_or_keyword_with_quoted()?; + let arguments = if self.match_token(TokenType::LParen) { + let args = if self.check(TokenType::RParen) { + Vec::new() + } else { + self.parse_function_arguments()? + }; + self.expect(TokenType::RParen)?; + Some(args) + } else { + None + }; + let remote = self.match_keyword("REMOTE"); + let cascade = self.match_keyword("CASCADE"); + hints.push(Expression::HanaHint(Box::new(HanaHint { + name, + arguments, + remote, + cascade, + }))); + if !self.match_token(TokenType::Comma) { + break; + } + } + self.expect(TokenType::RParen)?; + } + Ok(hints) + } + /// Parse FOR XML options (T-SQL) /// Syntax: FOR XML PATH|RAW|AUTO|EXPLICIT [('element')] [, BINARY BASE64] [, ELEMENTS [XSINIL|ABSENT]] [, TYPE] [, ROOT('name')] fn parse_for_xml_options(&mut self) -> Result> { @@ -12578,8 +13498,28 @@ impl Parser { let or_replace = self.match_keywords(&[TokenType::Or, TokenType::Replace]); let or_alter = !or_replace && self.match_text_seq(&["OR", "ALTER"]); + // HANA orders scope, lifetime, and storage before TABLE. + let hana_modifier = if self.config.dialect == Some(crate::dialects::DialectType::HANA) { + let mut parts = Vec::new(); + if self.match_texts(&["LOCAL", "GLOBAL"]) { + parts.push(self.previous_text().to_ascii_uppercase()); + self.expect(TokenType::Temporary)?; + parts.push("TEMPORARY".to_owned()); + } else if self.match_token(TokenType::Temporary) { + parts.push("TEMPORARY".to_owned()); + } + if self.match_texts(&["COLUMN", "ROW"]) { + parts.push(self.previous_text().to_ascii_uppercase()); + } + (!parts.is_empty()).then(|| parts.join(" ")) + } else { + None + }; // Handle TEMPORARY - let temporary = self.match_token(TokenType::Temporary); + let temporary = hana_modifier + .as_ref() + .is_some_and(|m| m.contains("TEMPORARY")) + || self.match_token(TokenType::Temporary); // Handle MATERIALIZED let materialized = self.match_token(TokenType::Materialized); @@ -12627,7 +13567,9 @@ impl Parser { let secure = self.match_identifier("SECURE"); // Handle table modifiers: DYNAMIC, ICEBERG, EXTERNAL, HYBRID, TRANSIENT (Snowflake), UNLOGGED (PostgreSQL) - let mut table_modifier: Option = if self.check_identifier("DYNAMIC") { + let mut table_modifier: Option = if hana_modifier.is_some() { + hana_modifier + } else if self.check_identifier("DYNAMIC") { self.skip(); Some("DYNAMIC".to_string()) } else if self.check_identifier("ICEBERG") { @@ -13187,6 +14129,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -13292,6 +14235,7 @@ impl Parser { temporary, or_replace, table_modifier: Some("EXTERNAL".to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), // BigQuery EXTERNAL tables don't support AS SELECT as_select: None, as_select_parenthesized: false, @@ -13358,6 +14302,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -13568,6 +14513,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -13683,6 +14629,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: Some(query), as_select_parenthesized, on_commit, @@ -13748,6 +14695,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select, as_select_parenthesized, on_commit: None, @@ -13835,6 +14783,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select, as_select_parenthesized: false, on_commit: None, @@ -13882,6 +14831,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -13927,6 +14877,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -13988,6 +14939,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select, as_select_parenthesized: false, on_commit: None, @@ -14044,6 +14996,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: Some(query), as_select_parenthesized: true, on_commit: None, @@ -14186,6 +15139,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -14789,6 +15743,18 @@ impl Parser { self.parse_clickhouse_table_properties(&mut table_properties)?; } + if self.config.dialect == Some(crate::dialects::DialectType::HANA) { + loop { + if self.check(TokenType::Partition) || self.check(TokenType::PartitionBy) { + table_properties.push(self.parse_hana_partition()?); + } else if let Some(property) = self.parse_hana_storage_property()? { + table_properties.push(property); + } else { + break; + } + } + } + // Parse PARTITION BY RANGE/LIST/HASH(columns) for regular CREATE TABLE let is_bigquery = matches!( self.config.dialect, @@ -15241,6 +16207,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select, as_select_parenthesized: false, on_commit, @@ -15393,6 +16360,7 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), + hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -17055,6 +18023,20 @@ impl Parser { col_def .constraint_order .push(ConstraintType::ComputedColumn); + } else if self.config.dialect == Some(crate::dialects::DialectType::HANA) { + let expression = self.parse_expression()?; + col_def + .constraints + .push(ColumnConstraint::ComputedColumn(ComputedColumn { + expression: Box::new(expression), + persisted: false, + not_null: false, + persistence_kind: None, + data_type: None, + })); + col_def + .constraint_order + .push(ConstraintType::ComputedColumn); } else { // Fallback: treat as GENERATED AS IDENTITY without explicit IDENTITY keyword col_def @@ -25292,6 +26274,41 @@ impl Parser { /// Parse CALL statement (stored procedure call) /// CALL procedure_name(args, ...) fn parse_call(&mut self) -> Result { + if self.config.dialect == Some(crate::dialects::DialectType::HANA) { + self.skip(); + let mut name = vec![self.expect_identifier_or_keyword_with_quoted()?]; + if self.match_token(TokenType::Dot) { + name.push(self.expect_identifier_or_keyword_with_quoted()?); + } + let member = if self.match_token(TokenType::Colon) { + Some(self.expect_identifier_or_keyword_with_quoted()?) + } else { + None + }; + let arguments = if self.match_token(TokenType::LParen) { + let args = if self.check(TokenType::RParen) { + Vec::new() + } else { + self.parse_function_arguments()? + }; + self.expect(TokenType::RParen)?; + args + } else { + Vec::new() + }; + let asynchronous = self.match_keyword("ASYNC"); + let hints = self.parse_hana_hints()?; + if member.is_some() && (asynchronous || !hints.is_empty()) { + return Err(self.parse_error("Library member CALL does not support ASYNC or hints")); + } + return Ok(Expression::HanaCall(Box::new(HanaCall { + name, + member, + arguments, + asynchronous, + hints, + }))); + } let call_token = self.advance()?; // consume CALL // Collect remaining tokens with their types @@ -29326,7 +30343,18 @@ impl Parser { global_in = true; } - let expr = if self.match_token(TokenType::Eq) { + let expr = if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && (self.peek_text().eq_ignore_ascii_case("LIKE_REGEXPR") + || (self.check(TokenType::Not) && self.check_next_identifier("LIKE_REGEXPR"))) + { + let negated = self.match_token(TokenType::Not); + self.skip(); + let mut regex = self.parse_hana_regex("LIKE_REGEXPR", Some(left))?; + if let Expression::HanaRegex(ref mut r) = regex { + r.negated = negated; + } + regex + } else if self.match_token(TokenType::Eq) { // Check for ANY/ALL subquery if self.match_token(TokenType::Any) || self.match_token(TokenType::Some) { let was_any = self.previous_token_type() == Some(TokenType::Any); @@ -32395,7 +33423,30 @@ impl Parser { // Check for no-paren functions like CURRENT_TIMESTAMP, CURRENT_DATE, etc. // These should be parsed as functions even without parentheses let upper_name = self.peek_text().to_ascii_uppercase(); - if !self.check_next(TokenType::LParen) + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && !self.check(TokenType::QuotedIdentifier) + && !self.check_next(TokenType::Dot) + && !self.check_next(TokenType::LParen) + && matches!( + upper_name.as_str(), + "CURRENT_UTCTIMESTAMP" + | "CURRENT_UTCDATE" + | "CURRENT_UTCTIME" + | "CURRENT_CONNECTION" + | "CURRENT_TRANSACTION_ISOLATION_LEVEL" + | "SYSUUID" + | "SESSION_USER" + | "CURRENT_SCHEMA" + | "CURRENT_USER" + ) + { + let mut function = Function::new(self.advance()?.text, Vec::new()); + function.no_parens = true; + return Ok(Expression::HanaFunction(Box::new(function))); + } + if !(self.config.dialect == Some(crate::dialects::DialectType::HANA) + && self.check(TokenType::QuotedIdentifier)) + && !self.check_next(TokenType::LParen) && !self.check_next(TokenType::Dot) && crate::function_registry::is_no_paren_function_name_upper(upper_name.as_str()) && !(matches!( @@ -32877,6 +33928,48 @@ impl Parser { #[inline(never)] fn parse_primary_slow(&mut self) -> Result { + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && !self.check(TokenType::QuotedIdentifier) + && !self.check_next(TokenType::Dot) + && matches!( + self.peek_text().to_ascii_uppercase().as_str(), + "CURRENT_DATE" + | "CURRENT_TIME" + | "CURRENT_TIMESTAMP" + | "CURRENT_CONNECTION" + | "CURRENT_TRANSACTION_ISOLATION_LEVEL" + | "SYSUUID" + | "SESSION_USER" + | "CURRENT_SCHEMA" + | "CURRENT_USER" + ) + { + let name = self.advance_text()?; + let upper = name.to_ascii_uppercase(); + let parenthesized = self.match_token(TokenType::LParen); + let args = if parenthesized { + if upper != "CURRENT_TIMESTAMP" { + return Err( + self.parse_error("This HANA reserved expression does not take parentheses") + ); + } + let precision = self.expect(TokenType::Number)?; + if !precision.text.parse::().is_ok_and(|p| p <= 7) { + return Err( + self.parse_error("HANA timestamp precision must be between 0 and 7") + ); + } + self.expect(TokenType::RParen)?; + vec![Expression::Literal(Box::new(Literal::Number( + precision.text, + )))] + } else { + Vec::new() + }; + let mut function = Function::new(name, args); + function.no_parens = !parenthesized; + return Ok(Expression::HanaFunction(Box::new(function))); + } // Handle APPROXIMATE COUNT(DISTINCT expr) - Redshift syntax // Parses as ApproxDistinct expression if self.check(TokenType::Var) && self.peek_text().eq_ignore_ascii_case("APPROXIMATE") { @@ -37249,12 +38342,115 @@ impl Parser { /// Parse a typed function call (after the opening paren) /// Following Python SQLGlot pattern: match all function aliases to typed expressions + fn parse_hana_typed_function( + &mut self, + name: &str, + upper_name: &str, + quoted: bool, + ) -> Result { + if quoted { + let expression = self.parse_generic_function(name, true)?; + return Ok(match expression { + Expression::Function(function) => Expression::HanaFunction(function), + other => other, + }); + } + if matches!(upper_name, "LOCALTOUTC" | "UTCTOLOCAL") { + return self.parse_hana_timezone(upper_name); + } + if matches!(upper_name, "JSON_VALUE" | "JSON_QUERY" | "JSON_TABLE") { + return self.parse_hana_json(upper_name); + } + if matches!(upper_name, "HIERARCHY" | "HIERARCHY_SPANTREE") { + return self.parse_hana_hierarchy(upper_name); + } + if matches!( + upper_name, + "SUBSTR_REGEXPR" + | "SUBSTRING_REGEXPR" + | "LOCATE_REGEXPR" + | "OCCURRENCES_REGEXPR" + | "REPLACE_REGEXPR" + ) { + return self.parse_hana_regex(upper_name, None); + } + if (crate::function_registry::is_hana_builtin(upper_name) + || matches!(upper_name, "CONTAINS" | "FUZZY")) + && !matches!( + upper_name, + "COUNT" + | "SUM" + | "MIN" + | "MAX" + | "AVG" + | "CAST" + | "EXTRACT" + | "TRIM" + | "ROW_NUMBER" + | "RANK" + | "DENSE_RANK" + | "LEAD" + | "LAG" + | "NTILE" + | "CUME_DIST" + | "PERCENT_RANK" + | "JSON_TABLE" + | "JSON_QUERY" + | "JSON_VALUE" + ) + { + let expr = self.parse_generic_function(name, false)?; + if let Expression::Function(f) = expr { + let arity_valid = match upper_name { + "LOCATE" => (2..=4).contains(&f.args.len()), + "SUBSTRING" | "SUBSTR" => (2..=3).contains(&f.args.len()), + "TO_DECIMAL" => (1..=3).contains(&f.args.len()), + "TO_DATE" | "TO_TIMESTAMP" | "TO_VARCHAR" | "TO_NVARCHAR" => { + (1..=2).contains(&f.args.len()) + } + "CURRENT_UTCTIMESTAMP" => { + f.args.len() == 1 + && matches!(&f.args[0], Expression::Literal(l) if matches!(l.as_ref(), Literal::Number(n) if n.parse::().is_ok_and(|n| n <= 7))) + } + "CURRENT_UTCDATE" | "CURRENT_UTCTIME" => false, + "ADD_DAYS" | "ADD_MONTHS" | "ADD_MONTHS_LAST" | "ADD_YEARS" | "ADD_SECONDS" + | "DAYS_BETWEEN" | "MONTHS_BETWEEN" | "SECONDS_BETWEEN" | "IFNULL" + | "BITAND" | "BITOR" | "BITXOR" => f.args.len() == 2, + "BITNOT" => f.args.len() == 1, + _ => true, + }; + if !arity_valid { + return Err( + self.parse_error(format!("Invalid arguments for HANA {upper_name}")) + ); + } + return Ok(Expression::HanaFunction(f)); + } + return Ok(match expr { + Expression::AggregateFunction(f) => Expression::HanaAggregateFunction(f), + Expression::WithinGroup(mut w) => { + if let Expression::AggregateFunction(f) = w.this { + w.this = Expression::HanaAggregateFunction(f); + } + Expression::WithinGroup(w) + } + other => other, + }); + } + self.parse_generic_function(name, quoted) + } + fn parse_typed_function( &mut self, name: &str, upper_name: &str, quoted: bool, ) -> Result { + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && (quoted || crate::function_registry::hana_uses_source_node(upper_name)) + { + return self.parse_hana_typed_function(name, upper_name, quoted); + } // ClickHouse bitOr/bitAnd/bitXor are scalar functions, not aggregate-family calls. // Routing them directly to the generic parser avoids aggregate-specific recursion // and matches the syntax used throughout the ClickHouse parser corpus. @@ -39138,7 +40334,9 @@ impl Parser { /// Parse a generic function call (fallback for unrecognized functions) fn parse_generic_function(&mut self, name: &str, quoted: bool) -> Result { - let is_known_agg = self.is_aggregate_function(name); + let is_known_agg = !(quoted + && self.config.dialect == Some(crate::dialects::DialectType::HANA)) + && self.is_aggregate_function(name); let (mut args, distinct) = if self.check(TokenType::RParen) { (Vec::new(), false) @@ -39366,6 +40564,20 @@ impl Parser { } fn parse_single_function_argument(&mut self) -> Result { + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && self.check_identifier("PLACEHOLDER") + && self.check_next(TokenType::Dot) + { + self.skip(); + self.skip(); + let name = self.expect_identifier_with_quoted()?; + self.expect(TokenType::FArrow)?; + let value = self.parse_expression()?; + return Ok(Expression::HanaPlaceholder(Box::new(HanaPlaceholder { + name, + value, + }))); + } let is_table_or_model_arg = if !self.is_at_end() { self.check(TokenType::Table) || self.peek_text().eq_ignore_ascii_case("MODEL") } else { @@ -42321,7 +43533,9 @@ impl Parser { fn parse_data_type_inner(&mut self) -> Result { // Handle special token types that represent data type keywords // Teradata tokenizes ST_GEOMETRY as TokenType::Geometry - if self.check(TokenType::Geometry) { + if self.check(TokenType::Geometry) + && self.config.dialect != Some(crate::dialects::DialectType::HANA) + { let _token = self.advance()?; let (subtype, srid) = self.parse_spatial_type_args()?; return Ok(DataType::Geometry { subtype, srid }); @@ -42335,6 +43549,14 @@ impl Parser { raw_name.push_str(&part); } let mut name = raw_name.to_ascii_uppercase(); + if self.config.dialect == Some(crate::dialects::DialectType::HANA) { + name = match name.as_str() { + "DEC" => "DECIMAL".to_owned(), + "LONGDATE" => "TIMESTAMP".to_owned(), + "DAYDATE" => "DATE".to_owned(), + _ => name, + }; + } // SQL standard: NATIONAL CHAR/CHARACTER → NCHAR if name == "NATIONAL" { @@ -42369,6 +43591,66 @@ impl Parser { } } + if self.config.dialect == Some(crate::dialects::DialectType::HANA) + && matches!( + name.as_str(), + "TINYINT" + | "FLOAT" + | "SMALLDECIMAL" + | "DECIMAL" + | "ALPHANUM" + | "SECONDDATE" + | "TIMESTAMP" + | "TIME" + | "NVARCHAR" + | "VARCHAR" + | "CLOB" + | "NCLOB" + | "TEXT" + | "BINTEXT" + | "SHORTTEXT" + | "REAL_VECTOR" + | "HALF_VECTOR" + | "ST_POINT" + | "ST_GEOMETRY" + ) + { + let mut parameters = Vec::new(); + if self.match_token(TokenType::LParen) { + loop { + let token = self.expect(TokenType::Number)?; + let parameter = token.text.parse::().map_err(|_| { + self.parse_error("Expected a non-negative integer HANA type parameter") + })?; + parameters.push(parameter); + if !self.match_token(TokenType::Comma) { + break; + } + } + self.expect(TokenType::RParen)?; + } + let valid = match (name.as_str(), parameters.as_slice()) { + ("FLOAT", [] | [1..=53]) => true, + ("DECIMAL", [] | [1..=38]) => true, + ("DECIMAL", [p, scale]) => (1..=38).contains(p) && scale <= p, + ("NVARCHAR" | "VARCHAR", [] | [1..=5000]) => true, + ("ALPHANUM", [] | [1..=127]) => true, + ("SHORTTEXT", [] | [1..=5000]) => true, + ("REAL_VECTOR" | "HALF_VECTOR" | "ST_POINT" | "ST_GEOMETRY", [] | [_]) => true, + ( + "TINYINT" | "SMALLDECIMAL" | "SECONDDATE" | "TIMESTAMP" | "TIME" | "CLOB" + | "NCLOB" | "TEXT" | "BINTEXT", + [], + ) => true, + _ => false, + }; + if !valid { + return Err(self.parse_error(format!("Invalid HANA {name} type parameters"))); + } + return self.finish_data_type(DataType::Hana { + hana_type: HanaDataType { name, parameters }, + }); + } if let Some(data_type) = self.parse_oracle_data_type(&name)? { return Ok(data_type); } @@ -44505,6 +45787,23 @@ impl Parser { /// Convert a DataType to a string representation for JSONColumnDef.kind fn data_type_to_string(&self, dt: &DataType) -> String { match dt { + DataType::Hana { hana_type } => { + if hana_type.parameters.is_empty() { + hana_type.name.clone() + } else { + format!( + "{}({})", + hana_type.name, + hana_type + .parameters + .iter() + .map(u32::to_string) + .collect::>() + .join(", ") + ) + } + } + DataType::Int { length: Some(n), integer_spelling: true, @@ -57042,6 +58341,7 @@ impl Parser { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), + hana_options: None, leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, @@ -57165,6 +58465,7 @@ impl Parser { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), + hana_options: None, leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, diff --git a/crates/polyglot-sql/src/traversal.rs b/crates/polyglot-sql/src/traversal.rs index 3db9fd71..de27f689 100644 --- a/crates/polyglot-sql/src/traversal.rs +++ b/crates/polyglot-sql/src/traversal.rs @@ -480,7 +480,15 @@ pub fn is_literal(expr: &Expression) -> bool { pub fn is_function(expr: &Expression) -> bool { matches!( expr, - Expression::Function(_) | Expression::AggregateFunction(_) + Expression::Function(_) + | Expression::HanaFunction(_) + | Expression::AggregateFunction(_) + | Expression::HanaAggregateFunction(_) + | Expression::HanaJson(_) + | Expression::HanaTableFunction(_) + | Expression::HanaHierarchy(_) + | Expression::HanaTimezone(_) + | Expression::HanaRegex(_) ) } @@ -503,6 +511,7 @@ pub fn is_aggregate(expr: &Expression) -> bool { matches!( expr, Expression::AggregateFunction(_) + | Expression::HanaAggregateFunction(_) | Expression::Count(_) | Expression::Sum(_) | Expression::Avg(_) diff --git a/crates/polyglot-sql/src/validation.rs b/crates/polyglot-sql/src/validation.rs index ea6e9a3c..4dbec295 100644 --- a/crates/polyglot-sql/src/validation.rs +++ b/crates/polyglot-sql/src/validation.rs @@ -766,6 +766,17 @@ fn data_type_family(data_type: &DataType) -> TypeFamily { DataType::Float { .. } | DataType::Double { .. } | DataType::Decimal { .. } => { TypeFamily::Numeric } + DataType::Hana { hana_type } => match hana_type.name.as_str() { + "TINYINT" => TypeFamily::Integer, + "TIMESTAMP" | "SECONDDATE" => TypeFamily::Timestamp, + "TIME" => TypeFamily::Time, + "FLOAT" | "DECIMAL" | "SMALLDECIMAL" => TypeFamily::Numeric, + "BINTEXT" => TypeFamily::Binary, + "ALPHANUM" | "VARCHAR" | "NVARCHAR" | "CLOB" | "NCLOB" | "TEXT" | "SHORTTEXT" => { + TypeFamily::String + } + _ => TypeFamily::Unknown, + }, DataType::Oracle { oracle_type } => match oracle_type { OracleDataType::Number { .. } | OracleDataType::BinaryFloat @@ -2571,7 +2582,7 @@ fn check_types( )); } } - Expression::Function(function) => { + Expression::Function(function) | Expression::HanaFunction(function) => { check_function_catalog(function, dialect, function_catalog, strict, &mut errors); check_generic_function(function, schema_map, &context, strict, &mut errors); } diff --git a/crates/polyglot-sql/tests/common/test_runner.rs b/crates/polyglot-sql/tests/common/test_runner.rs index 1263ce8c..8442c706 100644 --- a/crates/polyglot-sql/tests/common/test_runner.rs +++ b/crates/polyglot-sql/tests/common/test_runner.rs @@ -307,6 +307,7 @@ pub fn parse_dialect(name: &str) -> Option { "druid" => Some(DialectType::Druid), "dune" => Some(DialectType::Dune), "exasol" => Some(DialectType::Exasol), + "hana" | "saphana" | "sap_hana" => Some(DialectType::HANA), "fabric" => Some(DialectType::Fabric), "solr" => Some(DialectType::Solr), "datafusion" | "arrow-datafusion" | "arrow_datafusion" => Some(DialectType::DataFusion), diff --git a/crates/polyglot-sql/tests/custom_fixtures/hana/ddl.json b/crates/polyglot-sql/tests/custom_fixtures/hana/ddl.json new file mode 100644 index 00000000..6b7d3c75 --- /dev/null +++ b/crates/polyglot-sql/tests/custom_fixtures/hana/ddl.json @@ -0,0 +1,66 @@ +{ + "dialect": "hana", + "category": "ddl", + "identity": [ + { + "sql": "CREATE TABLE t (id INTEGER, name NVARCHAR(100), salary SMALLDECIMAL, created SECONDDATE)", + "description": "CREATE TABLE with HANA types", + "expected": "CREATE TABLE t (id INT, name NVARCHAR(100), salary SMALLDECIMAL, created SECONDDATE)" + }, + { + "sql": "CREATE TABLE t (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(100) NOT NULL)", + "description": "CREATE TABLE with constraints", + "expected": "CREATE TABLE t (id INT NOT NULL PRIMARY KEY, name VARCHAR(100) NOT NULL)" + }, + { + "sql": "CREATE TABLE t (a NVARCHAR(255), b SMALLDECIMAL)", + "description": "Types with precision and length args" + }, + { + "sql": "CREATE TABLE t (a ALPHANUM(20), b CLOB)", + "description": "ALPHANUM and CLOB types" + }, + { + "sql": "CREATE TABLE t (id BIGINT, name TEXT, val DECIMAL(15, 2), ts TIMESTAMP)", + "description": "Various HANA column types" + }, + { + "sql": "CREATE TABLE t (a INTEGER, b NVARCHAR(50) NOT NULL, c DECIMAL(10, 2))", + "description": "Mixed constraints and types", + "expected": "CREATE TABLE t (a INT, b NVARCHAR(50) NOT NULL, c DECIMAL(10, 2))" + }, + { + "sql": "CREATE TABLE t (a INTEGER)", + "description": "CREATE TABLE", + "expected": "CREATE TABLE t (a INT)" + }, + { + "sql": "DROP TABLE t", + "description": "DROP TABLE" + }, + { + "sql": "DROP TABLE t", + "description": "DROP TABLE", + "expected": "DROP TABLE t" + }, + { + "sql": "ALTER TABLE t ADD (x INTEGER)", + "description": "ALTER TABLE ADD COLUMN", + "expected": "ALTER TABLE t ADD (x INT)" + }, + { + "sql": "CREATE TABLE t (a INTEGER, b INTEGER, PRIMARY KEY (a))", + "description": "CREATE TABLE with table-level PRIMARY KEY", + "expected": "CREATE TABLE t (a INT, b INT, PRIMARY KEY (a))" + }, + { + "sql": "CREATE VIEW v AS SELECT a, b FROM t WHERE x > 1", + "description": "CREATE VIEW" + }, + { + "sql": "CREATE TABLE t AS SELECT a, b FROM s", + "description": "CREATE TABLE AS SELECT" + } + ], + "transpilation": [] +} diff --git a/crates/polyglot-sql/tests/custom_fixtures/hana/dml.json b/crates/polyglot-sql/tests/custom_fixtures/hana/dml.json new file mode 100644 index 00000000..1fe77a1d --- /dev/null +++ b/crates/polyglot-sql/tests/custom_fixtures/hana/dml.json @@ -0,0 +1,51 @@ +{ + "dialect": "hana", + "category": "dml", + "identity": [ + { + "sql": "INSERT INTO t (a, b) VALUES (1, 'x')", + "description": "INSERT with VALUES and explicit column list" + }, + { + "sql": "INSERT INTO t SELECT 1, 'a' FROM DUMMY UNION ALL SELECT 2, 'b' FROM DUMMY UNION ALL SELECT 3, 'c' FROM DUMMY", + "description": "Insert several rows using a union query" + }, + { + "sql": "INSERT INTO t SELECT a, b FROM s", + "description": "INSERT with SELECT" + }, + { + "sql": "INSERT INTO t (a, b) SELECT x, y FROM s", + "description": "INSERT with explicit column list and SELECT" + }, + { + "sql": "INSERT INTO t SELECT * FROM s", + "description": "INSERT SELECT star" + }, + { + "sql": "INSERT INTO t VALUES (1, NULL)", + "description": "INSERT with NULL value" + }, + { + "sql": "UPDATE t SET x = 1 WHERE y = 2", + "description": "UPDATE with WHERE" + }, + { + "sql": "UPDATE t SET x = 1, y = 2 WHERE z = 3", + "description": "UPDATE multiple columns with WHERE" + }, + { + "sql": "DELETE FROM t WHERE x = 1", + "description": "DELETE with WHERE" + }, + { + "sql": "DELETE FROM t", + "description": "DELETE all rows" + }, + { + "sql": "INSERT INTO t (a, b, c) VALUES (1, 'hello', 3.14)", + "description": "INSERT with mixed type values" + } + ], + "transpilation": [] +} diff --git a/crates/polyglot-sql/tests/custom_fixtures/hana/functions.json b/crates/polyglot-sql/tests/custom_fixtures/hana/functions.json new file mode 100644 index 00000000..68c91838 --- /dev/null +++ b/crates/polyglot-sql/tests/custom_fixtures/hana/functions.json @@ -0,0 +1,136 @@ +{ + "dialect": "hana", + "category": "functions", + "identity": [ + { + "sql": "SELECT ADD_DAYS(d, 7) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT ADD_MONTHS(d, 3) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT ADD_SECONDS(ts, 30) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT ADD_YEARS(d, 1) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT DAYS_BETWEEN(d1, d2) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT MONTHS_BETWEEN(d1, d2) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT SECONDS_BETWEEN(d1, d2) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT YEARS_BETWEEN(d1, d2) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT TO_VARCHAR(x) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT TO_VARCHAR(d, 'YYYY-MM-DD') FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT TO_INTEGER(s) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT TO_DECIMAL(s) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT IFNULL(a, b) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT SUBSTR(s, 1, 3) FROM t", + "description": "Native SUBSTR alias" + }, + { + "sql": "SELECT LCASE(s) FROM t", + "description": "LCASE canonicalized to LOWER by parser" + }, + { + "sql": "SELECT UCASE(s) FROM t", + "description": "UCASE canonicalized to UPPER by parser" + }, + { + "sql": "SELECT LOCATE('abc', s) FROM t", + "description": "LOCATE canonicalized to STRPOS with arg swap by parser" + }, + { + "sql": "SELECT CURRENT_UTCTIMESTAMP FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT CURRENT_UTCDATE FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT CURRENT_UTCTIME FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT TRUNC(x, 2) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT BITAND(a, b) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT BITOR(a, b) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT BITNOT(a) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT BINTOSTR(HEXTOBIN('414243')) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT IFNULL(a, b) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT CASE WHEN cond THEN a ELSE b END FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT add_days(d, 7) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT Add_Months(d, 3) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT lcase(s) FROM t", + "description": "Mixed-case lcase canonicalized to LOWER by parser" + }, + { + "sql": "SELECT CAST(x AS INTEGER) FROM t", + "description": "Explicit type conversion", + "expected": "SELECT CAST(x AS INT) FROM t" + }, + { + "sql": "SELECT * FROM t WHERE LOWER(name) LIKE '%john%'", + "description": "Native HANA calls preserve their name and arguments" + } + ], + "transpilation": [] +} diff --git a/crates/polyglot-sql/tests/custom_fixtures/hana/identity.json b/crates/polyglot-sql/tests/custom_fixtures/hana/identity.json new file mode 100644 index 00000000..155f747e --- /dev/null +++ b/crates/polyglot-sql/tests/custom_fixtures/hana/identity.json @@ -0,0 +1,163 @@ +{ + "dialect": "hana", + "category": "identity", + "identity": [ + { + "sql": "SELECT a, b FROM t WHERE x > 1", + "description": "Simple SELECT with WHERE" + }, + { + "sql": "SELECT \"MyColumn\" FROM \"MyTable\"", + "description": "Double-quoted mixed-case identifiers" + }, + { + "sql": "SELECT \"SELECT\" FROM \"ORDER\"", + "description": "Double-quoted reserved words as identifiers" + }, + { + "sql": "SELECT 'it''s' AS val FROM t", + "description": "Escaped single quote in string literal" + }, + { + "sql": "SELECT NULL AS x FROM t", + "description": "NULL literal in SELECT" + }, + { + "sql": "SELECT dept, COUNT(*) FROM employees GROUP BY dept ORDER BY dept", + "description": "Aggregate with GROUP BY" + }, + { + "sql": "SELECT a.x, b.y FROM a INNER JOIN b ON a.id = b.id", + "description": "INNER JOIN" + }, + { + "sql": "SELECT a.x, b.y FROM a LEFT JOIN b ON a.id = b.id WHERE b.y IS NULL", + "description": "LEFT JOIN with IS NULL" + }, + { + "sql": "SELECT * FROM a JOIN b ON a.id = b.id JOIN c ON b.id = c.id", + "description": "Multiple JOINs" + }, + { + "sql": "SELECT * FROM (SELECT x FROM t WHERE x > 0) AS sub", + "description": "Subquery in FROM" + }, + { + "sql": "SELECT * FROM t WHERE x IN (SELECT y FROM s)", + "description": "Nested subquery in WHERE" + }, + { + "sql": "WITH cte AS (SELECT x FROM t) SELECT * FROM cte", + "description": "CTE" + }, + { + "sql": "SELECT x, ROW_NUMBER() OVER (PARTITION BY y ORDER BY z) AS rn FROM t", + "description": "Window function with PARTITION BY and ORDER BY" + }, + { + "sql": "SELECT 1 FROM DUMMY UNION ALL SELECT 2 FROM DUMMY", + "description": "UNION ALL" + }, + { + "sql": "SELECT * FROM t LIMIT 10 OFFSET 5", + "description": "LIMIT and OFFSET" + }, + { + "sql": "SELECT CASE WHEN x > 1 THEN 'a' ELSE 'b' END FROM t", + "description": "CASE WHEN" + }, + { + "sql": "SELECT COALESCE(a, b, c) FROM t", + "description": "COALESCE" + }, + { + "sql": "SELECT ADD_DAYS(d, 7), IFNULL(a, b) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT SUBSTR(s, 1, 3) FROM t", + "description": "Native SUBSTR alias" + }, + { + "sql": "SELECT add_days(d, 7) FROM t", + "description": "Native HANA calls preserve their name and arguments" + }, + { + "sql": "SELECT * FROM t WHERE x IS NULL", + "description": "IS NULL in WHERE" + }, + { + "sql": "SELECT * FROM t WHERE x IS NOT NULL", + "description": "IS NOT NULL in WHERE" + }, + { + "sql": "SELECT a, b FROM t ORDER BY a, b DESC", + "description": "ORDER BY multiple columns" + }, + { + "sql": "SELECT a, b FROM t WHERE x = 1 AND y = 2 OR z = 3", + "description": "Boolean logic in WHERE" + }, + { + "sql": "SELECT a, COUNT(*) AS cnt FROM t GROUP BY a HAVING COUNT(*) > 1", + "description": "GROUP BY with HAVING" + }, + { + "sql": "SELECT * FROM t WHERE x BETWEEN 1 AND 10", + "description": "BETWEEN" + }, + { + "sql": "SELECT * FROM t WHERE x IN (1, 2, 3)", + "description": "IN list" + }, + { + "sql": "SELECT * FROM t WHERE x LIKE '%foo%'", + "description": "LIKE pattern" + }, + { + "sql": "SELECT a || b FROM t", + "description": "String concatenation" + }, + { + "sql": "SELECT COUNT(DISTINCT a) FROM t", + "description": "COUNT DISTINCT" + }, + { + "sql": "SELECT SUM(a), AVG(a), MIN(a), MAX(a) FROM t", + "description": "Aggregate functions" + }, + { + "sql": "WITH cte1 AS (SELECT 1 AS x FROM DUMMY), cte2 AS (SELECT 2 AS y FROM DUMMY) SELECT * FROM cte1, cte2", + "description": "Multiple CTEs" + }, + { + "sql": "SELECT * FROM t WHERE EXISTS (SELECT 1 FROM s WHERE s.id = t.id)", + "description": "EXISTS subquery", + "expected": "SELECT * FROM t WHERE EXISTS(SELECT 1 FROM s WHERE s.id = t.id)" + }, + { + "sql": "SELECT a, ROW_NUMBER() OVER (PARTITION BY b ORDER BY c DESC) AS rn FROM t", + "description": "Window function with DESC ordering" + }, + { + "sql": "SELECT a FROM t -- trailing comment", + "description": "Single-line comment preserved as block comment", + "expected": "SELECT a FROM t /* trailing comment */" + }, + { + "sql": "SELECT a /* inline comment */ FROM t", + "description": "Multi-line comment preserved in identity round-trip" + }, + { + "sql": "SELECT a FROM t WHERE /* outer /* inner */ x = 1", + "description": "No nested comments: first */ closes the comment", + "expected": "SELECT a FROM t WHERE x = 1" + }, + { + "sql": "select a, b from t where x > 1", + "description": "Lowercase keywords normalized to uppercase", + "expected": "SELECT a, b FROM t WHERE x > 1" + } + ], + "transpilation": [] +} diff --git a/crates/polyglot-sql/tests/custom_fixtures/hana/select.json b/crates/polyglot-sql/tests/custom_fixtures/hana/select.json new file mode 100644 index 00000000..d842f64f --- /dev/null +++ b/crates/polyglot-sql/tests/custom_fixtures/hana/select.json @@ -0,0 +1,128 @@ +{ + "dialect": "hana", + "category": "select", + "identity": [ + { + "sql": "SELECT DISTINCT x FROM t", + "description": "SELECT DISTINCT" + }, + { + "sql": "SELECT ALL x FROM t", + "description": "SELECT ALL", + "expected": "SELECT x FROM t" + }, + { + "sql": "SELECT x AS alias_name FROM t", + "description": "Column alias" + }, + { + "sql": "SELECT * FROM t", + "description": "Star select" + }, + { + "sql": "SELECT a + b * c FROM t", + "description": "Arithmetic expression" + }, + { + "sql": "SELECT a, b, a + b AS sum FROM t", + "description": "Multiple columns with expression alias" + }, + { + "sql": "SELECT CASE WHEN x > 1 THEN 'a' WHEN x > 2 THEN 'b' ELSE 'c' END FROM t", + "description": "CASE WHEN with multiple branches" + }, + { + "sql": "SELECT CASE x WHEN 1 THEN 'a' WHEN 2 THEN 'b' ELSE 'c' END FROM t", + "description": "Simple CASE expression" + }, + { + "sql": "SELECT COALESCE(a, b) FROM t", + "description": "COALESCE in SELECT" + }, + { + "sql": "SELECT 'hello world' FROM t", + "description": "String literal" + }, + { + "sql": "SELECT 'it''s a test' FROM t", + "description": "Escaped quote in string literal" + }, + { + "sql": "SELECT 1, 2, 3 FROM t", + "description": "Multiple literal select" + }, + { + "sql": "SELECT 1.5, 2.5 FROM t", + "description": "Float literals" + }, + { + "sql": "SELECT -1 FROM t", + "description": "Negative literal" + }, + { + "sql": "SELECT TRUE FROM t", + "description": "Boolean TRUE literal" + }, + { + "sql": "SELECT FALSE FROM t", + "description": "Boolean FALSE literal" + }, + { + "sql": "SELECT t.* FROM t", + "description": "Qualified star" + }, + { + "sql": "SELECT a, b FROM t AS t1", + "description": "Table alias" + }, + { + "sql": "SELECT a FROM t WHERE a IS NOT NULL", + "description": "IS NOT NULL filter" + }, + { + "sql": "SELECT a FROM t WHERE a BETWEEN 1 AND 100", + "description": "BETWEEN filter" + }, + { + "sql": "SELECT a FROM t WHERE a NOT BETWEEN 1 AND 100", + "description": "NOT BETWEEN filter" + }, + { + "sql": "SELECT a FROM t WHERE a NOT IN (1, 2, 3)", + "description": "NOT IN list" + }, + { + "sql": "SELECT a FROM t WHERE NOT (a = 1)", + "description": "NOT with parenthesized expression" + }, + { + "sql": "SELECT COUNT(*) FROM t", + "description": "COUNT star" + }, + { + "sql": "SELECT LENGTH(s) FROM t", + "description": "LENGTH function" + }, + { + "sql": "SELECT UPPER(s), LOWER(s) FROM t", + "description": "UPPER and LOWER functions" + }, + { + "sql": "SELECT TRIM(s) FROM t", + "description": "TRIM function" + }, + { + "sql": "SELECT a, b FROM t ORDER BY a ASC, b DESC", + "description": "ORDER BY with mixed ASC/DESC" + }, + { + "sql": "SELECT a FROM t GROUP BY a", + "description": "GROUP BY single column" + }, + { + "sql": "SELECT a, COUNT(*) FROM t GROUP BY a HAVING COUNT(*) > 5", + "description": "GROUP BY with HAVING" + } + ], + "transpilation": [] +} diff --git a/crates/polyglot-sql/tests/custom_fixtures/hana/types.json b/crates/polyglot-sql/tests/custom_fixtures/hana/types.json new file mode 100644 index 00000000..3b66eb65 --- /dev/null +++ b/crates/polyglot-sql/tests/custom_fixtures/hana/types.json @@ -0,0 +1,39 @@ +{ + "dialect": "hana", + "category": "types", + "identity": [ + { + "sql": "SELECT CAST(x AS SMALLDECIMAL) FROM t", + "description": "CAST to SMALLDECIMAL (HANA identity)" + }, + { + "sql": "SELECT CAST(x AS SECONDDATE) FROM t", + "description": "CAST to SECONDDATE (HANA identity)" + }, + { + "sql": "SELECT CAST(x AS ALPHANUM) FROM t", + "description": "CAST to ALPHANUM (HANA identity)" + }, + { + "sql": "SELECT CAST(x AS NVARCHAR(255)) FROM t", + "description": "CAST to NVARCHAR(255) (HANA identity)" + }, + { + "sql": "SELECT CAST(x AS CLOB) FROM t", + "description": "CAST to CLOB (HANA identity)" + }, + { + "sql": "SELECT CAST(x AS NCLOB) FROM t", + "description": "CAST to NCLOB (HANA identity)" + }, + { + "sql": "SELECT CAST(x AS BINARY) FROM t", + "description": "CAST to BINARY (HANA identity)" + }, + { + "sql": "SELECT CAST(x AS FLOAT) FROM t", + "description": "Native HANA calls preserve their name and arguments" + } + ], + "transpilation": [] +} diff --git a/crates/polyglot-sql/tests/dialect_matrix.rs b/crates/polyglot-sql/tests/dialect_matrix.rs index 67c123c5..81919074 100644 --- a/crates/polyglot-sql/tests/dialect_matrix.rs +++ b/crates/polyglot-sql/tests/dialect_matrix.rs @@ -4912,3 +4912,424 @@ mod secondary_dialects { )); } } + +#[cfg(feature = "dialect-hana")] +mod hana_regressions { + use super::*; + use polyglot_sql::expressions::Expression; + use polyglot_sql::ExpressionWalk; + + #[test] + fn native_semantics_survive_transpile_and_json() { + let hana = Dialect::get(DialectType::HANA); + for sql in [ + "SELECT LOCATE('abcabc', 'bc', 1, 2) FROM DUMMY", + "SELECT TO_DECIMAL(7654321.888888, 10, 3) FROM DUMMY", + "SELECT CURRENT_UTCTIMESTAMP(7), CURRENT_UTCDATE, CURRENT_UTCTIME FROM DUMMY", + "SELECT ADD_DAYS(d, 7), BITAND(a, b), TO_VARCHAR(d, 'YYYY-MM-DD') FROM t", + "SELECT * FROM t FOR JSON", + "SELECT * FROM t FOR XML", + "SELECT * FROM t FOR JSON ('arraywrap' = 'NO')", + "SELECT * FROM t WITH HINT (NO_INLINE)", + "ALTER TABLE t ADD (x INT)", + "CREATE TABLE t (xs INT ARRAY)", + "CREATE COLUMN TABLE t (id INT)", + "CREATE ROW TABLE t (id INT)", + "CREATE LOCAL TEMPORARY COLUMN TABLE t (id INT)", + "SELECT * FROM t FOR UPDATE IGNORE LOCKED", + "SELECT * FROM t WHERE CONTAINS(name, 'abc', FUZZY(0.8))", + "SELECT * FROM t WHERE name LIKE_REGEXPR '^a' FLAG 'i'", + "SELECT SUBSTR_REGEXPR('a' IN s OCCURRENCE 2) FROM t", + "UPSERT t VALUES (1, 8) WITH PRIMARY KEY", + "UPSERT t VALUES (2, 2) WHERE id = 2", + "UPSERT t SELECT id, val FROM source", + "CREATE COLUMN TABLE t (id INT) PARTITION BY HASH (id) PARTITIONS 4", + "CREATE COLUMN TABLE t (id INT) PARTITION BY HASH (id) NO PRIMARY KEY CHECK PARTITIONS 4", + "CREATE COLUMN TABLE t (id INT) PARTITION BY RANGE (id) PRIMARY KEY CHECK (PARTITION OTHERS)", + "SELECT * FROM HIERARCHY(SOURCE (SELECT id AS node_id, parent AS parent_id FROM t))", + "SELECT * FROM HIERARCHY(SOURCE t START WHERE id = 1 SIBLING ORDER BY id ORPHAN ROOT)", + r#"SELECT * FROM "_SYS_BIC"."pkg/view"(PLACEHOLDER."$$P$$" => 'X')"#, + "SELECT * FROM t FOR JSON ('arraywrap' = 'NO') RETURNS NVARCHAR(5000)", + "SELECT * FROM t FOR XML RETURNS NCLOB", + "SELECT * FROM t FOR SHARE LOCK WAIT 3", + "SELECT * FROM t FOR SHARE LOCK IGNORE LOCKED", + "SELECT * FROM t ORDER BY a WITH COLLATION ENGLISH WITH HINT (NO_INLINE CASCADE)", + "CALL demo.proc(1, ?) ASYNC WITH HINT (NO_INLINE)", + "CALL demo.library:member(1)", + "SELECT JSON_VALUE(j, '$.a' RETURNING INT DEFAULT 0 ON EMPTY ERROR ON ERROR) FROM t", + "SELECT JSON_QUERY(j, '$.a' WITH CONDITIONAL ARRAY WRAPPER EMPTY ARRAY ON EMPTY NULL ON ERROR) FROM t", + "SELECT * FROM JSON_TABLE(j, '$' COLUMNS (rn FOR ORDINALITY, v NVARCHAR(20) PATH '$.v' DEFAULT 'missing' ON EMPTY ERROR ON ERROR))", + "SELECT * FROM JSON_TABLE(j, '$' COLUMNS (NESTED PATH '$.a[*]' COLUMNS (v INT PATH '$.v')) ERROR ON ERROR)", + "SELECT CAST(x AS ST_GEOMETRY(4326)), CAST(y AS REAL_VECTOR(3)) FROM t", + "CREATE COLUMN TABLE t (id INT) NO AUTO MERGE UNLOAD PRIORITY 5", + "CREATE TABLE t (id INT) RECORD COMMIT TIMESTAMP", + "CREATE TABLE t (id INT, next_id INT GENERATED ALWAYS AS id + 1)", + + "CREATE COLUMN TABLE t (id INT) PARTITION BY RANGE (id) (PARTITION 0 <= VALUES < 100, PARTITION OTHERS)", + "CREATE COLUMN TABLE t (id INT) PARTITION BY HASH (id) PARTITIONS 4 SUBPARTITION BY RANGE (id) (PARTITION VALUES < 100, PARTITION OTHERS DYNAMIC THRESHOLD 1000)", + "CREATE COLUMN TABLE t (id INT) PARTITION BY RANGE (id) (PARTITION VALUES = 1 PAGE LOADABLE, PARTITION OTHERS DYNAMIC INCREASING INTERVAL 10)", + "SELECT CURRENT_CONNECTION, CURRENT_SCHEMA, CURRENT_USER, SESSION_USER, SYSUUID FROM DUMMY", + "SELECT NTH_VALUE(x, 2 ORDER BY y), STRING_AGG(s, ',' ORDER BY id) FROM t", + "SELECT * FROM t WHERE s NOT LIKE_REGEXPR '^a' FLAG 'i'", + "SELECT REPLACE_REGEXPR('a' IN s WITH 'b' OCCURRENCE ALL) FROM t", + "SELECT LOCATE_REGEXPR(AFTER 'a' IN s FROM 2 OCCURRENCE 1 GROUP 0) FROM t", + "SELECT a, b, SUM(x) FROM t GROUP BY GROUPING SETS BEST -1 LIMIT 2 OFFSET 1 WITH SUBTOTAL WITH BALANCE WITH TOTAL ((a), (b))", + "SELECT a, SUM(x) FROM t GROUP BY ROLLUP STRUCTURED RESULT WITH OVERVIEW PREFIX '#groups' (a)", + "SELECT a, SUM(x) FROM t GROUP BY CUBE MULTIPLE RESULTSETS (a)", + "SELECT * FROM t LIMIT 1 OFFSET 2 TOTAL ROWCOUNT", + "SELECT LOCALTOUTC(ts, 'EST', 'sap' NULL ON ERROR) FROM t", + "SELECT UTCTOLOCAL(ts, 'INVALID', 'sap' DEFAULT '2025-01-01 00:00:00' ON ERROR) FROM t", + ] { + let ast = hana.parse(sql).unwrap_or_else(|err| panic!("{sql}: {err}")); + assert!(!ast[0].dfs().any(|node| matches!(node, Expression::Raw(_) | Expression::Command(_))), "{sql}"); + let json = serde_json::to_string(&ast).unwrap(); + let decoded: Vec = serde_json::from_str(&json).unwrap(); + let output = hana.generate(&decoded[0]).unwrap(); + assert_eq!(output, sql, "AST round trip: {sql}"); + assert_eq!(hana.transpile(sql, DialectType::HANA).unwrap(), vec![sql], "transpile: {sql}"); + } + } + + #[test] + fn preserves_quoted_and_qualified_names() { + let sql = "SELECT \"CURRENT_UTCDATE\", t.CURRENT_UTCTIME, \"ADD_DAYS\"(d, 1) FROM t"; + assert_eq!(transpile(sql, DialectType::HANA, DialectType::HANA), sql); + } + + #[test] + fn native_children_participate_in_ast_mutations() { + use polyglot_sql::ast_transforms::{rename_columns, rename_tables}; + let hana = Dialect::get(DialectType::HANA); + for sql in [ + "SELECT LOCATE(value, 'a'), JSON_VALUE(payload, '$.n' DEFAULT value ON EMPTY) FROM records", + "SELECT SUBSTR_REGEXPR('a' IN value), LOCALTOUTC(value, 'UTC') FROM records ORDER BY value", + "SELECT value, SUM(n) FROM records GROUP BY ROLLUP BEST 1 (value)", + "SELECT * FROM HIERARCHY(SOURCE (SELECT value AS node_id, parent AS parent_id FROM records))", + "UPSERT target_table SELECT value FROM source_table", + "CREATE TABLE records (value INT, next_value INT GENERATED ALWAYS AS value + 1) PARTITION BY HASH (value) PARTITIONS 4", + ] { + let ast = hana.parse(sql).unwrap().remove(0); + assert!(ast.dfs().any(|e| matches!(e, Expression::Column(c) if c.name.name == "value")), "{sql}"); + let renamed = rename_columns(ast.clone(), &[("value".to_owned(), "renamed".to_owned())].into()); + assert!(!renamed.dfs().any(|e| matches!(e, Expression::Column(c) if c.name.name == "value")), "{sql}"); + assert!(renamed.dfs().any(|e| matches!(e, Expression::Column(c) if c.name.name == "renamed")), "{sql}"); + assert!(ast.dfs().any(|e| matches!(e, Expression::Column(c) if c.name.name == "value")), "{sql}"); + } + let ast = hana + .parse("UPSERT target_table SELECT value FROM source_table") + .unwrap() + .remove(0); + let renamed = rename_tables( + ast, + &[ + ("target_table".to_owned(), "new_target".to_owned()), + ("source_table".to_owned(), "new_source".to_owned()), + ] + .into(), + ); + assert_eq!( + hana.generate(&renamed).unwrap(), + "UPSERT new_target SELECT value FROM new_source" + ); + } + + #[test] + fn quoted_reserved_names_and_qualified_calls_are_not_builtins() { + for sql in [ + r#"SELECT "CURRENT_USER", t.CURRENT_SCHEMA, demo."ADD_DAYS"(d, 1) FROM t"#, + r#"SELECT "COUNT"(x) FROM t"#, + ] { + assert_eq!(transpile(sql, DialectType::HANA, DialectType::HANA), sql); + } + } + + #[test] + fn incoming_queries_generate_native_syntax_or_report_unsupported() { + assert_eq!( + transpile("SELECT 1", DialectType::Generic, DialectType::HANA), + "SELECT 1 FROM DUMMY" + ); + for (sql, source) in [ + ("SELECT SUBSTRING('abcdef', -2, 2)", DialectType::DuckDB), + ("SELECT DATE_ADD('day', 1, d) FROM t", DialectType::Trino), + ("SELECT x ILIKE 'a%' FROM t", DialectType::PostgreSQL), + ] { + assert!( + Dialect::get(source) + .transpile(sql, DialectType::HANA) + .is_err(), + "{sql}" + ); + } + } + + #[test] + fn source_casts_retain_conversion_semantics() { + assert_eq!( + transpile("SELECT UNKNOWN", DialectType::HANA, DialectType::HANA), + "SELECT NULL FROM DUMMY" + ); + assert_eq!( + transpile("SELECT UNKNOWN", DialectType::HANA, DialectType::DuckDB), + "SELECT NULL" + ); + assert_eq!( + transpile( + r#"SELECT "UNKNOWN" FROM t"#, + DialectType::HANA, + DialectType::HANA + ), + r#"SELECT "UNKNOWN" FROM t"# + ); + + for (sql, expected) in [ + ( + "SELECT CAST(-12.349 AS DECIMAL(5, 2))", + "SELECT CAST(TRUNC(-12.349, 2) AS DECIMAL(5, 2))", + ), + ( + "SELECT CAST(12.99 AS DECIMAL(5))", + "SELECT CAST(TRUNC(12.99, 0) AS DECIMAL(5, 0))", + ), + ( + "SELECT CAST(-12.349 AS DEC(5, 2))", + "SELECT CAST(TRUNC(-12.349, 2) AS DECIMAL(5, 2))", + ), + ] { + assert_eq!( + transpile(sql, DialectType::HANA, DialectType::DuckDB), + expected + ); + } + assert_eq!( + transpile( + "SELECT CAST(255 AS TINYINT)", + DialectType::HANA, + DialectType::Trino + ), + "SELECT CAST(255 AS SMALLINT)" + ); + assert!(Dialect::get(DialectType::HANA) + .transpile( + "SELECT CAST(x AS DECIMAL(10, 2)) FROM t", + DialectType::DuckDB + ) + .is_err()); + } + + #[test] + fn rejects_unverified_string_domains_and_volatile_bounds() { + for sql in [ + "SELECT SUBSTRING(s, -2, 2) FROM t", + "SELECT SUBSTRING('abcdef', RAND(), 2) FROM DUMMY", + "SELECT SUBSTRING('a😀b', 2, 1) FROM DUMMY", + "SELECT SUBSTRING(x'ABCDEF', 1, 2) FROM DUMMY", + "SELECT LOCATE('a😀b', 'b') FROM DUMMY", + "SELECT LOCATE(s, 'b') FROM t", + "SELECT LOCATE('abc', '', 2) FROM DUMMY", + "SELECT LOCATE('abc', '', 1, 2) FROM DUMMY", + "SELECT TO_DECIMAL(CAST(s AS NVARCHAR(30)), 10, 2) FROM t", + ] { + for target in [ + DialectType::Trino, + DialectType::DuckDB, + DialectType::PostgreSQL, + ] { + assert!( + Dialect::get(DialectType::HANA) + .transpile(sql, target) + .is_err(), + "{sql} -> {target}" + ); + } + } + } + + #[test] + fn validates_native_precision_and_function_arity() { + let hana = Dialect::get(DialectType::HANA); + for sql in [ + "SELECT LOCATE('a') FROM DUMMY", + "SELECT SUBSTRING('a') FROM DUMMY", + "SELECT CURRENT_UTCTIMESTAMP(8) FROM DUMMY", + "SELECT CURRENT_UTCTIMESTAMP(x) FROM t", + "SELECT CAST(x AS FLOAT(0)) FROM t", + "SELECT CAST(x AS FLOAT(54)) FROM t", + "SELECT CAST(x AS DECIMAL(10, 11)) FROM t", + "SELECT CAST(x AS SMALLDECIMAL(10, 2)) FROM t", + "SELECT CAST(x AS NVARCHAR(5001)) FROM t", + ] { + assert!(hana.parse(sql).is_err(), "{sql}"); + } + } + + #[test] + fn source_semantics_generate_safe_target_expressions() { + for target in [ + DialectType::Presto, + DialectType::Athena, + DialectType::Dune, + DialectType::DuckDB, + ] { + assert!(Dialect::get(DialectType::HANA) + .transpile( + "SELECT TO_TIMESTAMP(s, 'YYYY-MM-DD HH24:MI:SS') FROM t", + target + ) + .is_err()); + } + for (sql, target, expected) in [ + ( + "SELECT LOCATE('abcabc', 'bc')", + DialectType::Trino, + "SELECT STRPOS('abcabc', 'bc')", + ), + ( + "SELECT LOCATE('length in char', '')", + DialectType::Trino, + "SELECT STRPOS('length in char', '')", + ), + ( + "SELECT TO_TIMESTAMP('2024-01-15 12:30:45', 'YYYY-MM-DD HH24:MI:SS')", + DialectType::Trino, + "SELECT CAST(DATE_PARSE('2024-01-15 12:30:45', '%Y-%m-%d %H:%i:%s') AS TIMESTAMP(7))", + ), + ( + "SELECT SUBSTRING('abcdef', -2, 2)", + DialectType::DuckDB, + "SELECT SUBSTRING('abcdef', 1, 2)", + ), + ( + "SELECT TO_DECIMAL(7654321.888888, 10, 3)", + DialectType::DuckDB, + "SELECT CAST(TRUNC(7654321.888888, 3) AS DECIMAL(10, 3))", + ), + ( + "SELECT TO_DATE('2024-01-15', 'YYYY-MM-DD')", + DialectType::Trino, + "SELECT CAST(DATE_PARSE('2024-01-15', '%Y-%m-%d') AS DATE)", + ), + ( + "SELECT CAST(x AS FLOAT(24)), CAST(y AS FLOAT(53)) FROM t", + DialectType::Trino, + "SELECT CAST(x AS REAL), CAST(y AS DOUBLE) FROM t", + ), + ( + "SELECT CAST(x AS LONGDATE), CAST(y AS TIME) FROM t", + DialectType::Trino, + "SELECT CAST(x AS TIMESTAMP(7)), CAST(y AS TIME(0)) FROM t", + ), + ] { + assert_eq!(transpile(sql, DialectType::HANA, target), expected); + let ast = Dialect::get(DialectType::HANA).parse(sql).unwrap(); + assert_eq!(Dialect::get(target).generate(&ast[0]).unwrap(), expected); + } + } + + #[test] + fn incompatible_hana_features_fail_in_every_mode() { + for sql in [ + "SELECT * FROM t FOR JSON", + "SELECT * FROM t FOR XML", + "SELECT TO_VARCHAR(1234.5, '9,999.00')", + "SELECT TO_VARCHAR(d, fmt) FROM t", + "SELECT TO_TIMESTAMP(s, 'YYYY-MM-DD HH24:MI:SS.FF7') FROM t", + "SELECT CAST(x AS SMALLDECIMAL) FROM t", + "SELECT ADD_MONTHS_LAST(d, 1) FROM t", + "SELECT * FROM t WITH HINT (NO_INLINE)", + "SELECT * FROM t FOR UPDATE IGNORE LOCKED", + "SELECT * FROM HIERARCHY(SOURCE t)", + "SELECT JSON_VALUE(j, '$.a' ERROR ON ERROR) FROM t", + "SELECT SUBSTR_REGEXPR('a' IN s) FROM t", + "UPSERT t VALUES (1) WITH PRIMARY KEY", + "CREATE COLUMN TABLE t (a INT)", + "CALL demo.proc(1)", + "SELECT a, SUM(x) FROM t GROUP BY ROLLUP BEST 1 (a)", + "SELECT * FROM t LIMIT 1 TOTAL ROWCOUNT", + "SELECT LOCALTOUTC(ts, 'EST', 'sap' NULL ON ERROR) FROM t", + ] { + for target in [ + DialectType::Generic, + DialectType::PostgreSQL, + DialectType::MySQL, + DialectType::BigQuery, + DialectType::Snowflake, + DialectType::DuckDB, + DialectType::SQLite, + DialectType::Hive, + DialectType::Spark, + DialectType::Trino, + DialectType::Presto, + DialectType::Redshift, + DialectType::TSQL, + DialectType::Oracle, + DialectType::ClickHouse, + DialectType::Databricks, + DialectType::Athena, + DialectType::Teradata, + DialectType::Doris, + DialectType::StarRocks, + DialectType::Materialize, + DialectType::RisingWave, + DialectType::SingleStore, + DialectType::CockroachDB, + DialectType::TiDB, + DialectType::Druid, + DialectType::Solr, + DialectType::Tableau, + DialectType::Dune, + DialectType::Fabric, + DialectType::Drill, + DialectType::Dremio, + DialectType::Exasol, + DialectType::DataFusion, + ] { + let ast = Dialect::get(DialectType::HANA).parse(sql).unwrap(); + assert!( + Dialect::get(target).generate(&ast[0]).is_err(), + "direct: {sql} -> {target}" + ); + for level in [ + UnsupportedLevel::Ignore, + UnsupportedLevel::Warn, + UnsupportedLevel::Raise, + UnsupportedLevel::Immediate, + ] { + assert!( + Dialect::get(DialectType::HANA) + .transpile_with( + sql, + target, + TranspileOptions::default().with_unsupported_level(level) + ) + .is_err(), + "{sql} -> {target}: {level:?}" + ); + } + } + } + } + + #[test] + fn hana_storage_checks_do_not_apply_to_other_sources() { + let sql = "CREATE GLOBAL TEMPORARY TABLE t (a INT)"; + let output = Dialect::get(DialectType::Teradata) + .transpile(sql, DialectType::Teradata) + .unwrap(); + assert!(output[0].contains("GLOBAL TEMPORARY TABLE")); + assert!(Dialect::get(DialectType::HANA) + .transpile(sql, DialectType::Teradata) + .is_err()); + } + + #[test] + fn unrelated_custom_types_are_unchanged() { + for name in ["SMALLDECIMAL", "ALPHANUM", "SECONDDATE"] { + let sql = format!("SELECT CAST(x AS {name}) FROM t"); + assert_eq!( + transpile(&sql, DialectType::PostgreSQL, DialectType::PostgreSQL), + sql + ); + } + } +} diff --git a/docs/hana/README.md b/docs/hana/README.md new file mode 100644 index 00000000..83824c15 --- /dev/null +++ b/docs/hana/README.md @@ -0,0 +1,148 @@ +# SAP HANA support + +The `hana` dialect targets SAP HANA Cloud QRC 2/2026 and HANA Platform 2.0 SPS 08. +`hana`, `saphana`, and `sap_hana` are accepted Rust dialect names. The public SDK +name is `hana` (`Dialect.HANA` in TypeScript). + +This implementation starts from [Torsten Glunde's PR #276](https://github.com/tobilg/polyglot/pull/276), +reviewed at `a452c0acd0a38892ef05e424b5ba94dc247bf3f0`, and replaces its unconditional +function and custom-type rewrites. Parser, expression, and generator changes are +integrated into the existing shared files. + +## Coverage and limits + +**This is not complete coverage of either SQL reference.** The inventories below +track the reference surface, including remaining work. Recognizing a function name, +parsing one example, and implementing every documented form are different levels +of support. A successful parse does not validate server privileges, object +existence, installed components, or runtime argument values. + +Native forms covered by regression tests include: + +- Ordinary queries, joins, CTEs, aggregates, window functions, common DML, and + basic table/view DDL, using the existing shared AST. +- HANA function calls with source provenance, including conversion, date/time, + string, bitwise, series-generation, and vector function names. Special argument + grammars need explicit parser support; registration alone does not provide it. +- `LOCATE` with two to four arguments; `SUBSTRING`/`SUBSTR`; decimal and formatted + date/string conversions; local and UTC current-time expressions and precision. +- Native numeric, string, LOB, spatial, and vector type names, including HANA's + unsigned `TINYINT`, precision-dependent `FLOAT`, and floating-decimal types. +- `FOR JSON`/`FOR XML`, including options and `RETURNS`; `WITH HINT`; query collation; + `FOR UPDATE` and `FOR SHARE LOCK`, including `IGNORE LOCKED`; `LIMIT ... TOTAL ROWCOUNT`. +- Grouping-set, rollup, and cube selection options (`BEST`, `LIMIT`, `OFFSET`, + subtotal/balance/total), structured results, prefixes, and multiple result sets. +- `LOCALTOUTC` and `UTCTOLOCAL` dataset/schema arguments and `ON ERROR` policies. +- `JSON_VALUE`, `JSON_QUERY`, and `JSON_TABLE`, with structured paths, return types, + wrapper behavior, defaults, error/empty behavior, ordinality, and nested columns. +- `UPSERT` values/query forms, partition and column lists, conditions, and + `WITH PRIMARY KEY`. +- Row/column and local/global temporary table modifiers; parenthesized `ALTER + TABLE ... ADD`; postfix array types; hash, round-robin, and balanced range + partitioning, subpartitioning, selected storage properties, and generated columns. +- Boolean `UNKNOWN` as the documented synonym for `NULL`, while retaining quoted names. +- `LIKE_REGEXPR`, `SUBSTR_REGEXPR`/`SUBSTRING_REGEXPR`, `LOCATE_REGEXPR`, + `OCCURRENCES_REGEXPR`, and `REPLACE_REGEXPR` clauses. +- `HIERARCHY` and `HIERARCHY_SPANTREE` source/options syntax; calculation-view + `PLACEHOLDER` arguments and qualified, quoted table function names. +- Procedure and library-member `CALL`, including asynchronous calls and hints. + +Remaining gaps include administrative and access-control grammar, advanced table, +view, index and temporal DDL, heterogeneous partition trees, association paths, +series specifications inside aggregates/windows, +additional hierarchy families, spatial method mappings, advanced search scoring, and special function +clauses. Procedure/function definitions are not implemented by the supported +`CALL` syntax. These are not covered merely because another spelling or a simpler +form parses. SQLScript body grammar is outside this dialect's scope. + +Unknown statement fallbacks that would produce `Raw` or `Command` nodes are +rejected. Unsupported forms can therefore fail native parsing rather than appear +to have structured support. The shared parser is permissive and is not a complete +HANA grammar validator; for example, accepted SELECTs without a FROM clause are +rendered with `FROM DUMMY` for a HANA target. + +## Translation policy + +HANA-specific AST nodes retain source semantics through JSON serialization and +independent target generation. A known HANA function is not automatically treated +as a compatible target function. Unverified mappings return an unsupported error, +including at `Ignore` and `Warn`, rather than silently dropping a result-shaping +clause or emitting a known incompatible operation. Checks run before target +normalization can erase protected casts or query options. + +Implemented scalar mappings are deliberately bounded: + +| Source operation | Targets | Conditions | +|---|---|---| +| `COALESCE`, `IFNULL` | Existing SQL targets | Standard coalescing form | +| `LOCATE` | Trino family, PostgreSQL family, DuckDB | Literal BMP strings, nonnegative constant start, positive occurrence; repeated occurrence requires Trino family | +| `SUBSTRING`, `SUBSTR` | Same families | Literal BMP string and constant bounds; starts below 1 clamp to 1 and lengths below 1 clamp to 0 | +| `TO_DECIMAL(value,p,s)` and fixed-decimal casts | Same families | Proven exact numeric input and valid constant precision/scale; truncate before cast | +| Formatted date parsing/formatting | Trino family, DuckDB | Supported literal datetime mask; formatting requires datetime type evidence; date parsing retains a DATE result; timestamp parsing is restricted to Trino with an explicit TIMESTAMP(7) result | +| UTC clock expressions | Selected Trino/PostgreSQL/DuckDB forms | Explicit UTC zone and representable precision; other forms report unsupported | +| `TIMESTAMP` / `LONGDATE`, `TIME` | Trino | Explicit `TIMESTAMP(7)` / `TIME(0)`; targets with unverified precision report unsupported | +| `FLOAT(p)` | Trino, Presto, PostgreSQL, DuckDB | `p <= 24` maps to REAL; larger/default precision maps to double precision | +| `TINYINT` | DuckDB, ClickHouse | Unsigned type; selected constant casts also widen safely on Trino/Presto/PostgreSQL | + +Unknown/binary/supplementary-Unicode string inputs, dynamic bounds or masks, +negative-start searches, empty-needle searches with offsets/repetition, floating-decimal conversions, and unsupported timestamp +precision are not approximated. HANA indexes CESU-8/UTF-16 character units, which +can differ from target Unicode code-point indexing. The `DEC`, `DAYDATE`, and `LONGDATE` aliases retain their canonical type semantics. +Qualified/quoted user-defined +names remain distinct from unqualified built-ins. + +Basic SQL can be generated for a HANA target. Foreign operations with unverified +HANA semantics, including positional strings, formatted time conversion, +time-zone-sensitive clocks, and dialect date arithmetic, can report unsupported. +Transpilation does not migrate procedures, calculation views, catalogs, privileges, +or system tables such as `DUMMY` into another database. + +## Reference inventory and evidence + +- [Cloud reference inventory](cloud-reference.json): pinned QRC 2/2026 topics. +- [Platform function inventory](functions.json): Platform 2.0 SPS 08 function topics. +- [Platform statement inventory](statements.json): Platform 2.0 SPS 08 statement topics. +- Native fixtures: `crates/polyglot-sql/tests/custom_fixtures/hana/`. +- Source semantics, JSON AST round trips, quoting, boundary and all-target error + policy tests: the existing `tests/dialect_matrix.rs` HANA regression module. +- Binding regressions: existing WASM, FFI, Python, Go, and TypeScript test files. + +Reference-example probes are a syntax audit, not a HANA server execution suite. +Documentation examples containing placeholders, omitted separators, typographical +errors, or excluded SQLScript require manual review before becoming test fixtures. +DuckDB execution checks verify selected scalar result values. HANA server execution +has not been performed. + +The adjacent SQLGlot Oracle, MySQL, Snowflake, and Presto/Trino implementations +informed argument ordering, format-token handling, and source/target separation. +The checked-in SQLGlot has no HANA dialect; its output is not a HANA specification. +No SQLGlot fixture exclusions were added for this implementation. + +## Validation + +Verified locally on 2026-09-22: + +- `make test-rust-verify`, including existing SQLGlot fixtures, the 132 native + HANA fixtures, ClickHouse parser and round-trip suites, and FFI tests. +- All 12 focused HANA regression tests in `dialect_matrix.rs`. +- Parse-only, generation, and transpilation builds with only `dialect-hana`, + plus a HANA-only WASM discovery/native parsing test. +- Rebuilt WASM and TypeScript SDK: 613 tests; TypeScript type checking. +- Rebuilt Python extension: 321 tests passed, one skipped; Python type checking. +- Go tests against the rebuilt FFI library, with the test cache disabled. +- Formatting, project consistency, and unchanged released changelog entries. + +Passing these checks establishes the tested behavior and regression baseline; +it does not establish complete SQL-reference or server-execution coverage. + +## References + +- [HANA Cloud SQL reference](https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209f5020751910148fd8fe88aa4d79d9.html?version=2026_2_QRC) +- [Platform 2.0 SPS 08 SQL reference](https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf) +- [HANA character encoding](https://help.sap.com/docs/SAP_HANA_CLIENT/f1b440ded6144a54ada97ff95dac7adf/5d221fc0e8b54c9d8eddd7748cdf398b.html) +- [Trino datetime functions](https://trino.io/docs/current/functions/datetime.html) +- [Trino string functions](https://trino.io/docs/current/functions/string.html) +- [Trino data types](https://trino.io/docs/current/language/types.html) +- [Trino numeric functions](https://trino.io/docs/current/functions/math.html) + +Timestamp mappings are checked per target. See also the [Presto types reference](https://www.prestodb.io/docs/current/language/types.html) and [Athena timestamp restrictions](https://docs.aws.amazon.com/athena/latest/ug/engine-versions-reference-0003.html). diff --git a/docs/hana/cloud-reference.json b/docs/hana/cloud-reference.json new file mode 100644 index 00000000..d243ff76 --- /dev/null +++ b/docs/hana/cloud-reference.json @@ -0,0 +1,6824 @@ +[ + { + "title": "Introduction to SQL", + "path": [ + "SQL Reference" + ], + "file": "209f5020751910148fd8fe88aa4d79d9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209f5020751910148fd8fe88aa4d79d9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SQL Notation Conventions", + "path": [ + "SQL Reference" + ], + "file": "209e0cde751910149114be53649a1fb7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209e0cde751910149114be53649a1fb7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Binary Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "6b977a21b1d64dfca67c4f9d1c47f4e2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6b977a21b1d64dfca67c4f9d1c47f4e2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Boolean Data Type", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "f044a9c7fb7b49159384f92f147345fb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f044a9c7fb7b49159384f92f147345fb.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Character String Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "a33f7884b0c14c00b1a76ecd8af5feca.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a33f7884b0c14c00b1a76ecd8af5feca.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Data Type Conversion", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "46ff9650c7f44461a6146269c1e2a4c6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/46ff9650c7f44461a6146269c1e2a4c6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Datetime Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "3f81ccc7e35d44cbbc595c7d552c202a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3f81ccc7e35d44cbbc595c7d552c202a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "JSON as a SQL Data Type", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "735f74fc82d94e88a9b7040f4c49d051.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/735f74fc82d94e88a9b7040f4c49d051.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Large Object (LOB) Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "c374aca91944460b834ef1d5ceb82acf.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c374aca91944460b834ef1d5ceb82acf.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Multi-valued Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "cae8b00a6a964cb8a06d2c00dac4ad05.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/cae8b00a6a964cb8a06d2c00dac4ad05.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Numeric Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "4ee2f261e9c44003807d08ccc2e249ac.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4ee2f261e9c44003807d08ccc2e249ac.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Spatial Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "8efe5a4fe55a4607b6befd83807f79df.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8efe5a4fe55a4607b6befd83807f79df.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Vector Data Types", + "path": [ + "SQL Reference", + "Data Types" + ], + "file": "04cfbb84101145d283680d28edb1e26e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/04cfbb84101145d283680d28edb1e26e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Reserved Words", + "path": [ + "SQL Reference" + ], + "file": "28bcd6af3eb6437892719f7c27a8a285.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/28bcd6af3eb6437892719f7c27a8a285.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Operators", + "path": [ + "SQL Reference" + ], + "file": "20a380977519101494ceddd944e87527.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a380977519101494ceddd944e87527.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Expressions", + "path": [ + "SQL Reference" + ], + "file": "20a4389775191014b5a6bf2ccc0df2ed.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a4389775191014b5a6bf2ccc0df2ed.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Comparison Predicates (ANY, SOME, and ALL)", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "20f91040751910148e96d6cb73119afc.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f91040751910148e96d6cb73119afc.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "BETWEEN Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "20faa69a75191014b3c8e132b035d5a8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20faa69a75191014b3c8e132b035d5a8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CONTAINS Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "20f952437519101487edc3d9aba84238.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f952437519101487edc3d9aba84238.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "EXISTS Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "20f9915f75191014a3d7aa14a0637e41.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f9915f75191014a3d7aa14a0637e41.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "IN Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "20f9d29a7519101483fb90fe2fadc959.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f9d29a7519101483fb90fe2fadc959.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "LIKE Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "20fa17f375191014a4d8d8cbfddfe340.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fa17f375191014a4d8d8cbfddfe340.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "LIKE_REGEXPR Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "b40d483dd34d47aa9cc89b4d8a6e617e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b40d483dd34d47aa9cc89b4d8a6e617e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "MEMBER OF Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "f666b950e5d34f84bb5b6f125e7e85c4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f666b950e5d34f84bb5b6f125e7e85c4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "NULL Predicate", + "path": [ + "SQL Reference", + "Predicates" + ], + "file": "20fa62ef75191014a797dae048566adc.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fa62ef75191014a797dae048566adc.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Session Variables", + "path": [ + "SQL Reference" + ], + "file": "a16678c085bf475f832c10b2629f3997.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a16678c085bf475f832c10b2629f3997.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "HANA_CLOUD Macro", + "path": [ + "SQL Reference" + ], + "file": "6694324fbf4f4e1eb3b82f32ae0ffddd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6694324fbf4f4e1eb3b82f32ae0ffddd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ABAP_ALPHANUM Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "e4887a42a3eb4d5d88bf84da66c07668.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e4887a42a3eb4d5d88bf84da66c07668.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ABAP_DF16RAW_TO_SMALLDECIMAL Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "323345041b9343479807a1c3dff38715.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/323345041b9343479807a1c3dff38715.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ABAP_DF34RAW_TO_DECIMAL Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d88c19d816db4a58805bdc575c78e70c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d88c19d816db4a58805bdc575c78e70c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ABAP_LOWER Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f59d04cc4cc740ed80fbfd4b422f9842.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f59d04cc4cc740ed80fbfd4b422f9842.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ABAP_NUMC Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "6ccf1d971bca4bb6bb59f19fe6e1e6c9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6ccf1d971bca4bb6bb59f19fe6e1e6c9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ABAP_UPPER Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "0e34e8f7185e4909a35ed89dc5ee1229.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0e34e8f7185e4909a35ed89dc5ee1229.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ABS Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20da27c175191014b7b3ecbd7dd130b2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da27c175191014b7b3ecbd7dd130b2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ACOS Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20da43ce751910148d53a3c6f36d4873.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da43ce751910148d53a3c6f36d4873.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ADD_DAYS Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20da5fa8751910148969da2572b25ed8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da5fa8751910148969da2572b25ed8.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "ADD_MONTHS Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20da7b237519101489f3e2e1a284355a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da7b237519101489f3e2e1a284355a.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "ADD_MONTHS_LAST Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "0eda0f731fb34bd2a6237cd7d33374ef.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0eda0f731fb34bd2a6237cd7d33374ef.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "ADD_NANO100 Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "3962389a62b149b69d497bb25f4ec01a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3962389a62b149b69d497bb25f4ec01a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ADD_SECONDS Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20da994e75191014a6e4bf620c179299.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da994e75191014a6e4bf620c179299.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "ADD_WORKDAYS Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22c8391d2951014815a84e76cf66501.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22c8391d2951014815a84e76cf66501.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ADD_YEARS Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dab50375191014bd8fe42e781bdaa0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dab50375191014bd8fe42e781bdaa0.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "AI_TABULAR_PREDICTION (Procedural)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "05d1298b43e849d6896345a0ba2b4c72.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/05d1298b43e849d6896345a0ba2b4c72.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "AI_TEXT_COMPLETION Function (AI)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "036f73d0fd374d1492f61499cdcd29af.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/036f73d0fd374d1492f61499cdcd29af.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ALLOW_PRECISION_LOSS Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "5fd2a1b5a00649be90a77e6a712c164b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5fd2a1b5a00649be90a77e6a712c164b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ASCII Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dad083751910149584c5724f67488b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dad083751910149584c5724f67488b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ASIN Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20daebda751910148c77ac06bb049df2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20daebda751910148c77ac06bb049df2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ATAN Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db38e775191014b31aa470840e14c6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db38e775191014b31aa470840e14c6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ATAN2 Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db65417519101484eded495b2526ae.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db65417519101484eded495b2526ae.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "AUTO_CORR Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "e279ce4d3fbb41a2801057f93dced141.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e279ce4d3fbb41a2801057f93dced141.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "AVG Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "2c93334adf654054a948cc7f151887de.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2c93334adf654054a948cc7f151887de.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "BINNING Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "9a78dfb3cd8240f4be22495a098e65ea.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9a78dfb3cd8240f4be22495a098e65ea.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "BINTOHEX Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db6dd27519101485b2978452f92bbd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd27519101485b2978452f92bbd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "BINTONHEX Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "0662e967cf0342679ce7adf1a0e16aca.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0662e967cf0342679ce7adf1a0e16aca.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "BINTOSTR Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22ce32dd295101481d58e6625b2112d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22ce32dd295101481d58e6625b2112d.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "BITAND Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db6dd3751910148a57978452f92bbd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd3751910148a57978452f92bbd.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "BITCOUNT Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "12501aa67d624a87a60be1eda9c1d093.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/12501aa67d624a87a60be1eda9c1d093.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "BITNOT Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "7c5d6f9cea634b1ab572a8d358aee825.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7c5d6f9cea634b1ab572a8d358aee825.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "BITOR Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "8c10a2303bc34150921debf745c25fe6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8c10a2303bc34150921debf745c25fe6.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "BITSET Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22d0974d29510149373deadadc83fe4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22d0974d29510149373deadadc83fe4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "BITUNSET Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22d21ddd2951014a15dcdbdf3fc5e00.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22d21ddd2951014a15dcdbdf3fc5e00.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "BITXOR Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "bab52a76fde24045bce31993aa3b3c82.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bab52a76fde24045bce31993aa3b3c82.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CARDINALITY Function (Array)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "21c6746955ce4cc2809801c5b0e93817.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/21c6746955ce4cc2809801c5b0e93817.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CARDINALITY Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "5659861eb0254db9a6673f7913d82b43.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5659861eb0254db9a6673f7913d82b43.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CAST Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db6dd475191014aa7b978452f92bbd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd475191014aa7b978452f92bbd.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "CEIL Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db6dd575191014b704978452f92bbd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd575191014b704978452f92bbd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CHAR Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db6dd675191014a4fd978452f92bbd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd675191014a4fd978452f92bbd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "COALESCE Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20db6dd7751910149105978452f92bbd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd7751910149105978452f92bbd.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "CONCAT Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dd51f775191014990682ac74bbefe8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dd51f775191014990682ac74bbefe8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CONCAT_NAZ Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "5e7c8dd968d74c009bef98028837d5a9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5e7c8dd968d74c009bef98028837d5a9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CONVERT_CURRENCY Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22d746ed2951014bb7fb0114ffdaf96.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22d746ed2951014bb7fb0114ffdaf96.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CONVERT_UNIT Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f43ae7bb6f5b1014a345adb9db626de0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f43ae7bb6f5b1014a345adb9db626de0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CORR Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "aa049c2602824ba091b1b58153a310e5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/aa049c2602824ba091b1b58153a310e5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CORR_SPEARMAN Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "0579a6540e89468998e0ecfaff69acb0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0579a6540e89468998e0ecfaff69acb0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "COS Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dd798b7519101492ec8026cecb3aea.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dd798b7519101492ec8026cecb3aea.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "COSH Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dd990b751910148cefe6fae4ca1c3d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dd990b751910148cefe6fae4ca1c3d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "COSINE_SIMILARITY Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "063e1366a7d54735b98b2513ea4a88c9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/063e1366a7d54735b98b2513ea4a88c9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "COT Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ddc091751910148f72db8d34f39adf.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ddc091751910148f72db8d34f39adf.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "COUNT Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "28c3b573c4354f75a1931202e2271d7c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/28c3b573c4354f75a1931202e2271d7c.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "CROSS_CORR Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "b2197a4784044933ae7c9ed240939dff.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b2197a4784044933ae7c9ed240939dff.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CUBIC_SPLINE_APPROX Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "4300f0ccdf024a11a40a82615832e430.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4300f0ccdf024a11a40a82615832e430.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CUME_DIST Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f4351278aade4ac3be7618181acd2ea4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f4351278aade4ac3be7618181acd2ea4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_CONNECTION Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dde16475191014bf3090e6b2e9857f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dde16475191014bf3090e6b2e9857f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_DATABASE Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "7ddcb499036a483ab18ecb19816e6708.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7ddcb499036a483ab18ecb19816e6708.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_DATE Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ddfe5d75191014af50837e2818462d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ddfe5d75191014af50837e2818462d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_IDENTITY_VALUE Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "01e1a30aa542448da56da76233fea779.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/01e1a30aa542448da56da76233fea779.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_MVCC_SNAPSHOT_TIMESTAMP Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f15c8a4db42b46849c62c4f70d47abd2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f15c8a4db42b46849c62c4f70d47abd2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_OBJECT_SCHEMA Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "8feedda0f93b4b5aa66af0714d62c83a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8feedda0f93b4b5aa66af0714d62c83a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_ROLEGROUP Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "5132e3b06f8a45e9917269e1366e1602.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5132e3b06f8a45e9917269e1366e1602.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_SCHEMA Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20de1a3775191014b155e3a757a193d2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de1a3775191014b155e3a757a193d2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_SITE_ID Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "9ac7d1b81eb642f98a97c9682097e44f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9ac7d1b81eb642f98a97c9682097e44f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_TIME Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20de382f7519101482ca9a2865a86014.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de382f7519101482ca9a2865a86014.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_TIMESTAMP Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20de551c751910149bcfc30eaf359b03.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de551c751910149bcfc30eaf359b03.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_TRANSACTION_ISOLATION_LEVEL Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22ded87d2951014bce8cab9a11d55a2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22ded87d2951014bce8cab9a11d55a2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_UPDATE_STATEMENT_SEQUENCE Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "9ae97edbfee241138fcc1c45c079b3e2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9ae97edbfee241138fcc1c45c079b3e2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_UPDATE_TRANSACTION Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "e04d1f42467544a38ac2125f046793ae.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e04d1f42467544a38ac2125f046793ae.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_USER Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20de8b3775191014acc4e9ee60df1746.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de8b3775191014acc4e9ee60df1746.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_USER_ID Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "75262ff0734c40cdb9fe2f2d15b6e750.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/75262ff0734c40cdb9fe2f2d15b6e750.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_USERGROUP Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "95fb067f7c5f43f9aaab61a809547d0b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/95fb067f7c5f43f9aaab61a809547d0b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_UTCDATE Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dea8e57519101499438ff2eb028eff.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dea8e57519101499438ff2eb028eff.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_UTCTIME Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20dec53a751910149b5e8425a022f9cd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dec53a751910149b5e8425a022f9cd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "CURRENT_UTCTIMESTAMP Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e0f06c751910148d388dacfe4b0b58.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e0f06c751910148d388dacfe4b0b58.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "DAYNAME Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e115c375191014a259acd3d72e3722.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e115c375191014a259acd3d72e3722.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "DAYOFMONTH Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e133a875191014a958bb2c7dd5d960.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e133a875191014a958bb2c7dd5d960.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "DAYOFYEAR Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e1505475191014ade2f3f22fc139e9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1505475191014ade2f3f22fc139e9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "DAYS_BETWEEN Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e16ca5751910148da4fc7ec69bae03.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e16ca5751910148da4fc7ec69bae03.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "DENSE_RANK Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "1a116cbd04a942e498ffef3a37b47461.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1a116cbd04a942e498ffef3a37b47461.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "DFT Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "fcf204141f89497bb07f8efbb1bb92da.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fcf204141f89497bb07f8efbb1bb92da.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ESCAPE_DOUBLE_QUOTES Function (Security)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "46c5fecd565c4623b03ad316e27aa22a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/46c5fecd565c4623b03ad316e27aa22a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ESCAPE_SINGLE_QUOTES Function (Security)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "885b059cc20340979c8927c9301ceb63.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/885b059cc20340979c8927c9301ceb63.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "EXP Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e1894075191014b86fe8a17ff0301d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1894075191014b86fe8a17ff0301d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "EXPRESSION_MACRO Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "a8d114522b3a445bb877039fa208f9ba.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a8d114522b3a445bb877039fa208f9ba.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "EXTRACT Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e1a58475191014a343f6fe96c9846c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1a58475191014a343f6fe96c9846c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "FIRST_VALUE Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "034b17549b5d4b7d913e2c2770eea45b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/034b17549b5d4b7d913e2c2770eea45b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "FLOOR Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e1c2b47519101484d8af631b6845f9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1c2b47519101484d8af631b6845f9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "GENERATE_PASSWORD Function (Security)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "5157398354a14cf49110fac593f83997.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5157398354a14cf49110fac593f83997.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "GET_DELTA_LAKE_TABLE_CHANGES Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "7f38a110382e4635a87a8091e7d7f2af.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7f38a110382e4635a87a8091e7d7f2af.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "GET_DELTA_LAKE_TABLE_VERSION Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "e12e6b52d1c94300a40065f3111fe551.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e12e6b52d1c94300a40065f3111fe551.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "GREATEST Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e20038751910148ed9fadf866413e0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e20038751910148ed9fadf866413e0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "GROUP_SCORE Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "89bc59e4df254c29b66f8feed2b785dc.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/89bc59e4df254c29b66f8feed2b785dc.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "GROUPING Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22eb360d2951014b6f0b9f1e84edce9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22eb360d2951014b6f0b9f1e84edce9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "GROUPING_ID Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e21cfd75191014a5cbbea031962073.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e21cfd75191014a5cbbea031962073.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "HAMMING_DISTANCE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d0878e31868b4f0392c71a299125148d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d0878e31868b4f0392c71a299125148d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "HASH_MD5 Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "881159b167a246e88926075e0c59ea36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/881159b167a246e88926075e0c59ea36.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "HASH_SHA256 Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d22ecca9d2951014850492e8c88d498c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22ecca9d2951014850492e8c88d498c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "HEXTOBIN Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e2390b75191014be86bf1562fcaf1b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e2390b75191014be86bf1562fcaf1b.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "HEXTONUM Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "0fe4116d8e7347d6a22923c6d7b8c6e2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0fe4116d8e7347d6a22923c6d7b8c6e2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "HOUR Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e23eda75191014a64ce3271722de36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23eda75191014a64ce3271722de36.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "IFNULL Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e23edb75191014b906e3271722de36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23edb75191014b906e3271722de36.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "INITCAP Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d1e67902534d426180459ae45a264667.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d1e67902534d426180459ae45a264667.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "IS_SQL_INJECTION_SAFE Function (Security)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "4496cc5717e847feb7daa41516047df9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4496cc5717e847feb7daa41516047df9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ISOWEEK Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e23edc7519101482eae3271722de36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23edc7519101482eae3271722de36.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "JSON_QUERY Function (JSON)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "3126ea33d50d42d19517a08fe22ec5a1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3126ea33d50d42d19517a08fe22ec5a1.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "JSON_TABLE Function (JSON)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f8f6916b5c434a6fbd1bb7e0dc65acd4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f8f6916b5c434a6fbd1bb7e0dc65acd4.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "JSON_VALUE Function (JSON)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "9355cb9e45a149c1a6ddb2bd2392d864.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9355cb9e45a149c1a6ddb2bd2392d864.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "L2DISTANCE Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "0d48be92cebd4fec8944d208fbf923fc.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0d48be92cebd4fec8944d208fbf923fc.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "L2NORM Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "1225d640200147279b45db92457b5612.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1225d640200147279b45db92457b5612.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "L2NORMALIZE Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f068dc71d41d492bbbd893105b9edced.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f068dc71d41d492bbbd893105b9edced.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LAG Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "e7ef7cc478f14a408e1af27fc1a78624.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e7ef7cc478f14a408e1af27fc1a78624.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LAST_DAY Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e23ede75191014a1c2e3271722de36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23ede75191014a1c2e3271722de36.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LAST_VALUE Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "32e95b7fac5c4b489d938c11ce5b4695.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/32e95b7fac5c4b489d938c11ce5b4695.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LCASE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e23edf7519101490eee3271722de36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23edf7519101490eee3271722de36.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "LEAD Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "5932eebb6208406590071eb65c6caa83.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5932eebb6208406590071eb65c6caa83.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LEAST Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e2fddb75191014a794e3271722de36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e2fddb75191014a794e3271722de36.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LEFT Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e3428a75191014a9949b4f90076dee.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3428a75191014a9949b4f90076dee.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LENGTH Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e35f5275191014ba6df6dc5f8bad5b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e35f5275191014ba6df6dc5f8bad5b.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "LINEAR_APPROX Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "b06f3e60d29e4968ab2da3cca7333db0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b06f3e60d29e4968ab2da3cca7333db0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LN Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e37b49751910148948cbf4dbb66310.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e37b49751910148948cbf4dbb66310.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LOCALTOUTC Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e39ac67519101486b49c65d9aa5174.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e39ac67519101486b49c65d9aa5174.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs" + ], + "builtin_recognized": true + }, + { + "title": "LOCATE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e3b6b77519101485e6bd62f7018f75.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3b6b77519101485e6bd62f7018f75.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "LOCATE_REGEXPR Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "cb4866494bd647cd8926763aa940f613.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/cb4866494bd647cd8926763aa940f613.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "LOG Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e3d2fe7519101481a1fc67a4370740.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3d2fe7519101481a1fc67a4370740.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LOWER Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e3eff7751910148366dfb349020b4c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3eff7751910148366dfb349020b4c.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "LPAD Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e40bdb75191014bc66f14fa7a3d769.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e40bdb75191014bc66f14fa7a3d769.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "LTRIM Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e43dd175191014bee9ed5ab9ae44f7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e43dd175191014bee9ed5ab9ae44f7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MAP Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e4654f75191014b58bdd5ea7423a15.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e4654f75191014b58bdd5ea7423a15.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MAX Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "69290904995f47d3a06f70f561c4efca.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/69290904995f47d3a06f70f561c4efca.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "MEDIAN Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "0531b496ea0c463d8c9ddfc15cbdbf04.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0531b496ea0c463d8c9ddfc15cbdbf04.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MEMBER_AT Function (Array)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f17a873883164d958449a94af689895e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f17a873883164d958449a94af689895e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MEMBER_AT Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "559502d670d84bd498780c254354b0ac.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/559502d670d84bd498780c254354b0ac.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MIN Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "4409b0c5441f401486f1c4d4328d4905.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4409b0c5441f401486f1c4d4328d4905.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "MINUTE Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e4ff2275191014825297d563cd0b85.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e4ff2275191014825297d563cd0b85.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MOD Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e51e5c751910149879aa97a95d564b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e51e5c751910149879aa97a95d564b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MONTH Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e544ea75191014b8209a9fc217ce0e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e544ea75191014b8209a9fc217ce0e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MONTHNAME Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e562537519101499c6a760e719afbd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e562537519101499c6a760e719afbd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "MONTHS_BETWEEN Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "9f9eb73468b04bbc9d6014d22d2bfb90.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9f9eb73468b04bbc9d6014d22d2bfb90.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "NANO100_BETWEEN Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e57ed975191014be39aeb6e5fd3d89.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e57ed975191014be39aeb6e5fd3d89.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NCHAR Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e59b1d751910149321c5c68efb5905.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e59b1d751910149321c5c68efb5905.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NDIV0 Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "bcbb7ba0f4f2495ca954132382226929.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bcbb7ba0f4f2495ca954132382226929.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NEXT_DAY Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e5a75e75191014b2539bd2c7772cf2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e5a75e75191014b2539bd2c7772cf2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NEWUID Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "fe7b7fede9aa4287ae69ffe3986e9c25.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fe7b7fede9aa4287ae69ffe3986e9c25.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NORMALIZE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "8fa2d19e3dae4de2a4613a4987858894.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8fa2d19e3dae4de2a4613a4987858894.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NOW Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e5db42751910148cebadec507448b5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e5db42751910148cebadec507448b5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NTH_VALUE Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "6522df94eee542d5b1700a7766e6e6a2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6522df94eee542d5b1700a7766e6e6a2.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "NTILE Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "886723669fb34ff8b5c51eabc003cbd2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/886723669fb34ff8b5c51eabc003cbd2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NULLIF Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e5f7fe751910149ecdc8ee8a8a5c85.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e5f7fe751910149ecdc8ee8a8a5c85.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "NUMTOHEX Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "3688c8288c024907b4d933cd7c9a72c9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3688c8288c024907b4d933cd7c9a72c9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "OCCURRENCES_REGEXPR Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "4114b026f750429c8eeef9f54258edfa.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4114b026f750429c8eeef9f54258edfa.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "PARSE_CERTIFICATES Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "fec4e28a12a946ce86fe789318e85b01.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fec4e28a12a946ce86fe789318e85b01.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "PARSE_JSON Function (JSON)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "58d203e84ed2431d9465d504c69b20ef.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/58d203e84ed2431d9465d504c69b20ef.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "PARTITION_ALLOCATION Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "028be0c864734d2b9e10402a4c7065f2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/028be0c864734d2b9e10402a4c7065f2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "PARTITION_HASH Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "e1e79a1230234c6699f8054d0e42d413.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e1e79a1230234c6699f8054d0e42d413.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "PERCENT_RANK Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "90f4533f07d34269a47924c963f1d5ec.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/90f4533f07d34269a47924c963f1d5ec.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "PERCENTILE_CONT Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "3028c19181b14bdf80fcc5333c5dc7b1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3028c19181b14bdf80fcc5333c5dc7b1.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "PERCENTILE_DISC Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d8394326f65e4fd9aa5a9750755b4665.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d8394326f65e4fd9aa5a9750755b4665.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "POWER Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e6141e75191014a599dce99d5f9ba9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6141e75191014a599dce99d5f9ba9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "QUARTER Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e62fe875191014b78bd015a16966fb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e62fe875191014b78bd015a16966fb.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RAND Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e64d8675191014bba389d65920392d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e64d8675191014bba389d65920392d.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "RANDOM_PARTITION Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "abf3dd7576464c30a7897a05d1ef8cb2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/abf3dd7576464c30a7897a05d1ef8cb2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RAND_SECURE Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d18abab24ad9470d98a760b61955d073.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d18abab24ad9470d98a760b61955d073.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RANK Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "10bb583b586e47a09790eb8f8eeeab62.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/10bb583b586e47a09790eb8f8eeeab62.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RECORD_COMMIT_TIMESTAMP Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "a85896b8b0de48089f76b73ae7388740.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a85896b8b0de48089f76b73ae7388740.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RECORD_ID Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "fba3ff40198c4504b3693ad376e2bfbf.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fba3ff40198c4504b3693ad376e2bfbf.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "REPLACE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e66a2c75191014bac6a279955db665.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e66a2c75191014bac6a279955db665.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "REPLACE_REGEXPR Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "dcf1045ce51d45119cfe8ba17cf9da4f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dcf1045ce51d45119cfe8ba17cf9da4f.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "RESULT_CACHE_ID Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "9e9da58b772a4df4811e3d0845679d5d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9e9da58b772a4df4811e3d0845679d5d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RESULT_CACHE_REFRESH_TIME Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "be8d87e527aa499fbcbcd75357af73bf.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/be8d87e527aa499fbcbcd75357af73bf.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RIGHT Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e6862e75191014af8d997e620c1ee8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6862e75191014af8d997e620c1ee8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ROUND Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e6a27575191014bd54a07fd86c585d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6a27575191014bd54a07fd86c585d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RPAD Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e6be627519101487989fa5c2fceccd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6be627519101487989fa5c2fceccd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "RTRIM Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e6da0175191014a632fe729f839d44.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6da0175191014a632fe729f839d44.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "ROW_NUMBER Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "87f0d4985c4a49bfb64682dcb325173d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/87f0d4985c4a49bfb64682dcb325173d.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "SCORE Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e6f8e97519101489a0cd3c29991e72.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6f8e97519101489a0cd3c29991e72.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SECOND Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e7152675191014bb54fed5d26b9e6f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7152675191014bb54fed5d26b9e6f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SECONDS_BETWEEN Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e73218751910148528de57be340475.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e73218751910148528de57be340475.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "SERIES_DISAGGREGATE Function (Series Data)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "7c34535972b94f74b1a9c1760f9e4a8e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7c34535972b94f74b1a9c1760f9e4a8e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SERIES_ELEMENT_TO_PERIOD Function (Series Data)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "c266e91b94484674b7da636f3f477158.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c266e91b94484674b7da636f3f477158.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SERIES_FILTER Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "c097a58f3a7c4a3a8d851371bcc8e5ba.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c097a58f3a7c4a3a8d851371bcc8e5ba.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SERIES_GENERATE Function (Series Data)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "c8101037ad4344768db31e68e4d30eb4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c8101037ad4344768db31e68e4d30eb4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SERIES_PERIOD_TO_ELEMENT Function (Series Data)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "eb21d794c95341a9816bb528f134d491.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/eb21d794c95341a9816bb528f134d491.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SERIES_ROUND Function (Series Data)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "435ec476ab494ad6b8409f22abec13fe.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/435ec476ab494ad6b8409f22abec13fe.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SESSION_CONTEXT Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e74dc875191014b20c81d140d67e42.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e74dc875191014b20c81d140d67e42.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SESSION_USER Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e76c1a7519101496b1f32f0d1128d9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e76c1a7519101496b1f32f0d1128d9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SIGN Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e788537519101487829d6ad0ba5244.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e788537519101487829d6ad0ba5244.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SIN Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e7a62475191014b6c499e5f954d817.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7a62475191014b6c499e5f954d817.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SINH Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e7c25e751910148a11981903397e9c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7c25e751910148a11981903397e9c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SOUNDEX Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "3ca8ac5cb49d401993b5dfcca925c22f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3ca8ac5cb49d401993b5dfcca925c22f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SQRT Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e7de8875191014ba5dc4f74fa82376.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7de8875191014ba5dc4f74fa82376.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "STATEMENT_EXECUTION_HOST Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d42113dcde234542919d610a739ffcc1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d42113dcde234542919d610a739ffcc1.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "STATEMENT_EXECUTION_PORT Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "4b410ddd8e8041eb89772717d20a29e0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4b410ddd8e8041eb89772717d20a29e0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "STDDEV Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "c0c42b56360144e99bd443db90847597.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c0c42b56360144e99bd443db90847597.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "STDDEV_POP Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "67d48b64f0d048bfb028767cb377fbb2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/67d48b64f0d048bfb028767cb377fbb2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "STDDEV_SAMP Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "303513466051489dbe926bd482bfc5d9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/303513466051489dbe926bd482bfc5d9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "STRING_AGG Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "a924ee1e98ab435a874efa32e6f0ae14.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a924ee1e98ab435a874efa32e6f0ae14.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "STRTOBIN Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d230efaad295101481708a3a9aea9254.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d230efaad295101481708a3a9aea9254.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SUBARRAY Function (Array)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "49d7752679f643539eaddcf4a2d7cb8e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/49d7752679f643539eaddcf4a2d7cb8e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SUBSTR_AFTER Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e7fb71751910148292a53e1b4a9bba.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7fb71751910148292a53e1b4a9bba.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SUBSTR_BEFORE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e8174b751910149796bd4aad28bdca.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8174b751910149796bd4aad28bdca.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SUBSTRING Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e8341275191014a4cfdcd3c830fc98.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8341275191014a4cfdcd3c830fc98.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "SUBSTRING_REGEXPR Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "a2f80e8ac8904c13959c69bfc3058f19.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a2f80e8ac8904c13959c69bfc3058f19.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SUBVECTOR Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "5f2979b935ff4831875a8ef0f8cb10be.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5f2979b935ff4831875a8ef0f8cb10be.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "SUM Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "03958a1eb0ad4950b00dedd8fdda475a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/03958a1eb0ad4950b00dedd8fdda475a.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "SYSUUID Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e8cdfc7519101498c5ab902aee5306.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8cdfc7519101498c5ab902aee5306.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TAN Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e8ee6e75191014a8b3b47e4f8c296d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8ee6e75191014a8b3b47e4f8c296d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TANH Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20e90bf975191014b967c5d414e8b167.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e90bf975191014b967c5d414e8b167.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_ARRAY Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "877008aee4ad4467a1d5ae38f325671d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/877008aee4ad4467a1d5ae38f325671d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_BIGINT Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20eae5e1751910148391d3079da8527e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20eae5e1751910148391d3079da8527e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_BINARY Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20eb65d4751910149a7dc10f93a24a75.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20eb65d4751910149a7dc10f93a24a75.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_BLOB Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20eba7c375191014b9bfbf21581ee86a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20eba7c375191014b9bfbf21581ee86a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_BOOLEAN Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "258b5350ad43487397d47f2ab309952d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/258b5350ad43487397d47f2ab309952d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_CLOB Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ebe72e75191014b314da7e6f95e73b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ebe72e75191014b314da7e6f95e73b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_DATE Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ec6b6975191014b835eb436e4827df.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ec6b6975191014b835eb436e4827df.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "TO_DATS Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ecb35c75191014b225b00e53f9c1b8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ecb35c75191014b225b00e53f9c1b8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_DECIMAL Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ee237775191014924e81b18c73c831.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ee237775191014924e81b18c73c831.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "TO_DOUBLE Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ee824a751910148a149311d1aa0f32.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ee824a751910148a149311d1aa0f32.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_HALF_VECTOR Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f4f80d5254a94db79ce01cddc724c105.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f4f80d5254a94db79ce01cddc724c105.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_INT Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ef08b775191014b8f4f7fad1c7f0f1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ef08b775191014b8f4f7fad1c7f0f1.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_INTEGER Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ef488375191014888a939fbf0acd6b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ef488375191014888a939fbf0acd6b.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "TO_JSON_BOOLEAN (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "8791a379ef08455c9bc95f88d4b18630.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8791a379ef08455c9bc95f88d4b18630.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "TO_NCLOB Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20ef8d6f751910148aa787ac113859f0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ef8d6f751910148aa787ac113859f0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_NVARCHAR Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20efce3f751910149e20b0068fd68287.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20efce3f751910149e20b0068fd68287.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_REAL Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f017bc7519101490f792fb956eb045.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f017bc7519101490f792fb956eb045.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_REAL_VECTOR Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "2c10279264a04affbb018753641b01cf.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2c10279264a04affbb018753641b01cf.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_SECONDDATE Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f057b075191014809a8f010c03d7c2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f057b075191014809a8f010c03d7c2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_SMALLDECIMAL Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f0d4aa75191014a96ef18b874d6f2d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f0d4aa75191014a96ef18b874d6f2d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_SMALLINT Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f11dbf75191014972cc8c3d639d432.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f11dbf75191014972cc8c3d639d432.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_TIME Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f1662775191014a6f7cead37a5937a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f1662775191014a6f7cead37a5937a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_TIMESTAMP Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f1a5b075191014b773acf0dc277cae.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f1a5b075191014b773acf0dc277cae.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "TO_TINYINT Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f1e6a175191014a59583315d023b7f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f1e6a175191014a59583315d023b7f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_VARBINARY Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "048f39f4577d4f929b5eda86797ba8d7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/048f39f4577d4f929b5eda86797ba8d7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "TO_VARCHAR Function (Data Type Conversion)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f226a1751910149edd8969c469d54d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f226a1751910149edd8969c469d54d.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ], + "builtin_recognized": true + }, + { + "title": "TRIM Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f266137519101480abfc0aeb6c9dc3.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f266137519101480abfc0aeb6c9dc3.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "TRIM_ARRAY Function (Array)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "565f8f65e5324117b5435682150f45f3.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/565f8f65e5324117b5435682150f45f3.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "UCASE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f4073275191014a8418376b0a184eb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4073275191014a8418376b0a184eb.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "UMINUS Function (Numeric)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f4667a75191014a8acfc814316001f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4667a75191014a8acfc814316001f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "UNICODE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f4a5fb75191014a75be5e25682ea6f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4a5fb75191014a75be5e25682ea6f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "UPPER Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f4ef8775191014bb2d94bbf2fe50d7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4ef8775191014bb2d94bbf2fe50d7.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "UTCTOLOCAL Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f52f4475191014a1089242486060c1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f52f4475191014a1089242486060c1.html?version=2026_2_QRC", + "status": "regression_tested_forms", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs" + ], + "builtin_recognized": true + }, + { + "title": "VALIDATE_USERGROUP_CONNECT_RESTRICTION_DETAILS Function (Security)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "508e1735f86a4c97a9072627e1e265de.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/508e1735f86a4c97a9072627e1e265de.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "VALIDATE_USERGROUP_CONNECT_RESTRICTION Function (Security)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "c7a96e0bcc51447fa2af31413dbaff41.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c7a96e0bcc51447fa2af31413dbaff41.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "VAR Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "21a8eb1267d549c6a3eb0e15f82943e6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/21a8eb1267d549c6a3eb0e15f82943e6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "VAR_POP Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "4faac7bced8140b0a703eb32b420edf8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4faac7bced8140b0a703eb32b420edf8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "VAR_SAMP Function (Aggregate)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d1e36dfe43854bf5853fb7cca64b771b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d1e36dfe43854bf5853fb7cca64b771b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "VECTOR_EMBEDDING Function (Vector)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "87bbd2c23b8342a0b70c6022664465a9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/87bbd2c23b8342a0b70c6022664465a9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "WEEK Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f5758b7519101498b28e41757fe664.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f5758b7519101498b28e41757fe664.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "WEEKDAY Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f5bb79751910148e7198206fbd199f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f5bb79751910148e7198206fbd199f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "WEIGHTED_AVG Function (Window)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d97252bcd22f4d9fa4812715cee5139b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d97252bcd22f4d9fa4812715cee5139b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "WIDTH_BUCKET Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "953bce3cc9a84ebfa77c17ab687ff0ee.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/953bce3cc9a84ebfa77c17ab687ff0ee.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "WORKDAYS_BETWEEN Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "d232c253d295101486a3dee449981b3f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d232c253d295101486a3dee449981b3f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "XMLEXTRACT Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "f1045c62108c449a835adba32c279090.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f1045c62108c449a835adba32c279090.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "XMLEXTRACTVALUE Function (Miscellaneous)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "85ee0084ac014a63aa2680b384466f39.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/85ee0084ac014a63aa2680b384466f39.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "XMLTABLE Function (String)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "2bb8ab119e384b5f94635696bb9f68b5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2bb8ab119e384b5f94635696bb9f68b5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "YEAR Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "20f5fac6751910148dabd3c6821f907d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f5fac6751910148dabd3c6821f907d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [], + "builtin_recognized": true + }, + { + "title": "YEARS_BETWEEN Function (Datetime)", + "path": [ + "SQL Reference", + "SQL Functions", + "Alphabetical List Of Functions" + ], + "file": "7c0d2c161ea34def86de3f5eadd6a0af.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7c0d2c161ea34def86de3f5eadd6a0af.html?version=2026_2_QRC", + "status": "native_fixture_forms", + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ], + "builtin_recognized": true + }, + { + "title": "Aggregate Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "6fff7f0ae9184d1db47a25791545a1b6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6fff7f0ae9184d1db47a25791545a1b6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "AI Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "062a3e4c83d14418850aa0267db7c6dd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/062a3e4c83d14418850aa0267db7c6dd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Array Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "e32b3b4076244f63825091adeaba6299.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e32b3b4076244f63825091adeaba6299.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Data Type Conversion Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "209ddefe75191014ac249bf78ba2a1e9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209ddefe75191014ac249bf78ba2a1e9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Datetime Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "209f228975191014baed94f1b69693ae.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209f228975191014baed94f1b69693ae.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Hierarchy Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "2969da89b87f4abd85fd0b5f9f5bc395.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2969da89b87f4abd85fd0b5f9f5bc395.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "JSON Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "5848028bcd364d9aa0706ae1d7ab4184.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5848028bcd364d9aa0706ae1d7ab4184.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Miscellaneous Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "20a465cd75191014abacf163b404e930.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a465cd75191014abacf163b404e930.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Numeric Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "20a190b975191014b769eafa93453d3a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a190b975191014b769eafa93453d3a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Security Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "287e6e06fd69494488d71863c3e49285.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/287e6e06fd69494488d71863c3e49285.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Series Data Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "2dea02fb9feb451080a8c2ee573a88f9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2dea02fb9feb451080a8c2ee573a88f9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "String Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "20a24d4b75191014afc5ac3b997d3ce2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a24d4b75191014afc5ac3b997d3ce2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Vector Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "0d67bb2b7fd246b48ca4a6cf0bb9d77a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0d67bb2b7fd246b48ca4a6cf0bb9d77a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Windows Functions", + "path": [ + "SQL Reference", + "SQL Functions", + "Window Functions and the Window Specification" + ], + "file": "4958a2b74950493b900fb14ba9efdf24.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4958a2b74950493b900fb14ba9efdf24.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Window Aggregate Functions", + "path": [ + "SQL Reference", + "SQL Functions", + "Window Functions and the Window Specification" + ], + "file": "ee3c26a9f6354191800e6d0ba8485200.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ee3c26a9f6354191800e6d0ba8485200.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER AUDIT POLICY Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20cfb7b875191014866c930164aaf07c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20cfb7b875191014866c930164aaf07c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER CREDENTIAL Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20cfdad57519101482fcb19af478ec34.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20cfdad57519101482fcb19af478ec34.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER FUNCTION Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "1102d570f16a4925a706f20285870350.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1102d570f16a4925a706f20285870350.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d014b575191014b66d8ef88f6a55f6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d014b575191014b66d8ef88f6a55f6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER JWT PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "61863f687c3d40c5a7c76a4ab110ede5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/61863f687c3d40c5a7c76a4ab110ede5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER LDAP PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "ae9ba28ddefc4b29809d5b926d6ee02d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ae9ba28ddefc4b29809d5b926d6ee02d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER LIBRARY Statement (SQLScript)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "d0b979ccbbd14377983f254e85241ff4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d0b979ccbbd14377983f254e85241ff4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER PROCEDURE Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d0328875191014964a9059637c7f5f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0328875191014964a9059637c7f5f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER PSE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "9c22c6f22df64bc6881d1ed61be18b8d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9c22c6f22df64bc6881d1ed61be18b8d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER REMOTE SOURCE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "f423eb496f5b1014a1a7bb3e49bcc07b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f423eb496f5b1014a1a7bb3e49bcc07b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER REMOTE SUBSCRIPTION Statement", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "b366013688df494980a9c81f7c81f503.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b366013688df494980a9c81f7c81f503.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER ROLE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "c16ff341be00433f862b2c064431ec0c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c16ff341be00433f862b2c064431ec0c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER ROLEGROUP Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "bb0d9c0c86f6421cb3c37e48dc513d38.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bb0d9c0c86f6421cb3c37e48dc513d38.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SAML PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d04f7b751910148a98f145797d3482.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d04f7b751910148a98f145797d3482.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SCHEDULER JOB Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "701e46758a044d868365b54bac173405.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/701e46758a044d868365b54bac173405.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SEQUENCE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d06b0575191014afb2dfcb7aed7fff.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d06b0575191014afb2dfcb7aed7fff.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER STATISTICS Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "c6564762f4b846e5a76fcfb3fd7a1a88.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c6564762f4b846e5a76fcfb3fd7a1a88.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER STRUCTURED COLUMN MASK Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "58ea2c4950454b6eb9c2b29bc44e2b8f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/58ea2c4950454b6eb9c2b29bc44e2b8f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER STRUCTURED FILTER Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "07b14e01c65a4e7b89b779defb12c97c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/07b14e01c65a4e7b89b779defb12c97c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER STRUCTURED PRIVILEGE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "fd4016543766478ea6304c3909b4245c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fd4016543766478ea6304c3909b4245c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {ADD | ALTER | REMOVE} STATEMENT HINT Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "1ec23ef0839b45b7991a785eff19fd2c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1ec23ef0839b45b7991a785eff19fd2c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {ADD | REMOVE} ABSTRACT SQL PLAN FILTER (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "9c6ac161c9d8492f9d55c9cff38fb17f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9c6ac161c9d8492f9d55c9cff38fb17f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM ALTER AUDIT LOG (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "f135e4a7883746f4b4b7c06b8605a589.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f135e4a7883746f4b4b7c06b8605a589.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM ALTER CONFIGURATION Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d08a5b751910148145dbc016c826a4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d08a5b751910148145dbc016c826a4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM ALTER SESSION SET Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d0b09375191014b517e1ec387f9c26.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0b09375191014b517e1ec387f9c26.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM ALTER SESSION UNSET Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d0ce04751910149e6bf5840bb2042a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0ce04751910149e6bf5840bb2042a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM ALTER TABLE PLACEMENT Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "0715b97c91cd4c87982040cdd341d676.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0715b97c91cd4c87982040cdd341d676.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM APPLICATION ENCRYPTION Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "f42595956f5b1014bc6cb241d3d75fc2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f42595956f5b1014bc6cb241d3d75fc2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CANCEL [WORK IN] SESSION Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d0eb287519101498c4ecb8114cab17.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0eb287519101498c4ecb8114cab17.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR AUDIT LOG Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "d2231bd2d2951014ad35d218ea6628c8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d2231bd2d2951014ad35d218ea6628c8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR CACHE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "141ad67a9cbe4c6c951b542aff239df4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/141ad67a9cbe4c6c951b542aff239df4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR COLUMN JOIN DATA STATISTICS (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "9ac0859babf549c1a05bdfd8c9c68f11.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9ac0859babf549c1a05bdfd8c9c68f11.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR CONSISTENCY CHECK HISTORY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "89ea41b59b354983bdea16daf75ac6b9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/89ea41b59b354983bdea16daf75ac6b9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR INIFILE CONTENT HISTORY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "fb097f2620c645d18064ce6b93c24a1e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fb097f2620c645d18064ce6b93c24a1e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR RESULT CACHE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "97dca93d321540faa947abe647ebdf6b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/97dca93d321540faa947abe647ebdf6b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR SQL PLAN CACHE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d107c875191014b8aecbb218720fd9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d107c875191014b8aecbb218720fd9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR TIMEZONE CACHE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "a7804953f5cb458a84f47d3045436107.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a7804953f5cb458a84f47d3045436107.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CLEAR TRACES Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d12816751910149640d1e144741069.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d12816751910149640d1e144741069.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CREATE RUNTIMEDUMP Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "6954969bba544da190ca53c1bf367086.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6954969bba544da190ca53c1bf367086.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM CREATE WAITGRAPH Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "078511c1125a4235bbd09e3ea6ff04a8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/078511c1125a4235bbd09e3ea6ff04a8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM DISCONNECT SESSION Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d1524e751910148706e0aab4063a0f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d1524e751910148706e0aab4063a0f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {ENABLE | DISABLE} ALL [ASYNCHRONOUS | SYNCHRONOUS] TABLE REPLICAS Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "f9486656d74b4b059f53c28f7d5f8be9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f9486656d74b4b059f53c28f7d5f8be9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {ENABLE | DISABLE | REMOVE} ABSTRACT SQL PLAN (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "031158f3b53342b095ab4d49ffd95a3e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/031158f3b53342b095ab4d49ffd95a3e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {ENABLE | DISABLE} STATEMENT HINT Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "8505e6f5023c4092901735116d03fdce.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8505e6f5023c4092901735116d03fdce.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM LOAD PERFTRACE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d170777519101493f4be280b8d0b45.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d170777519101493f4be280b8d0b45.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {PIN | UNPIN} SQL PLAN CACHE ENTRY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "68e2f7a8e06f41cb871276858202c605.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/68e2f7a8e06f41cb871276858202c605.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM RECLAIM DATAVOLUME Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d1e5e57519101486c7812a5a8990e8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d1e5e57519101486c7812a5a8990e8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM RECLAIM LOB SPACE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "a0b723599451418d91a5f264387a3250.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a0b723599451418d91a5f264387a3250.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM RECOMPILE SQL PLAN CACHE ENTRY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "d2264261d2951014ae11f585d3cca109.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d2264261d2951014ae11f585d3cca109.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM RECONFIGURE SERVICE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d23ead751910148f18dcd2a0862e90.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d23ead751910148f18dcd2a0862e90.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM REFRESH RESULT CACHE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "9d274fa7e20d4841a6017e020d871aa0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9d274fa7e20d4841a6017e020d871aa0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM REFRESH RESULT CACHE ENTRY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "1ab0dbbae3734a48b7a286f3df467b6b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1ab0dbbae3734a48b7a286f3df467b6b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM REMOVE CACHE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "e4a2ad5facb04ae2b76b6c885f7913ff.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e4a2ad5facb04ae2b76b6c885f7913ff.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM REMOVE RESULT CACHE ENTRY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "2124566f72194618be0d40036c1dea52.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2124566f72194618be0d40036c1dea52.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM REMOVE SQL PLAN CACHE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "dafece708a524a7b9cabc13fe95406c1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dafece708a524a7b9cabc13fe95406c1.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM REMOVE TRACES Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d25bff75191014965ad9dcc606d225.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d25bff75191014965ad9dcc606d225.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM RESET MONITORING VIEW Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d27aa375191014a9cd8ea8c334741a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d27aa375191014a9cd8ea8c334741a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM SAVE PERFTRACE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d2973275191014bafef616be15326a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d2973275191014bafef616be15326a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM SAVEPOINT Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d2b6e4751910148f429f70714d1910.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d2b6e4751910148f429f70714d1910.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {START | STOP} APPLY ABSTRACT SQL PLAN (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "935ecd1974af406a91bc1cb60a0e5ef5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/935ecd1974af406a91bc1cb60a0e5ef5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {START | STOP} CAPTURE ABSTRACT SQL PLAN (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "dc462710a89d4ebc981eda6908db28dc.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dc462710a89d4ebc981eda6908db28dc.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {START | STOP | CLEAR} SQLSCRIPT PLAN PROFILER Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "f518753a450942a48fecc02c926e3847.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f518753a450942a48fecc02c926e3847.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {START | STOP | SAVE | CLEAR} KERNEL PROFILER Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "864e9b9851bb467e9c0c4c1f285bef12.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/864e9b9851bb467e9c0c4c1f285bef12.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {START | STOP} PERFTRACE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d2d3ed75191014bb9c86ed27c378d8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d2d3ed75191014bb9c86ed27c378d8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM {START | STOP} SQLSCRIPT CODE COVERAGE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "1a40f07c15c3401083fc8fd8b9786f7b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1a40f07c15c3401083fc8fd8b9786f7b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM STOP SERVICE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" + ], + "file": "20d30dab75191014bf7de6f8ea2b3ed6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d30dab75191014bf7de6f8ea2b3ed6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER TABLE GROUP Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "28543a11bacf412a9062f5fe54bc4f5c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/28543a11bacf412a9062f5fe54bc4f5c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Non-Heterogeneous Alter Partition Clauses", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER TABLE Statement (Data Definition)" + ], + "file": "f7ae27ca1b954471a4e1a7feab2c24d7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f7ae27ca1b954471a4e1a7feab2c24d7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Heterogeneous Alter Partition Clauses", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "ALTER TABLE Statement (Data Definition)" + ], + "file": "a4258b865710423b8712b06fb5b8e7c5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a4258b865710423b8712b06fb5b8e7c5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER TOKEN EXCHANGER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "47dbef7cc96e4cccaadcf4e027b245b3.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/47dbef7cc96e4cccaadcf4e027b245b3.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER USER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d3459f75191014a7bbeb670bad8850.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3459f75191014a7bbeb670bad8850.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER USERGROUP Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "aa94ca874c01458da5a275aac8883c23.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/aa94ca874c01458da5a275aac8883c23.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER VECTOR INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "5274113d391e40cdb31e255a1e9b3063.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5274113d391e40cdb31e255a1e9b3063.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER VIEW Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "3bc89515b93d4844bd700b3492673270.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3bc89515b93d4844bd700b3492673270.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER VIRTUAL TABLE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "51826981a2d24e7aa872f4278220b579.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/51826981a2d24e7aa872f4278220b579.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER WORKLOAD CLASS Statement (Workload Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "d4b4659f501c48fd90d52d99759a87f2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d4b4659f501c48fd90d52d99759a87f2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER WORKLOAD MAPPING Statement (Workload Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "81fc16bfa4904943b730bcd1848cd37d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/81fc16bfa4904943b730bcd1848cd37d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER X509 PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "4f7e59d60616461cbfaa00bda366b9f2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4f7e59d60616461cbfaa00bda366b9f2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ANNOTATE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "534df83ee61946b884e7594d21459e35.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/534df83ee61946b884e7594d21459e35.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CALL Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d364c175191014b592f500ccb5510c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d364c175191014b592f500ccb5510c.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "title": "CANCEL ASYNC CALL Statement", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "63ae89ee80ec4671b551d459e129d4a1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/63ae89ee80ec4671b551d459e129d4a1.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "COMMENT ON Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d3817075191014ba7bcfdbab508d0e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3817075191014ba7bcfdbab508d0e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "COMMIT Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d39db97519101480e7f9b76f48c2c4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d39db97519101480e7f9b76f48c2c4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CONNECT Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d3b9ad751910148cdccc8205563a87.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3b9ad751910148cdccc8205563a87.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE ANALYTIC MODEL (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "42da9e00b0f74e27980ccd49012ad49e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/42da9e00b0f74e27980ccd49012ad49e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE AUDIT POLICY Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d3d56075191014af43d6487fcaa603.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3d56075191014af43d6487fcaa603.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE CERTIFICATE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "ba87935fc4a84f4eb805d5eba9a7b480.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ba87935fc4a84f4eb805d5eba9a7b480.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE CREDENTIAL Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d3f464751910148968e73782586ed0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3f464751910148968e73782586ed0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE FUNCTION Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d42e77751910149f0ff6b879b1290f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d42e77751910149f0ff6b879b1290f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE FUZZY SEARCH INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "9b79b31dde1b4f6d84144fba8d942bd3.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9b79b31dde1b4f6d84144fba8d942bd3.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d44b4175191014a940afff4b47c7ea.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d44b4175191014a940afff4b47c7ea.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE JWT PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "bfe3daf744324bc390902251817a1fcc.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bfe3daf744324bc390902251817a1fcc.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE LDAP PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "3b722036ba4941df8712508a3b231643.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3b722036ba4941df8712508a3b231643.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE LIBRARY Statement (SQLScript)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "62263ce35ac74488a397553fcb25a7d6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/62263ce35ac74488a397553fcb25a7d6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE PROCEDURE Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d467407519101484f190f545d54b24.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d467407519101484f190f545d54b24.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE PROJECTION VIEW Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "e35411b417a94f199679b9f9f45c2306.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e35411b417a94f199679b9f9f45c2306.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE PSE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "4d80bf63fc374a7f99be94d8ce70a07a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4d80bf63fc374a7f99be94d8ce70a07a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE PUBLIC KEY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "80bae7bd45b14516b334d649fdac6de2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/80bae7bd45b14516b334d649fdac6de2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE REMOTE SOURCE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d48343751910149985a2c925e12190.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d48343751910149985a2c925e12190.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE REMOTE SUBSCRIPTION Statement", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "0d7acab98a0346039221da5d5c5156ba.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0d7acab98a0346039221da5d5c5156ba.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE ROLE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d4a23b75191014a182b123906d5b16.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d4a23b75191014a182b123906d5b16.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE ROLEGROUP Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "6cf193279bb4481faf8f2c77f137250c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6cf193279bb4481faf8f2c77f137250c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE SAML PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d4cca075191014824eeda2cbba6445.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d4cca075191014824eeda2cbba6445.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE SCHEDULER JOB Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "d7d43d818366460dae1328aab5d5df4f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d7d43d818366460dae1328aab5d5df4f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE SCHEMA Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d4ecad7519101497d192700ce5f3df.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d4ecad7519101497d192700ce5f3df.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE SCHEMA SYNONYM Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "1b54e1f64cfc401bb3adbe7c143bc323.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1b54e1f64cfc401bb3adbe7c143bc323.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE SEQUENCE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d509277519101489029c064d468c5d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d509277519101489029c064d468c5d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE STATISTICS Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d5252d7519101493f5e662a6cda4d4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5252d7519101493f5e662a6cda4d4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE STRUCTURED COLUMN MASK Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "a084e535192342dda9e8549b45d63e7f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a084e535192342dda9e8549b45d63e7f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE STRUCTURED FILTER Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "f0238ff8445342a8a9a2f9c3dd36631e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f0238ff8445342a8a9a2f9c3dd36631e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE STRUCTURED PRIVILEGE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "622b2dfdce81455a949fb2bb3be014d2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/622b2dfdce81455a949fb2bb3be014d2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE SYNONYM Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d5412b75191014bc7ec7e133ce5bf5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5412b75191014bc7ec7e133ce5bf5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE TABLE GROUP Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "a8dfce213a28413e94038f2ae5f91e6a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a8dfce213a28413e94038f2ae5f91e6a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Non-Heterogeneous Create Partition Clauses", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "CREATE TABLE Statement (Data Definition)" + ], + "file": "ca6a99bbfcd94be9ab8020a86f43caae.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ca6a99bbfcd94be9ab8020a86f43caae.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Heterogeneous Create Partition Clauses", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "CREATE TABLE Statement (Data Definition)" + ], + "file": "d496e58ce9b54bac9674beda4a636946.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d496e58ce9b54bac9674beda4a636946.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE TOKEN EXCHANGER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "fb015cd6638b46abbe3c32e66c43d576.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fb015cd6638b46abbe3c32e66c43d576.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE TRIGGER Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d5a65575191014946db96aaedbef5b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5a65575191014946db96aaedbef5b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE TYPE Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d5c1ed75191014a80d897035629def.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5c1ed75191014a80d897035629def.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE USER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d5ddb075191014b594f7b11ff08ee2.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5ddb075191014b594f7b11ff08ee2.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE USERGROUP Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "9869125ea93548009820702f5bd897d8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9869125ea93548009820702f5bd897d8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE VECTOR INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "ab672646e17c46e8ab60463efa22558d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ab672646e17c46e8ab60463efa22558d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE VIEW Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d5fa9b75191014a33eee92692f1702.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5fa9b75191014a33eee92692f1702.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE VIRTUAL FUNCTION Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "55d2f440e375408194be7e58266733fa.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/55d2f440e375408194be7e58266733fa.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE VIRTUAL TABLE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "d2a0406155f24a49aa6c549e0c428bd7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d2a0406155f24a49aa6c549e0c428bd7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE WORKLOAD CLASS Statement (Workload Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "dc417c30b1b3460c8860f6c7ea2a7faa.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dc417c30b1b3460c8860f6c7ea2a7faa.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE WORKLOAD MAPPING Statement (Workload Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "996978a669b847ea89ca7f2cce41d916.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/996978a669b847ea89ca7f2cce41d916.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "CREATE X509 PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "3b3163d6ad0f4eb9bd73c7c060f49649.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3b3163d6ad0f4eb9bd73c7c060f49649.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DELETE Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d6169a75191014892db922f94abe41.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6169a75191014892db922f94abe41.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "title": "DO BEGIN...END Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "52103853351841f6a1e87f40b2686da9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/52103853351841f6a1e87f40b2686da9.html?version=2026_2_QRC", + "status": "outside_scope_sqlscript_body", + "tests": [] + }, + { + "title": "DROP ANALYTIC MODEL (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "99539ed9e50f4e9395c4d87982885ff4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/99539ed9e50f4e9395c4d87982885ff4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP AUDIT POLICY Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d6324675191014b588d13fe491415e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6324675191014b588d13fe491415e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP CERTIFICATE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "b7784cfa101942f4ae17a258d060998e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b7784cfa101942f4ae17a258d060998e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP CREDENTIAL Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d64db0751910149535843182bf8d86.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d64db0751910149535843182bf8d86.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP FUNCTION Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d6852375191014a6e2f134db8fc8cb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6852375191014a6e2f134db8fc8cb.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d6f4e575191014b333904458242bd7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6f4e575191014b333904458242bd7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP JWT PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "e3caf68bb0b84b4cbcc0e3a7c022e92a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e3caf68bb0b84b4cbcc0e3a7c022e92a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP LDAP PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "340e913ae1d044d993dec2a7eff941c4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/340e913ae1d044d993dec2a7eff941c4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP LIBRARY Statement (SQLScript)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "d4160799a5564fc0b901e499c29dc5b4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d4160799a5564fc0b901e499c29dc5b4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP PROCEDURE Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d7165e75191014a7129ace03afebeb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7165e75191014a7129ace03afebeb.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP PSE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "25d67950e6614770aa98aec23ab117ee.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/25d67950e6614770aa98aec23ab117ee.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP PUBLIC KEY Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "1f935a3dff744f7bbf488271a6c869f4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1f935a3dff744f7bbf488271a6c869f4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP REMOTE SOURCE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d7332f75191014866fc4b83cfba146.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7332f75191014866fc4b83cfba146.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP REMOTE SUBSCRIPTION Statement", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "27b652dbc0064091bcc57ebde419e2fd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/27b652dbc0064091bcc57ebde419e2fd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP ROLE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d74f7f75191014a71ee6a2ae78547f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d74f7f75191014a71ee6a2ae78547f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP ROLEGROUP Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "9506eaa644934372bf5f7d6117e68e55.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9506eaa644934372bf5f7d6117e68e55.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP SAML PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d76c8675191014b9acc9697a367773.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d76c8675191014b9acc9697a367773.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP SCHEDULER JOB Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "5a5f9f0efe9544769977e5ef45defc1f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5a5f9f0efe9544769977e5ef45defc1f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP SCHEMA Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d7891d751910149164f0d4ca73639d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7891d751910149164f0d4ca73639d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP SCHEMA SYNONYM Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "f8ac4d9c656049c29d80a9ba3a495001.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f8ac4d9c656049c29d80a9ba3a495001.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP SEQUENCE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d7a85b751910149482f673a4789209.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7a85b751910149482f673a4789209.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP STATISTICS Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d7c595751910148307bf3bf4c745e6.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7c595751910148307bf3bf4c745e6.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP STRUCTURED COLUMN MASK Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "82d10ff0b6bd47ca9f982855015f9c36.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/82d10ff0b6bd47ca9f982855015f9c36.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP STRUCTURED FILTER Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "897bc02cfb274a54a2661ffde9f97c76.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/897bc02cfb274a54a2661ffde9f97c76.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP STRUCTURED PRIVILEGE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "4742f573d0c24e9084a699d464bf20c7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4742f573d0c24e9084a699d464bf20c7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP SYNONYM Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d7e172751910148bccb49de92d9859.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7e172751910148bccb49de92d9859.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP TABLE GROUP Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "bb62f12fef1c445189837576189c7143.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bb62f12fef1c445189837576189c7143.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP TABLE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d7fd287519101480afbce1b997e4b9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7fd287519101480afbce1b997e4b9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP TOKEN EXCHANGER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "f5db5d688f3e4f069b67b9088f34eb3b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f5db5d688f3e4f069b67b9088f34eb3b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP TRIGGER Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d81ec9751910148fe6e1e072ac439e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d81ec9751910148fe6e1e072ac439e.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP TYPE Statement (Procedural)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d83beb751910148651cebdf3564ad3.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d83beb751910148651cebdf3564ad3.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP USER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d8d33275191014adce9c099eeed35c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d8d33275191014adce9c099eeed35c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP USERGROUP Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "6dc0adae9f4c4ebaa46cbe6b5f636ee7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6dc0adae9f4c4ebaa46cbe6b5f636ee7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP VECTOR INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "3e5e6e9b6fc14561b242fd22d97dbf91.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3e5e6e9b6fc14561b242fd22d97dbf91.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP VIEW Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d9c05f75191014b24fca55a8534531.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d9c05f75191014b24fca55a8534531.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP WORKLOAD CLASS Statement (Workload Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "22f628bdb85d4ccd885cf642d3fd31c4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/22f628bdb85d4ccd885cf642d3fd31c4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP WORKLOAD MAPPING Statement (Workload Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "8d90e94880924f7d957ba73db7e7db17.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8d90e94880924f7d957ba73db7e7db17.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "DROP X509 PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "f7a37e81a9b64a2cb6a6092a38b06c60.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f7a37e81a9b64a2cb6a6092a38b06c60.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "EXPLAIN PLAN Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d9ec5575191014a251e58ecf90997a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d9ec5575191014a251e58ecf90997a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "EXPORT Statement (Data Import Export)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20da0bec751910148e69c9668ea3ccb8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da0bec751910148e69c9668ea3ccb8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "EXPORT INTO RDF FILE Statement (Data Import Export)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "EXPORT INTO Statement (Data Import Export)" + ], + "file": "644d06c7e0d94343b3872a88acb08c33.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/644d06c7e0d94343b3872a88acb08c33.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "GRANT Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f674e1751910148a8b990d33efbdc5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f674e1751910148a8b990d33efbdc5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "IMPORT Statement (Data Import Export)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f75ade751910148492a90e5e375b8f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f75ade751910148492a90e5e375b8f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "IMPORT FROM RDF FILE Statement (Data Import Export)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "IMPORT FROM Statement (Data Import Export)" + ], + "file": "f07faf9748d549dda8c70ca0b5d2ba20.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f07faf9748d549dda8c70ca0b5d2ba20.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "IMPORT SCAN Statement (Data Import Export)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f79b2175191014a45f9947577a2e85.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f79b2175191014a45f9947577a2e85.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "INSERT Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f7f70975191014a76da70c9181720e.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f7f70975191014a76da70c9181720e.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "title": "LOAD Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f83c8c75191014b215d6c8c427c91b.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f83c8c75191014b215d6c8c427c91b.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "LOCK TABLE Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f88d8d75191014a51abbaa4e3d36cb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f88d8d75191014a51abbaa4e3d36cb.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "MERGE DELTA Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f8d0a175191014a7c192193b8645a9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f8d0a175191014a7c192193b8645a9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "MERGE INTO Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "3226201f95764a57810dd256c9524d56.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3226201f95764a57810dd256c9524d56.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "REFRESH PSE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "c2f1007259654a8f941bab6cebd0ad31.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c2f1007259654a8f941bab6cebd0ad31.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "REFRESH STATISTICS Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fae6d975191014849d91781fd50986.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fae6d975191014849d91781fd50986.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "REFRESH VIEW Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "81e15837ac7249938e05e346c391ead5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/81e15837ac7249938e05e346c391ead5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "RELEASE SAVEPOINT Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "445eb4d2202f4f29b67e9874a3c9acfb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/445eb4d2202f4f29b67e9874a3c9acfb.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "RENAME COLUMN Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fb2b8b7519101499d2c6bd37c81b32.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fb2b8b7519101499d2c6bd37c81b32.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "RENAME INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fb6e10751910148b45cefcb6294342.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fb6e10751910148b45cefcb6294342.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "RENAME SCHEMA Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "a52198083ad642f79851b8f501aad7f5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a52198083ad642f79851b8f501aad7f5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "RENAME TABLE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fbadb2751910148b24d8d93aff01d4.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fbadb2751910148b24d8d93aff01d4.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "RENAME VECTOR INDEX Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "8b2f122785f24dde8f2b6441b47914b0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8b2f122785f24dde8f2b6441b47914b0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "REPLACE Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fc06a7751910149892c0d09be21a38.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fc06a7751910149892c0d09be21a38.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "REVOKE Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fc91cb75191014ac15eb4d6f2d7dde.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fc91cb75191014ac15eb4d6f2d7dde.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ROLLBACK Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fcc453751910149557fc90fe781449.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fcc453751910149557fc90fe781449.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ROLLBACK TO SAVEPOINT Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "104ae26787e24bddbda2953c0397b6e8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/104ae26787e24bddbda2953c0397b6e8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SAVEPOINT Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "cd4172aead1e47e99f6599656887f343.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/cd4172aead1e47e99f6599656887f343.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "HINT Details", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements", + "SELECT Statement (Data Manipulation)" + ], + "file": "4ba9edce1f2347a0b9fcda99879c17a1.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4ba9edce1f2347a0b9fcda99879c17a1.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET PSE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "10fe8070539649358c79955110311082.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/10fe8070539649358c79955110311082.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET [SESSION] Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fd82b675191014b22c8af08d0b319c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fd82b675191014b22c8af08d0b319c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET SESSION CREDENTIAL FOR REMOTE SOURCE (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "3480cdfb947844ab8c60dabe16a5daef.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3480cdfb947844ab8c60dabe16a5daef.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET ROLEGROUP Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "6e62e7ef3b7949eb83c47115dc47e2c8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6e62e7ef3b7949eb83c47115dc47e2c8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET SCHEMA Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fd550375191014b886a338afb4cd5f.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fd550375191014b886a338afb4cd5f.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET TRANSACTION Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fdf9cb75191014b85aaa9dec841291.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fdf9cb75191014b85aaa9dec841291.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET TRANSACTION AUTOCOMMIT DDL Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "d538d11053bd4f3f847ec5ce817a3d4c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d538d11053bd4f3f847ec5ce817a3d4c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SET USERGROUP Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "19918539993849888af17415d43382b5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/19918539993849888af17415d43382b5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "TRUNCATE TABLE Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fe29f0751910149904f0c5c3201cfa.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fe29f0751910149904f0c5c3201cfa.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UNLOAD Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fe92a2751910148c38887562a97c5a.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fe92a2751910148c38887562a97c5a.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UNSET PSE Statement (System Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "408255391bd043209a957830f8e87b65.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/408255391bd043209a957830f8e87b65.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UNSET [SESSION] Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fec78075191014a376da819b302f43.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fec78075191014a376da819b302f43.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UNSET ROLEGROUP Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "2f2ee71a3da04b248216d7915e85cb11.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2f2ee71a3da04b248216d7915e85cb11.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UNSET SESSION CREDENTIAL FOR REMOTE SOURCE (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "348e978c588c4905957ece4126f98126.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/348e978c588c4905957ece4126f98126.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UNSET TRANSACTION Statement (Transaction Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "bc90c1228539462a99344eb3d39dae00.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bc90c1228539462a99344eb3d39dae00.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UNSET USERGROUP Statement (Session Management)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "996f99709bfa4037a9dcce812b6d57d9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/996f99709bfa4037a9dcce812b6d57d9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "UPDATE Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20ff268675191014964add3d17700909.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ff268675191014964add3d17700909.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "title": "UPSERT Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "ea8b6773be584203bcd99da76844c5ed.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ea8b6773be584203bcd99da76844c5ed.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "title": "VALIDATE LDAP PROVIDER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "4181217e3e104c57a5090431c1cd70b7.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4181217e3e104c57a5090431c1cd70b7.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "VALIDATE USER Statement (Access Control)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "5e336347cb8444279b451c172ad00c75.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5e336347cb8444279b451c172ad00c75.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Access Control Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "20a40b54751910148a82d91c57a21c1c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a40b54751910148a82d91c57a21c1c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Data Definition Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "209ce8cd75191014bcd59c2b379a17c9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209ce8cd75191014bcd59c2b379a17c9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Data Import Export Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "20a5342e75191014bb95e83cbbe772fa.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a5342e75191014bb95e83cbbe772fa.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Data Manipulation Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "209eaa85751910149a30f95c936075be.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209eaa85751910149a30f95c936075be.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Graph Workspace Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "953a96f81f774fdeb733b83987ac6693.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/953a96f81f774fdeb733b83987ac6693.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "JSON Document Store Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "2282aef7db6846b68f09d72be04cb9c0.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2282aef7db6846b68f09d72be04cb9c0.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Procedural Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "20a64c8c75191014af7ce80b4895b2eb.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a64c8c75191014af7ce80b4895b2eb.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Session Management Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "20a27b0a75191014a5bd9e2a08ff9354.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a27b0a75191014a5bd9e2a08ff9354.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Smart Data Integration and Smart Data Quality Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "86526627ff5e4362922c72048c9c61f5.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/86526627ff5e4362922c72048c9c61f5.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "System Management Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "20a1c3a975191014be0cf8b1b853ddf8.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a1c3a975191014be0cf8b1b853ddf8.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Transaction Management Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "20a3ae8a75191014b039b36c43e2029d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a3ae8a75191014b039b36c43e2029d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Workload Management Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "c5f48e60b55645fe91b241c4d0b89278.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c5f48e60b55645fe91b241c4d0b89278.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "System Limitations", + "path": [ + "SQL Reference" + ], + "file": "20a760537519101497e3cfe07b348f3c.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a760537519101497e3cfe07b348f3c.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SQL Error Codes", + "path": [ + "SQL Reference" + ], + "file": "20a78d3275191014b41bae7c4a46d835.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a78d3275191014b41bae7c4a46d835.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Predicates", + "path": [ + "SQL Reference" + ], + "file": "20a2ab29751910148de0fe7189c330bc.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a2ab29751910148de0fe7189c330bc.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SQL Functions", + "path": [ + "SQL Reference" + ], + "file": "20a61f29751910149f99f0300dd95cd9.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a61f29751910149f99f0300dd95cd9.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Alphabetical List Of Functions", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "f12b86a6284c4aeeb449e57eb5dd3ebd.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f12b86a6284c4aeeb449e57eb5dd3ebd.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Window Functions and the Window Specification", + "path": [ + "SQL Reference", + "SQL Functions" + ], + "file": "20a353327519101495dfd0a87060a0d3.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a353327519101495dfd0a87060a0d3.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SQL Statements", + "path": [ + "SQL Reference" + ], + "file": "20a6791f751910148d2bfe3814192a01.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a6791f751910148d2bfe3814192a01.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "Alphabetical List of Statements", + "path": [ + "SQL Reference", + "SQL Statements" + ], + "file": "3bc1a0d4611d40c4a6e3fc7c8e80395d.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3bc1a0d4611d40c4a6e3fc7c8e80395d.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER SYSTEM ... (All ALTER SYSTEM Statements)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "5f62bd7ebd0f471494faffaec4015041.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5f62bd7ebd0f471494faffaec4015041.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "ALTER TABLE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d329a6751910149d5fdbc4800f92ff.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d329a6751910149d5fdbc4800f92ff.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "title": "CREATE TABLE Statement (Data Definition)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20d58a5f75191014b2fe92141b7df228.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d58a5f75191014b2fe92141b7df228.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "title": "EXPORT INTO Statement (Data Import Export)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "6a6f59bbfbb64ade84d83d7f87789753.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6a6f59bbfbb64ade84d83d7f87789753.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "IMPORT FROM Statement (Data Import Export)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20f712e175191014907393741fadcb97.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f712e175191014907393741fadcb97.html?version=2026_2_QRC", + "status": "not_exhaustively_implemented", + "tests": [] + }, + { + "title": "SELECT Statement (Data Manipulation)", + "path": [ + "SQL Reference", + "SQL Statements", + "Alphabetical List of Statements" + ], + "file": "20fcf24075191014a89e9dc7b8408b26.html", + "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fcf24075191014a89e9dc7b8408b26.html?version=2026_2_QRC", + "status": "partially_implemented", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + } +] diff --git a/docs/hana/functions.json b/docs/hana/functions.json new file mode 100644 index 00000000..ff3b50ce --- /dev/null +++ b/docs/hana/functions.json @@ -0,0 +1,1795 @@ +[ + { + "id": "4.9.1.1", + "name": "ABAP_ALPHANUM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=83", + "builtin_recognized": true + }, + { + "id": "4.9.1.2", + "name": "ABAP_DF16RAW_TO_SMALLDECIMAL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=85", + "builtin_recognized": true + }, + { + "id": "4.9.1.3", + "name": "ABAP_DF34RAW_TO_DECIMAL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=85", + "builtin_recognized": true + }, + { + "id": "4.9.1.4", + "name": "ABAP_NUMC", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=86", + "builtin_recognized": true + }, + { + "id": "4.9.1.5", + "name": "ABAP_LOWER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=88", + "builtin_recognized": true + }, + { + "id": "4.9.1.6", + "name": "ABAP_UPPER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=89", + "builtin_recognized": true + }, + { + "id": "4.9.1.7", + "name": "ABS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=89", + "builtin_recognized": true + }, + { + "id": "4.9.1.8", + "name": "ACOS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=90", + "builtin_recognized": true + }, + { + "id": "4.9.1.9", + "name": "ADD_DAYS", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=91", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.10", + "name": "ADD_MONTHS", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=92", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.11", + "name": "ADD_MONTHS_LAST", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=94", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.12", + "name": "ADD_NANO100", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=95", + "builtin_recognized": true + }, + { + "id": "4.9.1.13", + "name": "ADD_SECONDS", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=96", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.14", + "name": "ADD_WORKDAYS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=97", + "builtin_recognized": true + }, + { + "id": "4.9.1.15", + "name": "ADD_YEARS", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=101", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.16", + "name": "ALLOW_PRECISION_LOSS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=102", + "builtin_recognized": true + }, + { + "id": "4.9.1.17", + "name": "ASCII", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=103", + "builtin_recognized": true + }, + { + "id": "4.9.1.18", + "name": "ASIN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=104", + "builtin_recognized": true + }, + { + "id": "4.9.1.19", + "name": "ATAN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=105", + "builtin_recognized": true + }, + { + "id": "4.9.1.20", + "name": "ATAN2", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=105", + "builtin_recognized": true + }, + { + "id": "4.9.1.21", + "name": "AUTO_CORR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=106", + "builtin_recognized": true + }, + { + "id": "4.9.1.22", + "name": "AVG", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=109", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.23", + "name": "BINNING", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=110", + "builtin_recognized": true + }, + { + "id": "4.9.1.24", + "name": "BINTOHEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=112", + "builtin_recognized": true + }, + { + "id": "4.9.1.25", + "name": "BINTONHEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=113", + "builtin_recognized": true + }, + { + "id": "4.9.1.26", + "name": "BINTOSTR", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=114", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.27", + "name": "BITAND", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=115", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.28", + "name": "BITCOUNT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=116", + "builtin_recognized": true + }, + { + "id": "4.9.1.29", + "name": "BITNOT", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=117", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.30", + "name": "BITOR", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=118", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.31", + "name": "BITSET", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=119", + "builtin_recognized": true + }, + { + "id": "4.9.1.32", + "name": "BITUNSET", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=121", + "builtin_recognized": true + }, + { + "id": "4.9.1.33", + "name": "BITXOR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=122", + "builtin_recognized": true + }, + { + "id": "4.9.1.34", + "name": "CARDINALITY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=123", + "builtin_recognized": true + }, + { + "id": "4.9.1.35", + "name": "CAST", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=124", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.36", + "name": "CEIL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=125", + "builtin_recognized": true + }, + { + "id": "4.9.1.37", + "name": "CHAR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=126", + "builtin_recognized": true + }, + { + "id": "4.9.1.38", + "name": "COALESCE", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=127", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.39", + "name": "CONCAT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=128", + "builtin_recognized": true + }, + { + "id": "4.9.1.40", + "name": "CONCAT_NAZ", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=129", + "builtin_recognized": true + }, + { + "id": "4.9.1.41", + "name": "CONVERT_CURRENCY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=130", + "builtin_recognized": true + }, + { + "id": "4.9.1.42", + "name": "CONVERT_UNIT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=140", + "builtin_recognized": true + }, + { + "id": "4.9.1.43", + "name": "CORR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=144", + "builtin_recognized": true + }, + { + "id": "4.9.1.44", + "name": "CORR_SPEARMAN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=147", + "builtin_recognized": true + }, + { + "id": "4.9.1.45", + "name": "COS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=151", + "builtin_recognized": true + }, + { + "id": "4.9.1.46", + "name": "COSH", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=152", + "builtin_recognized": true + }, + { + "id": "4.9.1.47", + "name": "COT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=153", + "builtin_recognized": true + }, + { + "id": "4.9.1.48", + "name": "COUNT", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=154", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.49", + "name": "CROSS_CORR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=155", + "builtin_recognized": true + }, + { + "id": "4.9.1.50", + "name": "CUBIC_SPLINE_APPROX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=158", + "builtin_recognized": true + }, + { + "id": "4.9.1.51", + "name": "CUME_DIST", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=163", + "builtin_recognized": true + }, + { + "id": "4.9.1.52", + "name": "CURRENT_CONNECTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=165", + "builtin_recognized": true + }, + { + "id": "4.9.1.53", + "name": "CURRENT_DATABASE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=165", + "builtin_recognized": true + }, + { + "id": "4.9.1.54", + "name": "CURRENT_DATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=166", + "builtin_recognized": true + }, + { + "id": "4.9.1.55", + "name": "CURRENT_IDENTITY_VALUE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=167", + "builtin_recognized": true + }, + { + "id": "4.9.1.56", + "name": "CURRENT_MVCC_SNAPSHOT_TIMESTAMP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=168", + "builtin_recognized": true + }, + { + "id": "4.9.1.57", + "name": "CURRENT_OBJECT_SCHEMA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=168", + "builtin_recognized": true + }, + { + "id": "4.9.1.58", + "name": "CURRENT_SCHEMA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=169", + "builtin_recognized": true + }, + { + "id": "4.9.1.59", + "name": "CURRENT_SITE_ID", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=170", + "builtin_recognized": true + }, + { + "id": "4.9.1.60", + "name": "CURRENT_TIME", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=171", + "builtin_recognized": true + }, + { + "id": "4.9.1.61", + "name": "CURRENT_TIMESTAMP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=171", + "builtin_recognized": true + }, + { + "id": "4.9.1.64", + "name": "CURRENT_UPDATE_TRANSACTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=174", + "builtin_recognized": true + }, + { + "id": "4.9.1.65", + "name": "CURRENT_USER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=175", + "builtin_recognized": true + }, + { + "id": "4.9.1.66", + "name": "CURRENT_USER_ID", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=176", + "builtin_recognized": true + }, + { + "id": "4.9.1.67", + "name": "CURRENT_UTCDATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=176", + "builtin_recognized": true + }, + { + "id": "4.9.1.68", + "name": "CURRENT_UTCTIME", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=177", + "builtin_recognized": true + }, + { + "id": "4.9.1.69", + "name": "CURRENT_UTCTIMESTAMP", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=178", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.70", + "name": "DAYNAME", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=179", + "builtin_recognized": true + }, + { + "id": "4.9.1.71", + "name": "DAYOFMONTH", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=180", + "builtin_recognized": true + }, + { + "id": "4.9.1.72", + "name": "DAYOFYEAR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=181", + "builtin_recognized": true + }, + { + "id": "4.9.1.73", + "name": "DAYS_BETWEEN", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=181", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.74", + "name": "DENSE_RANK", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=183", + "builtin_recognized": true + }, + { + "id": "4.9.1.75", + "name": "DFT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=184", + "builtin_recognized": true + }, + { + "id": "4.9.1.80", + "name": "ESCAPE_DOUBLE_QUOTES", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=191", + "builtin_recognized": true + }, + { + "id": "4.9.1.81", + "name": "ESCAPE_SINGLE_QUOTES", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=192", + "builtin_recognized": true + }, + { + "id": "4.9.1.82", + "name": "EXP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=193", + "builtin_recognized": true + }, + { + "id": "4.9.1.83", + "name": "EXPRESSION_MACRO", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=193", + "builtin_recognized": true + }, + { + "id": "4.9.1.84", + "name": "EXTRACT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=194", + "builtin_recognized": true + }, + { + "id": "4.9.1.85", + "name": "FIRST_VALUE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=195", + "builtin_recognized": true + }, + { + "id": "4.9.1.86", + "name": "FLOOR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=197", + "builtin_recognized": true + }, + { + "id": "4.9.1.87", + "name": "GENERATE_PASSWORD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=198", + "builtin_recognized": true + }, + { + "id": "4.9.1.88", + "name": "GREATEST", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=199", + "builtin_recognized": true + }, + { + "id": "4.9.1.89", + "name": "GROUP_SCORE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=199", + "builtin_recognized": true + }, + { + "id": "4.9.1.90", + "name": "GROUPING", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=203", + "builtin_recognized": true + }, + { + "id": "4.9.1.91", + "name": "GROUPING_ID", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=205", + "builtin_recognized": true + }, + { + "id": "4.9.1.92", + "name": "HAMMING_DISTANCE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=207", + "builtin_recognized": true + }, + { + "id": "4.9.1.93", + "name": "HASH_MD5", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=208", + "builtin_recognized": true + }, + { + "id": "4.9.1.94", + "name": "HASH_SHA256", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=210", + "builtin_recognized": true + }, + { + "id": "4.9.1.95", + "name": "HEXTOBIN", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=211", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.96", + "name": "HEXTONUM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=212", + "builtin_recognized": true + }, + { + "id": "4.9.1.97", + "name": "HOUR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=213", + "builtin_recognized": true + }, + { + "id": "4.9.1.98", + "name": "IFNULL", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=213", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.99", + "name": "INDEXING_ERROR_CODE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=214", + "builtin_recognized": true + }, + { + "id": "4.9.1.100", + "name": "INDEXING_ERROR_MESSAGE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=215", + "builtin_recognized": true + }, + { + "id": "4.9.1.101", + "name": "INDEXING_STATUS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=216", + "builtin_recognized": true + }, + { + "id": "4.9.1.102", + "name": "INITCAP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=218", + "builtin_recognized": true + }, + { + "id": "4.9.1.103", + "name": "IS_SQL_INJECTION_SAFE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=219", + "builtin_recognized": true + }, + { + "id": "4.9.1.104", + "name": "ISOWEEK", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=220", + "builtin_recognized": true + }, + { + "id": "4.9.1.105", + "name": "JSON_QUERY", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=221", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.106", + "name": "JSON_TABLE", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=224", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.107", + "name": "JSON_VALUE", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=233", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.108", + "name": "LAG", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=236", + "builtin_recognized": true + }, + { + "id": "4.9.1.109", + "name": "LANGUAGE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=238", + "builtin_recognized": true + }, + { + "id": "4.9.1.110", + "name": "LAST_DAY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=238", + "builtin_recognized": true + }, + { + "id": "4.9.1.111", + "name": "LAST_VALUE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=239", + "builtin_recognized": true + }, + { + "id": "4.9.1.112", + "name": "LCASE", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=241", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.113", + "name": "LEAD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=242", + "builtin_recognized": true + }, + { + "id": "4.9.1.114", + "name": "LEAST", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=243", + "builtin_recognized": true + }, + { + "id": "4.9.1.115", + "name": "LEFT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=244", + "builtin_recognized": true + }, + { + "id": "4.9.1.116", + "name": "LENGTH", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=245", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.117", + "name": "LINEAR_APPROX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=246", + "builtin_recognized": true + }, + { + "id": "4.9.1.118", + "name": "LN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=250", + "builtin_recognized": true + }, + { + "id": "4.9.1.119", + "name": "LOCALTOUTC", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=251", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs" + ] + }, + { + "id": "4.9.1.120", + "name": "LOCATE", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=252", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.121", + "name": "LOCATE_REGEXPR", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=253", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.122", + "name": "LOG", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=256", + "builtin_recognized": true + }, + { + "id": "4.9.1.123", + "name": "LOWER", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=256", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.124", + "name": "LPAD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=257", + "builtin_recognized": true + }, + { + "id": "4.9.1.125", + "name": "LTRIM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=258", + "builtin_recognized": true + }, + { + "id": "4.9.1.126", + "name": "MAP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=259", + "builtin_recognized": true + }, + { + "id": "4.9.1.127", + "name": "MAX", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=261", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.128", + "name": "MEDIAN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=262", + "builtin_recognized": true + }, + { + "id": "4.9.1.129", + "name": "MEMBER_AT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=265", + "builtin_recognized": true + }, + { + "id": "4.9.1.130", + "name": "MIMETYPE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=266", + "builtin_recognized": true + }, + { + "id": "4.9.1.131", + "name": "MIN", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=267", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.132", + "name": "MINUTE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=269", + "builtin_recognized": true + }, + { + "id": "4.9.1.133", + "name": "MOD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=270", + "builtin_recognized": true + }, + { + "id": "4.9.1.134", + "name": "MONTH", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=271", + "builtin_recognized": true + }, + { + "id": "4.9.1.135", + "name": "MONTHNAME", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=271", + "builtin_recognized": true + }, + { + "id": "4.9.1.136", + "name": "MONTHS_BETWEEN", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=272", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.137", + "name": "NANO100_BETWEEN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=273", + "builtin_recognized": true + }, + { + "id": "4.9.1.138", + "name": "NCHAR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=274", + "builtin_recognized": true + }, + { + "id": "4.9.1.139", + "name": "NDIV0", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=275", + "builtin_recognized": true + }, + { + "id": "4.9.1.140", + "name": "NEXT_DAY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=276", + "builtin_recognized": true + }, + { + "id": "4.9.1.141", + "name": "NEWUID", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=276", + "builtin_recognized": true + }, + { + "id": "4.9.1.142", + "name": "NORMALIZE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=277", + "builtin_recognized": true + }, + { + "id": "4.9.1.143", + "name": "NOW", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=280", + "builtin_recognized": true + }, + { + "id": "4.9.1.144", + "name": "NTH_VALUE", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=280", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.145", + "name": "NTILE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=282", + "builtin_recognized": true + }, + { + "id": "4.9.1.146", + "name": "NULLIF", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=284", + "builtin_recognized": true + }, + { + "id": "4.9.1.147", + "name": "NUMTOHEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=285", + "builtin_recognized": true + }, + { + "id": "4.9.1.148", + "name": "OCCURRENCES_REGEXPR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=286", + "builtin_recognized": true + }, + { + "id": "4.9.1.149", + "name": "PERCENT_RANK", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=287", + "builtin_recognized": true + }, + { + "id": "4.9.1.150", + "name": "PERCENTILE_CONT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=289", + "builtin_recognized": true + }, + { + "id": "4.9.1.151", + "name": "PERCENTILE_DISC", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=291", + "builtin_recognized": true + }, + { + "id": "4.9.1.152", + "name": "PLAINTEXT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=293", + "builtin_recognized": true + }, + { + "id": "4.9.1.153", + "name": "POWER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=293", + "builtin_recognized": true + }, + { + "id": "4.9.1.154", + "name": "QUARTER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=294", + "builtin_recognized": true + }, + { + "id": "4.9.1.155", + "name": "RAND", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=295", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.156", + "name": "RANDOM_PARTITION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=296", + "builtin_recognized": true + }, + { + "id": "4.9.1.157", + "name": "RAND_SECURE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=299", + "builtin_recognized": true + }, + { + "id": "4.9.1.158", + "name": "RANK", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=300", + "builtin_recognized": true + }, + { + "id": "4.9.1.159", + "name": "RECORD_COMMIT_TIMESTAMP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=301", + "builtin_recognized": true + }, + { + "id": "4.9.1.160", + "name": "RECORD_ID", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=302", + "builtin_recognized": true + }, + { + "id": "4.9.1.161", + "name": "REPLACE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=304", + "builtin_recognized": true + }, + { + "id": "4.9.1.162", + "name": "REPLACE_REGEXPR", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=305", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.163", + "name": "RESULT_CACHE_ID", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=307", + "builtin_recognized": true + }, + { + "id": "4.9.1.164", + "name": "RESULT_CACHE_REFRESH_TIME", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=308", + "builtin_recognized": true + }, + { + "id": "4.9.1.165", + "name": "RIGHT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=308", + "builtin_recognized": true + }, + { + "id": "4.9.1.166", + "name": "ROUND", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=310", + "builtin_recognized": true + }, + { + "id": "4.9.1.167", + "name": "RPAD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=312", + "builtin_recognized": true + }, + { + "id": "4.9.1.168", + "name": "RTRIM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=313", + "builtin_recognized": true + }, + { + "id": "4.9.1.169", + "name": "ROW_NUMBER", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=314", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.170", + "name": "SCORE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=316", + "builtin_recognized": true + }, + { + "id": "4.9.1.171", + "name": "SECOND", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=321", + "builtin_recognized": true + }, + { + "id": "4.9.1.172", + "name": "SECONDS_BETWEEN", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=321", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.173", + "name": "SERIES_DISAGGREGATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=322", + "builtin_recognized": true + }, + { + "id": "4.9.1.174", + "name": "SERIES_ELEMENT_TO_PERIOD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=327", + "builtin_recognized": true + }, + { + "id": "4.9.1.175", + "name": "SERIES_FILTER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=328", + "builtin_recognized": true + }, + { + "id": "4.9.1.176", + "name": "SERIES_GENERATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=332", + "builtin_recognized": true + }, + { + "id": "4.9.1.177", + "name": "SERIES_PERIOD_TO_ELEMENT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=337", + "builtin_recognized": true + }, + { + "id": "4.9.1.178", + "name": "SERIES_ROUND", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=339", + "builtin_recognized": true + }, + { + "id": "4.9.1.179", + "name": "SESSION_CONTEXT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=342", + "builtin_recognized": true + }, + { + "id": "4.9.1.180", + "name": "SESSION_USER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=343", + "builtin_recognized": true + }, + { + "id": "4.9.1.181", + "name": "SIGN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=345", + "builtin_recognized": true + }, + { + "id": "4.9.1.182", + "name": "SIN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=346", + "builtin_recognized": true + }, + { + "id": "4.9.1.183", + "name": "SINH", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=346", + "builtin_recognized": true + }, + { + "id": "4.9.1.184", + "name": "SOUNDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=347", + "builtin_recognized": true + }, + { + "id": "4.9.1.185", + "name": "SQRT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=348", + "builtin_recognized": true + }, + { + "id": "4.9.1.186", + "name": "STDDEV", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=349", + "builtin_recognized": true + }, + { + "id": "4.9.1.187", + "name": "STDDEV_POP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=351", + "builtin_recognized": true + }, + { + "id": "4.9.1.188", + "name": "STDDEV_SAMP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=352", + "builtin_recognized": true + }, + { + "id": "4.9.1.189", + "name": "STRING_AGG", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=353", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.190", + "name": "STRTOBIN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=355", + "builtin_recognized": true + }, + { + "id": "4.9.1.191", + "name": "SUBARRAY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=356", + "builtin_recognized": true + }, + { + "id": "4.9.1.192", + "name": "SUBSTR_AFTER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=358", + "builtin_recognized": true + }, + { + "id": "4.9.1.193", + "name": "SUBSTR_BEFORE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=359", + "builtin_recognized": true + }, + { + "id": "4.9.1.194", + "name": "SUBSTRING_REGEXPR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=360", + "builtin_recognized": true + }, + { + "id": "4.9.1.195", + "name": "SUBSTRING", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=362", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.196", + "name": "SUM", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=363", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.197", + "name": "SYSUUID", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=364", + "builtin_recognized": true + }, + { + "id": "4.9.1.198", + "name": "TAN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=365", + "builtin_recognized": true + }, + { + "id": "4.9.1.199", + "name": "TANH", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=366", + "builtin_recognized": true + }, + { + "id": "4.9.1.200", + "name": "TO_ALPHANUM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=366", + "builtin_recognized": true + }, + { + "id": "4.9.1.201", + "name": "TO_BIGINT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=367", + "builtin_recognized": true + }, + { + "id": "4.9.1.202", + "name": "TO_BINARY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=368", + "builtin_recognized": true + }, + { + "id": "4.9.1.203", + "name": "TO_BLOB", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=369", + "builtin_recognized": true + }, + { + "id": "4.9.1.204", + "name": "TO_BOOLEAN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=369", + "builtin_recognized": true + }, + { + "id": "4.9.1.205", + "name": "TO_CLOB", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=370", + "builtin_recognized": true + }, + { + "id": "4.9.1.206", + "name": "TO_DATE", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=371", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.207", + "name": "TO_DATS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=372", + "builtin_recognized": true + }, + { + "id": "4.9.1.208", + "name": "TO_DECIMAL", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=373", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.209", + "name": "TO_DOUBLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=374", + "builtin_recognized": true + }, + { + "id": "4.9.1.210", + "name": "TO_FIXEDCHAR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=375", + "builtin_recognized": true + }, + { + "id": "4.9.1.211", + "name": "TO_INT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=375", + "builtin_recognized": true + }, + { + "id": "4.9.1.212", + "name": "TO_INTEGER", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=376", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.214", + "name": "TO_NCLOB", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=378", + "builtin_recognized": true + }, + { + "id": "4.9.1.215", + "name": "TO_NVARCHAR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=378", + "builtin_recognized": true + }, + { + "id": "4.9.1.216", + "name": "TO_REAL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=380", + "builtin_recognized": true + }, + { + "id": "4.9.1.217", + "name": "TO_SECONDDATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=381", + "builtin_recognized": true + }, + { + "id": "4.9.1.218", + "name": "TO_SMALLDECIMAL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=382", + "builtin_recognized": true + }, + { + "id": "4.9.1.219", + "name": "TO_SMALLINT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=382", + "builtin_recognized": true + }, + { + "id": "4.9.1.220", + "name": "TO_TIME", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=383", + "builtin_recognized": true + }, + { + "id": "4.9.1.221", + "name": "TO_TIMESTAMP", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=384", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.222", + "name": "TO_TINYINT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=385", + "builtin_recognized": true + }, + { + "id": "4.9.1.223", + "name": "TO_VARCHAR", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=386", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" + ] + }, + { + "id": "4.9.1.224", + "name": "TRIM", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=387", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.225", + "name": "TRIM_ARRAY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=388", + "builtin_recognized": true + }, + { + "id": "4.9.1.226", + "name": "UCASE", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=389", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.227", + "name": "UMINUS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=390", + "builtin_recognized": true + }, + { + "id": "4.9.1.228", + "name": "UNICODE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=391", + "builtin_recognized": true + }, + { + "id": "4.9.1.229", + "name": "UPPER", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=392", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + }, + { + "id": "4.9.1.230", + "name": "UTCTOLOCAL", + "status": "regression_tested_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=392", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs" + ] + }, + { + "id": "4.9.1.233", + "name": "VAR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=398", + "builtin_recognized": true + }, + { + "id": "4.9.1.234", + "name": "VAR_POP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=399", + "builtin_recognized": true + }, + { + "id": "4.9.1.235", + "name": "VAR_SAMP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=401", + "builtin_recognized": true + }, + { + "id": "4.9.1.236", + "name": "WEEK", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=402", + "builtin_recognized": true + }, + { + "id": "4.9.1.237", + "name": "WEEKDAY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=403", + "builtin_recognized": true + }, + { + "id": "4.9.1.238", + "name": "WEIGHTED_AVG", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=404", + "builtin_recognized": true + }, + { + "id": "4.9.1.239", + "name": "WIDTH_BUCKET", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=406", + "builtin_recognized": true + }, + { + "id": "4.9.1.240", + "name": "WORKDAYS_BETWEEN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=407", + "builtin_recognized": true + }, + { + "id": "4.9.1.241", + "name": "XMLEXTRACT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=411", + "builtin_recognized": true + }, + { + "id": "4.9.1.242", + "name": "XMLEXTRACTVALUE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=413", + "builtin_recognized": true + }, + { + "id": "4.9.1.243", + "name": "XMLTABLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=414", + "builtin_recognized": true + }, + { + "id": "4.9.1.244", + "name": "YEAR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=420", + "builtin_recognized": true + }, + { + "id": "4.9.1.245", + "name": "YEARS_BETWEEN", + "status": "native_fixture_forms", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=421", + "builtin_recognized": true, + "tests": [ + "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" + ] + } +] diff --git a/docs/hana/statements.json b/docs/hana/statements.json new file mode 100644 index 00000000..506a5873 --- /dev/null +++ b/docs/hana/statements.json @@ -0,0 +1,1042 @@ +[ + { + "id": "4.10.1.1", + "name": "ALTER AUDIT POLICY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=439" + }, + { + "id": "4.10.1.2", + "name": "ALTER CLIENTSIDE ENCRYPTION COLUMN KEY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=442" + }, + { + "id": "4.10.1.3", + "name": "ALTER CLIENTSIDE ENCRYPTION KEYPAIR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=445" + }, + { + "id": "4.10.1.4", + "name": "ALTER CREDENTIAL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=446" + }, + { + "id": "4.10.1.5", + "name": "ALTER DATABASE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=448" + }, + { + "id": "4.10.1.6", + "name": "ALTER FULLTEXT INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=452" + }, + { + "id": "4.10.1.7", + "name": "ALTER FUNCTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=455" + }, + { + "id": "4.10.1.8", + "name": "ALTER INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=460" + }, + { + "id": "4.10.1.9", + "name": "ALTER JWT PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=463" + }, + { + "id": "4.10.1.10", + "name": "ALTER LDAP PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=466" + }, + { + "id": "4.10.1.11", + "name": "ALTER LIBRARY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=470" + }, + { + "id": "4.10.1.12", + "name": "ALTER PROCEDURE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=472" + }, + { + "id": "4.10.1.13", + "name": "ALTER PSE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=476" + }, + { + "id": "4.10.1.14", + "name": "ALTER REMOTE SOURCE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=480" + }, + { + "id": "4.10.1.15", + "name": "ALTER ROLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=483" + }, + { + "id": "4.10.1.16", + "name": "ALTER SAML PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=485" + }, + { + "id": "4.10.1.17", + "name": "ALTER SEQUENCE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=487" + }, + { + "id": "4.10.1.18", + "name": "ALTER SCHEDULER JOB", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=490" + }, + { + "id": "4.10.1.19", + "name": "ALTER STATISTICS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=492" + }, + { + "id": "4.10.1.20", + "name": "ALTER STRUCTURED PRIVILEGE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=499" + }, + { + "id": "4.10.1.21", + "name": "ALTER SYSTEM ...", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=501" + }, + { + "id": "4.10.1.22", + "name": "ALTER TABLE", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=603", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.23", + "name": "ALTER USER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=670" + }, + { + "id": "4.10.1.24", + "name": "ALTER USERGROUP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=680" + }, + { + "id": "4.10.1.25", + "name": "ALTER VIEW", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=685" + }, + { + "id": "4.10.1.26", + "name": "ALTER VIRTUAL TABLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=693" + }, + { + "id": "4.10.1.27", + "name": "ALTER WORKLOAD CLASS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=695" + }, + { + "id": "4.10.1.28", + "name": "ALTER WORKLOAD MAPPING", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=699" + }, + { + "id": "4.10.1.29", + "name": "ALTER X509 PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=702" + }, + { + "id": "4.10.1.30", + "name": "ANNOTATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=703" + }, + { + "id": "4.10.1.31", + "name": "BACKUP CANCEL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=705" + }, + { + "id": "4.10.1.32", + "name": "BACKUP CATALOG DELETE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=707" + }, + { + "id": "4.10.1.33", + "name": "BACKUP CATALOG RETAINED", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=710" + }, + { + "id": "4.10.1.34", + "name": "BACKUP CHECK", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=712" + }, + { + "id": "4.10.1.35", + "name": "BACKUP CHECK ACCESS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=713" + }, + { + "id": "4.10.1.36", + "name": "BACKUP DATA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=716" + }, + { + "id": "4.10.1.37", + "name": "BACKUP DATA CLOSE SNAPSHOT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=722" + }, + { + "id": "4.10.1.38", + "name": "BACKUP DATA CREATE SNAPSHOT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=724" + }, + { + "id": "4.10.1.39", + "name": "BACKUP DATA DROP SNAPSHOT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=726" + }, + { + "id": "4.10.1.40", + "name": "BACKUP ENCRYPTION ROOT KEYS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=727" + }, + { + "id": "4.10.1.41", + "name": "BACKUP LIST DATA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=730" + }, + { + "id": "4.10.1.42", + "name": "CALL", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=733", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.43", + "name": "COMMENT ON", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=736" + }, + { + "id": "4.10.1.44", + "name": "COMMIT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=738" + }, + { + "id": "4.10.1.45", + "name": "CONNECT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=739" + }, + { + "id": "4.10.1.46", + "name": "CREATE AUDIT POLICY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=740" + }, + { + "id": "4.10.1.47", + "name": "CREATE CERTIFICATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=757" + }, + { + "id": "4.10.1.48", + "name": "CREATE CLIENTSIDE ENCRYPTION COLUMN KEY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=759" + }, + { + "id": "4.10.1.49", + "name": "CREATE CLIENTSIDE ENCRYPTION KEYPAIR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=761" + }, + { + "id": "4.10.1.50", + "name": "CREATE CREDENTIAL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=763" + }, + { + "id": "4.10.1.51", + "name": "CREATE DATABASE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=764" + }, + { + "id": "4.10.1.52", + "name": "CREATE FULLTEXT INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=767" + }, + { + "id": "4.10.1.53", + "name": "CREATE FUNCTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=770" + }, + { + "id": "4.10.1.54", + "name": "CREATE FUZZY SEARCH INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=778" + }, + { + "id": "4.10.1.55", + "name": "CREATE GRAPH WORKSPACE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=779" + }, + { + "id": "4.10.1.56", + "name": "CREATE INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=781" + }, + { + "id": "4.10.1.57", + "name": "CREATE JWT PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=786" + }, + { + "id": "4.10.1.58", + "name": "CREATE LIBRARY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=789" + }, + { + "id": "4.10.1.59", + "name": "CREATE LDAP PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=791" + }, + { + "id": "4.10.1.60", + "name": "CREATE PROCEDURE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=796" + }, + { + "id": "4.10.1.61", + "name": "CREATE PROJECTION VIEW", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=813" + }, + { + "id": "4.10.1.62", + "name": "CREATE PSE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=816" + }, + { + "id": "4.10.1.63", + "name": "CREATE PUBLIC KEY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=818" + }, + { + "id": "4.10.1.64", + "name": "CREATE REMOTE SOURCE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=819" + }, + { + "id": "4.10.1.65", + "name": "CREATE ROLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=822" + }, + { + "id": "4.10.1.66", + "name": "CREATE SAML PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=823" + }, + { + "id": "4.10.1.67", + "name": "CREATE SCHEDULER JOB", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=825" + }, + { + "id": "4.10.1.68", + "name": "CREATE SCHEMA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=827" + }, + { + "id": "4.10.1.69", + "name": "CREATE SCHEMA SYNONYM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=828" + }, + { + "id": "4.10.1.70", + "name": "CREATE SEQUENCE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=831" + }, + { + "id": "4.10.1.71", + "name": "CREATE STATISTICS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=835" + }, + { + "id": "4.10.1.72", + "name": "CREATE STRUCTURED PRIVILEGE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=842" + }, + { + "id": "4.10.1.73", + "name": "CREATE SYNONYM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=844" + }, + { + "id": "4.10.1.74", + "name": "CREATE TABLE", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=845", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.75", + "name": "CREATE TRIGGER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=898" + }, + { + "id": "4.10.1.76", + "name": "CREATE TYPE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=913" + }, + { + "id": "4.10.1.77", + "name": "CREATE USER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=915" + }, + { + "id": "4.10.1.78", + "name": "CREATE USERGROUP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=923" + }, + { + "id": "4.10.1.79", + "name": "CREATE VIEW", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=927" + }, + { + "id": "4.10.1.80", + "name": "CREATE VIRTUAL FUNCTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=939" + }, + { + "id": "4.10.1.81", + "name": "CREATE VIRTUAL PROCEDURE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=945" + }, + { + "id": "4.10.1.82", + "name": "CREATE VIRTUAL TABLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=948" + }, + { + "id": "4.10.1.83", + "name": "CREATE WORKLOAD CLASS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=951" + }, + { + "id": "4.10.1.84", + "name": "CREATE WORKLOAD MAPPING", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=956" + }, + { + "id": "4.10.1.85", + "name": "CREATE X509 PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=959" + }, + { + "id": "4.10.1.86", + "name": "DELETE", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=961", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.87", + "name": "DO BEGIN...END", + "status": "outside_scope_sqlscript_body", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=965" + }, + { + "id": "4.10.1.88", + "name": "DROP AUDIT POLICY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=969" + }, + { + "id": "4.10.1.89", + "name": "DROP CERTIFICATE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=970" + }, + { + "id": "4.10.1.90", + "name": "DROP CLIENTSIDE ENCRYPTION COLUMN KEY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=971" + }, + { + "id": "4.10.1.91", + "name": "DROP CLIENTSIDE ENCRYPTION KEYPAIR", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=972" + }, + { + "id": "4.10.1.92", + "name": "DROP COLLECTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=974" + }, + { + "id": "4.10.1.93", + "name": "DROP CREDENTIAL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=975" + }, + { + "id": "4.10.1.94", + "name": "DROP DATABASE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=977" + }, + { + "id": "4.10.1.95", + "name": "DROP FULLTEXT INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=978" + }, + { + "id": "4.10.1.96", + "name": "DROP FUNCTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=979" + }, + { + "id": "4.10.1.97", + "name": "DROP GRAPH WORKSPACE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=980" + }, + { + "id": "4.10.1.98", + "name": "DROP INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=981" + }, + { + "id": "4.10.1.99", + "name": "DROP JWT PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=982" + }, + { + "id": "4.10.1.100", + "name": "DROP LIBRARY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=983" + }, + { + "id": "4.10.1.101", + "name": "DROP LDAP PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=984" + }, + { + "id": "4.10.1.102", + "name": "DROP PROCEDURE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=985" + }, + { + "id": "4.10.1.103", + "name": "DROP PSE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=987" + }, + { + "id": "4.10.1.104", + "name": "DROP PUBLIC KEY", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=988" + }, + { + "id": "4.10.1.105", + "name": "DROP REMOTE SOURCE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=989" + }, + { + "id": "4.10.1.106", + "name": "DROP ROLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=990" + }, + { + "id": "4.10.1.107", + "name": "DROP SAML PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=991" + }, + { + "id": "4.10.1.108", + "name": "DROP SCHEDULER JOB", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=992" + }, + { + "id": "4.10.1.109", + "name": "DROP SCHEMA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=993" + }, + { + "id": "4.10.1.110", + "name": "DROP SCHEMA SYNONYM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=994" + }, + { + "id": "4.10.1.111", + "name": "DROP SEQUENCE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=996" + }, + { + "id": "4.10.1.112", + "name": "DROP STATISTICS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=997" + }, + { + "id": "4.10.1.113", + "name": "DROP STRUCTURED PRIVILEGE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1000" + }, + { + "id": "4.10.1.114", + "name": "DROP SYNONYM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1001" + }, + { + "id": "4.10.1.115", + "name": "DROP TABLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1003" + }, + { + "id": "4.10.1.116", + "name": "DROP TRIGGER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1004" + }, + { + "id": "4.10.1.117", + "name": "DROP TYPE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1006" + }, + { + "id": "4.10.1.118", + "name": "DROP USER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1007" + }, + { + "id": "4.10.1.119", + "name": "DROP USERGROUP", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1009" + }, + { + "id": "4.10.1.120", + "name": "DROP VIEW", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1010" + }, + { + "id": "4.10.1.121", + "name": "DROP WORKLOAD CLASS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1012" + }, + { + "id": "4.10.1.122", + "name": "DROP WORKLOAD MAPPING", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1013" + }, + { + "id": "4.10.1.123", + "name": "DROP X509 PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1014" + }, + { + "id": "4.10.1.124", + "name": "EXPLAIN PLAN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1015" + }, + { + "id": "4.10.1.125", + "name": "EXPORT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1020" + }, + { + "id": "4.10.1.126", + "name": "EXPORT INTO", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1031" + }, + { + "id": "4.10.1.127", + "name": "GRANT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1034" + }, + { + "id": "4.10.1.128", + "name": "IMPORT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1053" + }, + { + "id": "4.10.1.129", + "name": "IMPORT FROM", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1063" + }, + { + "id": "4.10.1.130", + "name": "IMPORT SCAN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1072" + }, + { + "id": "4.10.1.131", + "name": "INSERT", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1075", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.132", + "name": "LOAD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1080" + }, + { + "id": "4.10.1.133", + "name": "LOCK TABLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1082" + }, + { + "id": "4.10.1.134", + "name": "MERGE DELTA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1084" + }, + { + "id": "4.10.1.135", + "name": "MERGE INTO", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1086" + }, + { + "id": "4.10.1.136", + "name": "RECOVER DATA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1090" + }, + { + "id": "4.10.1.137", + "name": "RECOVER DATABASE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1096" + }, + { + "id": "4.10.1.138", + "name": "RECOVER ENCRYPTION ROOT KEYS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1105" + }, + { + "id": "4.10.1.139", + "name": "REFRESH STATISTICS", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1109" + }, + { + "id": "4.10.1.140", + "name": "REFRESH VIEW", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1113" + }, + { + "id": "4.10.1.141", + "name": "RELEASE SAVEPOINT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1114" + }, + { + "id": "4.10.1.142", + "name": "RENAME COLUMN", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1115" + }, + { + "id": "4.10.1.143", + "name": "RENAME DATABASE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1116" + }, + { + "id": "4.10.1.144", + "name": "RENAME INDEX", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1117" + }, + { + "id": "4.10.1.145", + "name": "RENAME SCHEMA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1118" + }, + { + "id": "4.10.1.146", + "name": "RENAME TABLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1120" + }, + { + "id": "4.10.1.147", + "name": "REPLACE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1123" + }, + { + "id": "4.10.1.148", + "name": "REVOKE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1124" + }, + { + "id": "4.10.1.149", + "name": "ROLLBACK", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1127" + }, + { + "id": "4.10.1.150", + "name": "ROLLBACK TO SAVEPOINT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1128" + }, + { + "id": "4.10.1.151", + "name": "SAVEPOINT", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1130" + }, + { + "id": "4.10.1.152", + "name": "SELECT", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1131", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.153", + "name": "SET HISTORY SESSION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1191" + }, + { + "id": "4.10.1.154", + "name": "SET PSE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1193" + }, + { + "id": "4.10.1.155", + "name": "SET SCHEMA", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1196" + }, + { + "id": "4.10.1.156", + "name": "SET [SESSION]", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1197" + }, + { + "id": "4.10.1.157", + "name": "SET SYSTEM LICENSE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1198" + }, + { + "id": "4.10.1.158", + "name": "SET TRANSACTION", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1199" + }, + { + "id": "4.10.1.159", + "name": "SET TRANSACTION AUTOCOMMIT DDL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1202" + }, + { + "id": "4.10.1.160", + "name": "TRUNCATE TABLE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1204" + }, + { + "id": "4.10.1.161", + "name": "UNLOAD", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1206" + }, + { + "id": "4.10.1.162", + "name": "UNSET PSE", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1208" + }, + { + "id": "4.10.1.163", + "name": "UNSET [SESSION]", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1209" + }, + { + "id": "4.10.1.164", + "name": "UNSET SYSTEM LICENSE ALL", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1210" + }, + { + "id": "4.10.1.165", + "name": "UPDATE", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1211", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.166", + "name": "UPSERT", + "status": "partially_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1218", + "tests": [ + "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", + "crates/polyglot-sql/tests/custom_fixtures/hana/" + ] + }, + { + "id": "4.10.1.167", + "name": "VALIDATE LDAP PROVIDER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1221" + }, + { + "id": "4.10.1.168", + "name": "VALIDATE USER", + "status": "not_exhaustively_implemented", + "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1224" + } +] diff --git a/packages/go/integration_test.go b/packages/go/integration_test.go index de234433..f7708159 100644 --- a/packages/go/integration_test.go +++ b/packages/go/integration_test.go @@ -1547,3 +1547,19 @@ func TestIntegrationPackageLevelAPI(t *testing.T) { } assertValidJSON(t, "OpenLineageRunEvent wrapper", runEvent.Event) } + +func TestIntegrationHana(t *testing.T) { + client := integrationClient(t) + sql := "SELECT * FROM t FOR JSON ('arraywrap' = 'NO')" + output, err := client.Transpile(sql, "hana", "hana") + if err != nil || len(output) != 1 || output[0] != sql { + t.Fatalf("HANA native round trip: %v, %v", output, err) + } + if _, err := client.Transpile(sql, "hana", "duckdb"); err == nil { + t.Fatal("expected unsupported HANA serialization error") + } + output, err = client.Transpile("SELECT LOCATE('abcabc', 'bc')", "hana", "duckdb") + if err != nil || len(output) != 1 || output[0] != "SELECT STRPOS('abcabc', 'bc')" { + t.Fatalf("HANA LOCATE: %v, %v", output, err) + } +} diff --git a/packages/playground/src/lib/constants.ts b/packages/playground/src/lib/constants.ts index a2cf9587..8cc206f9 100644 --- a/packages/playground/src/lib/constants.ts +++ b/packages/playground/src/lib/constants.ts @@ -13,6 +13,7 @@ export const DIALECT_DISPLAY_NAMES: Record = { dune: "Dune SQL", exasol: "Exasol", fabric: "Microsoft Fabric", + hana: "SAP HANA", hive: "Apache Hive", materialize: "Materialize", mysql: "MySQL", diff --git a/packages/sdk/README.md b/packages/sdk/README.md index cd98d04e..2ccaa4a5 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -1031,6 +1031,7 @@ This limit covers recursive parsing, not arbitrary programmatic AST construction | ClickHouse | `Dialect.ClickHouse` | | CockroachDB | `Dialect.CockroachDB` | | DataFusion | `Dialect.DataFusion` | +| SAP HANA | `Dialect.HANA` | | Databricks | `Dialect.Databricks` | | Doris | `Dialect.Doris` | | Dremio | `Dialect.Dremio` | diff --git a/packages/sdk/src/ast/types/guards.ts b/packages/sdk/src/ast/types/guards.ts index 41365a40..8110a601 100644 --- a/packages/sdk/src/ast/types/guards.ts +++ b/packages/sdk/src/ast/types/guards.ts @@ -178,6 +178,23 @@ export const isExists = isType('exists'); /** Type guard for generic function calls */ export const isFunction = isType('function'); +/** HANA source nodes retain dialect-specific semantics until generation. */ +export const isHanaFunction = isType('hana_function'); +export const isHanaAggregateFunction = isType('hana_aggregate_function'); +export const isHanaJson = isType('hana_json'); +export const isHanaHierarchy = isType('hana_hierarchy'); +export const isHanaUpsert = isType('hana_upsert'); +export const isHanaGrouping = isType('hana_grouping'); +export const isHanaTimezone = isType('hana_timezone'); +export const isHanaRegex = isType('hana_regex'); +export const isHanaJsonColumn = isType('hana_json_column'); +export const isHanaPartition = isType('hana_partition'); +export const isHanaStorageProperty = isType('hana_storage_property'); +export const isHanaPlaceholder = isType('hana_placeholder'); +export const isHanaTableFunction = isType('hana_table_function'); +export const isHanaCall = isType('hana_call'); +export const isHanaHint = isType('hana_hint'); + /** Type guard for aggregate function calls */ export const isAggregateFunction = isType('aggregate_function'); @@ -296,7 +313,13 @@ export const isDropView = isType('drop_view'); /** Check if expression is a DML query (SELECT, INSERT, UPDATE, DELETE) */ export function isQuery(expr: Expression): boolean { const t = getExprType(expr); - return t === 'select' || t === 'insert' || t === 'update' || t === 'delete'; + return ( + t === 'select' || + t === 'insert' || + t === 'update' || + t === 'delete' || + t === 'hana_upsert' + ); } /** Check if expression is a set operation (UNION, INTERSECT, EXCEPT) */ diff --git a/packages/sdk/src/ast/visitor/visitor.test.ts b/packages/sdk/src/ast/visitor/visitor.test.ts index cf97bd62..fc897dfb 100644 --- a/packages/sdk/src/ast/visitor/visitor.test.ts +++ b/packages/sdk/src/ast/visitor/visitor.test.ts @@ -1458,3 +1458,32 @@ describe('Integration Tests', () => { expect(regenerated.toUpperCase()).toContain('FROM'); }); }); + +describe('HANA AST traversal', () => { + it('visits and replaces arguments retained in HANA source nodes', () => { + const sql = + "SELECT LOCATE(value, 'a', 1, 2), JSON_VALUE(payload, '$.n' DEFAULT 0 ON EMPTY) FROM records"; + const ast = parseFirstWithDialect(sql, Dialect.HANA); + expect( + findAll(ast, (node) => isExpressionType(node, 'hana_function')), + ).toHaveLength(1); + expect( + findAll(ast, (node) => isExpressionType(node, 'hana_json')), + ).toHaveLength(1); + expect(getColumns(ast).map(columnReference)).toEqual(['value', 'payload']); + const copied = clone(ast); + expect(generate([copied], Dialect.HANA)).toEqual( + generate([ast], Dialect.HANA), + ); + const renamed = renameColumns(copied, { + value: 'needle_source', + payload: 'document', + }); + expect(getColumns(renamed).map(columnReference)).toEqual([ + 'needle_source', + 'document', + ]); + expect(getColumns(ast).map(columnReference)).toEqual(['value', 'payload']); + expect(generate([copied], Dialect.DuckDB).success).toBe(false); + }); +}); diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 9d556f85..94148e59 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -49,6 +49,7 @@ export enum Dialect { Dremio = 'dremio', Exasol = 'exasol', DataFusion = 'datafusion', + HANA = 'hana', } /** From 10791805aaaf147f443509a827d788ddd2bb44e8 Mon Sep 17 00:00:00 2001 From: tobilg Date: Tue, 22 Sep 2026 17:42:50 +0200 Subject: [PATCH 2/8] Refactor HANA support onto shared AST and binding APIs --- .../python/polyglot_sql/__init__.py | 40 +- .../python/polyglot_sql/__init__.pyi | 20 +- crates/polyglot-sql-python/src/expr_types.rs | 20 +- .../tests/test_expression.py | 18 +- crates/polyglot-sql/src/ast_mutation.rs | 6 +- crates/polyglot-sql/src/ast_transforms.rs | 2 +- crates/polyglot-sql/src/dialects/bigquery.rs | 11 + .../polyglot-sql/src/dialects/clickhouse.rs | 10 + .../polyglot-sql/src/dialects/databricks.rs | 2 + crates/polyglot-sql/src/dialects/duckdb.rs | 34 + crates/polyglot-sql/src/dialects/mod.rs | 113 ++- crates/polyglot-sql/src/dialects/mysql.rs | 3 + .../src/dialects/normalization/aggregates.rs | 12 + .../src/dialects/normalization/json.rs | 6 + .../src/dialects/normalization/mod.rs | 8 + .../src/dialects/normalization/scalar.rs | 54 ++ .../src/dialects/normalization/statements.rs | 2 +- crates/polyglot-sql/src/dialects/postgres.rs | 12 + crates/polyglot-sql/src/dialects/presto.rs | 10 + crates/polyglot-sql/src/dialects/redshift.rs | 4 + crates/polyglot-sql/src/dialects/snowflake.rs | 28 + crates/polyglot-sql/src/dialects/spark.rs | 4 + crates/polyglot-sql/src/dialects/trino.rs | 4 + crates/polyglot-sql/src/expressions.rs | 410 +++++---- crates/polyglot-sql/src/generator.rs | 465 ++++++---- crates/polyglot-sql/src/lineage.rs | 2 +- .../src/optimizer/annotate_types.rs | 2 +- .../src/optimizer/canonicalize.rs | 44 +- .../src/optimizer/normalize_identifiers.rs | 11 + .../src/optimizer/pushdown_projections.rs | 2 + crates/polyglot-sql/src/parser.rs | 842 +++++++++++++++--- crates/polyglot-sql/src/transforms.rs | 8 + crates/polyglot-sql/src/traversal.rs | 11 +- crates/polyglot-sql/src/validation.rs | 2 +- crates/polyglot-sql/tests/dialect_matrix.rs | 155 +++- docs/hana/README.md | 18 +- packages/go/integration_test.go | 26 + packages/sdk/plugins/wasmCjsPlugin.ts | 11 + packages/sdk/src/ast/types/guards.ts | 19 +- packages/sdk/src/ast/visitor/visitor.test.ts | 15 +- 40 files changed, 1803 insertions(+), 663 deletions(-) diff --git a/crates/polyglot-sql-python/python/polyglot_sql/__init__.py b/crates/polyglot-sql-python/python/polyglot_sql/__init__.py index e7d8a77f..5e58db5b 100644 --- a/crates/polyglot-sql-python/python/polyglot_sql/__init__.py +++ b/crates/polyglot-sql-python/python/polyglot_sql/__init__.py @@ -596,21 +596,11 @@ def dense_rank(): FromTimeZone, FromUnixtime, Function, - HanaFunction, - HanaAggregateFunction, - HanaRegex, - HanaJson, - HanaJsonColumn, - HanaUpsert, - HanaPartition, - HanaStorageProperty, - HanaHierarchy, - HanaPlaceholder, - HanaTableFunction, - HanaCall, - HanaHint, - HanaGrouping, - HanaTimezone, + Upsert, + StorageProperty, + Hierarchy, + ViewParameter, + Call, FunctionEmits, GapFill, Generate, @@ -1317,21 +1307,11 @@ def dense_rank(): "Alias", "Cast", "Function", - "HanaFunction", - "HanaAggregateFunction", - "HanaRegex", - "HanaJson", - "HanaJsonColumn", - "HanaUpsert", - "HanaPartition", - "HanaStorageProperty", - "HanaHierarchy", - "HanaPlaceholder", - "HanaTableFunction", - "HanaCall", - "HanaHint", - "HanaGrouping", - "HanaTimezone", + "Upsert", + "StorageProperty", + "Hierarchy", + "ViewParameter", + "Call", "AggregateFunction", "WindowFunction", "From", diff --git a/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi b/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi index 5c8792b8..d2c659e1 100644 --- a/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi +++ b/crates/polyglot-sql-python/python/polyglot_sql/__init__.pyi @@ -855,21 +855,11 @@ class FromBase(Expression): ... class FromTimeZone(Expression): ... class FromUnixtime(Expression): ... class Function(Expression): ... -class HanaFunction(Expression): ... -class HanaAggregateFunction(Expression): ... -class HanaRegex(Expression): ... -class HanaJson(Expression): ... -class HanaJsonColumn(Expression): ... -class HanaUpsert(Expression): ... -class HanaPartition(Expression): ... -class HanaStorageProperty(Expression): ... -class HanaHierarchy(Expression): ... -class HanaPlaceholder(Expression): ... -class HanaTableFunction(Expression): ... -class HanaCall(Expression): ... -class HanaHint(Expression): ... -class HanaGrouping(Expression): ... -class HanaTimezone(Expression): ... +class Upsert(Expression): ... +class StorageProperty(Expression): ... +class Hierarchy(Expression): ... +class ViewParameter(Expression): ... +class Call(Expression): ... class FunctionEmits(Expression): ... class GapFill(Expression): ... class Generate(Expression): ... diff --git a/crates/polyglot-sql-python/src/expr_types.rs b/crates/polyglot-sql-python/src/expr_types.rs index 6ef8dc58..b5cb040c 100644 --- a/crates/polyglot-sql-python/src/expr_types.rs +++ b/crates/polyglot-sql-python/src/expr_types.rs @@ -140,21 +140,11 @@ define_expression_subclasses!( Exists, MemberOf, Function, - HanaFunction, - HanaAggregateFunction, - HanaRegex, - HanaJson, - HanaJsonColumn, - HanaUpsert, - HanaPartition, - HanaStorageProperty, - HanaHierarchy, - HanaPlaceholder, - HanaTableFunction, - HanaCall, - HanaHint, - HanaGrouping, - HanaTimezone, + Upsert, + StorageProperty, + Hierarchy, + ViewParameter, + Call, AggregateFunction, WindowFunction, From, diff --git a/crates/polyglot-sql-python/tests/test_expression.py b/crates/polyglot-sql-python/tests/test_expression.py index 577c9ab4..9ba1357c 100644 --- a/crates/polyglot-sql-python/tests/test_expression.py +++ b/crates/polyglot-sql-python/tests/test_expression.py @@ -3,23 +3,31 @@ import polyglot_sql -def test_hana_expression_subclasses_and_accessors(): +def test_hana_uses_shared_expression_subclasses_and_accessors(): expression = polyglot_sql.parse_one( "SELECT LOCATE(value, 'a', 1, 2), JSON_VALUE(payload, '$.n') FROM records", dialect="hana", ) - locate = expression.find("hana_function") - assert isinstance(locate, polyglot_sql.HanaFunction) + locate = expression.find(polyglot_sql.Function) + assert isinstance(locate, polyglot_sql.Function) assert locate.name == "LOCATE" assert len(locate.expressions) == 4 assert isinstance(locate.expressions[0], polyglot_sql.Column) assert locate.expressions[0].name == "value" - json_value = expression.find("hana_json") - assert isinstance(json_value, polyglot_sql.HanaJson) + json_value = expression.find(polyglot_sql.JSONValue) + assert isinstance(json_value, polyglot_sql.JSONValue) assert json_value.name == "JSON_VALUE" assert json_value.this.name == "payload" +def test_quoted_functions_use_shared_class_across_dialects(): + for dialect in ("hana", "postgresql"): + expression = polyglot_sql.parse_one('SELECT "f"(x) FROM t', dialect=dialect) + function = expression.find(polyglot_sql.Function) + assert isinstance(function, polyglot_sql.Function) + assert function.name == "f" + + def test_parse_one_returns_expression_object(): expr = polyglot_sql.parse_one("SELECT a FROM t WHERE b = 1", dialect="postgres") diff --git a/crates/polyglot-sql/src/ast_mutation.rs b/crates/polyglot-sql/src/ast_mutation.rs index f9e6e6f9..9a4b8fae 100644 --- a/crates/polyglot-sql/src/ast_mutation.rs +++ b/crates/polyglot-sql/src/ast_mutation.rs @@ -91,6 +91,8 @@ pub(crate) fn binary(kind: BinaryKind, left: Expression, right: Expression) -> E inferred_type: None, })), BinaryKind::RLike => Expression::RegexpLike(Box::new(RegexpFunc { + options: None, + this: operation.left, pattern: operation.right, flags: None, @@ -429,6 +431,8 @@ pub(crate) fn append_hint(expression: &mut Expression, text: String) -> Result<( select .hint .get_or_insert_with(|| Hint { + source_dialect: None, + expressions: Vec::new(), }) .expressions @@ -454,7 +458,7 @@ pub(crate) fn create_table_as( temporary, or_replace: replace, table_modifier: None, - hana_storage: false, + source_dialect: None, as_select: Some(query), as_select_parenthesized: false, on_commit: None, diff --git a/crates/polyglot-sql/src/ast_transforms.rs b/crates/polyglot-sql/src/ast_transforms.rs index a7bbc05c..9b0b301a 100644 --- a/crates/polyglot-sql/src/ast_transforms.rs +++ b/crates/polyglot-sql/src/ast_transforms.rs @@ -473,7 +473,7 @@ pub fn get_table_names(expr: &Expression) -> Vec { names.push(name); } } - Expression::HanaUpsert(upsert) => { + Expression::Upsert(upsert) => { push_table_ref_name(&upsert.table, &cte_aliases, &mut names); } Expression::Insert(insert) => { diff --git a/crates/polyglot-sql/src/dialects/bigquery.rs b/crates/polyglot-sql/src/dialects/bigquery.rs index b3ccaa47..221bdd91 100644 --- a/crates/polyglot-sql/src/dialects/bigquery.rs +++ b/crates/polyglot-sql/src/dialects/bigquery.rs @@ -1066,6 +1066,10 @@ impl BigQueryDialect { Ok(Expression::CurrentDate(crate::expressions::CurrentDate)) } "CURRENT_DATE" => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_DATE".to_string(), args: f.args, distinct: false, @@ -1391,6 +1395,10 @@ impl BigQueryDialect { | "SAFE.PARSE_TIMESTAMP" => { let args = self.normalize_time_format_args(f.args); Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: f.name, args, distinct: f.distinct, @@ -1425,6 +1433,9 @@ impl BigQueryDialect { _ => path, }; Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path: json_path, returning: None, diff --git a/crates/polyglot-sql/src/dialects/clickhouse.rs b/crates/polyglot-sql/src/dialects/clickhouse.rs index 030cef5c..4e9ea6dd 100644 --- a/crates/polyglot-sql/src/dialects/clickhouse.rs +++ b/crates/polyglot-sql/src/dialects/clickhouse.rs @@ -601,6 +601,8 @@ impl ClickHouseDialect { // STDDEV -> stddevSamp in ClickHouse (sample stddev) "STDDEV" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "stddevSamp".to_string(), args: f.args, distinct: f.distinct, @@ -615,6 +617,8 @@ impl ClickHouseDialect { // STDDEV_POP -> stddevPop "STDDEV_POP" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "stddevPop".to_string(), args: f.args, distinct: f.distinct, @@ -629,6 +633,8 @@ impl ClickHouseDialect { // VARIANCE -> varSamp in ClickHouse "VARIANCE" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "varSamp".to_string(), args: f.args, distinct: f.distinct, @@ -643,6 +649,8 @@ impl ClickHouseDialect { // VAR_POP -> varPop "VAR_POP" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "varPop".to_string(), args: f.args, distinct: f.distinct, @@ -657,6 +665,8 @@ impl ClickHouseDialect { // MEDIAN -> median "MEDIAN" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "median".to_string(), args: f.args, distinct: f.distinct, diff --git a/crates/polyglot-sql/src/dialects/databricks.rs b/crates/polyglot-sql/src/dialects/databricks.rs index 1ae441b3..27d95f9e 100644 --- a/crates/polyglot-sql/src/dialects/databricks.rs +++ b/crates/polyglot-sql/src/dialects/databricks.rs @@ -828,6 +828,8 @@ impl DatabricksDialect { // APPROX_DISTINCT -> APPROX_COUNT_DISTINCT "APPROX_DISTINCT" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "APPROX_COUNT_DISTINCT".to_string(), args: f.args, distinct: f.distinct, diff --git a/crates/polyglot-sql/src/dialects/duckdb.rs b/crates/polyglot-sql/src/dialects/duckdb.rs index a49e5e78..02ac4c58 100644 --- a/crates/polyglot-sql/src/dialects/duckdb.rs +++ b/crates/polyglot-sql/src/dialects/duckdb.rs @@ -527,6 +527,10 @@ impl DialectImpl for DuckDBDialect { // ===== Time functions ===== // CurrentTime -> CURRENT_TIME (no parens in DuckDB) Expression::CurrentTime(_) => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_TIME".to_string(), args: vec![], distinct: false, @@ -822,6 +826,9 @@ impl DialectImpl for DuckDBDialect { other => other, }; Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this: *e.this, path, returning: None, @@ -1073,6 +1080,8 @@ impl DialectImpl for DuckDBDialect { let filter = p.filter.clone(); Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "QUANTILE_CONT".to_string(), args: vec![column, percentile], distinct: false, @@ -1094,6 +1103,8 @@ impl DialectImpl for DuckDBDialect { let filter = p.filter.clone(); Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "QUANTILE_DISC".to_string(), args: vec![column, percentile], distinct: false, @@ -1119,6 +1130,8 @@ impl DialectImpl for DuckDBDialect { match (column, quantile) { (Some(col), Some(q)) => Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: new_name.to_string(), args: vec![col, q], distinct: false, @@ -2098,6 +2111,9 @@ impl DuckDBDialect { let path = args.pop().unwrap(); let this = args.pop().unwrap(); Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path, returning: None, @@ -2116,6 +2132,9 @@ impl DuckDBDialect { let path = args.pop().unwrap(); let this = args.pop().unwrap(); Ok(Expression::JsonExtractScalar(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path, returning: None, @@ -2337,6 +2356,9 @@ impl DuckDBDialect { let this = args.remove(0); let path = args.remove(0); Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path, returning: None, @@ -2355,6 +2377,9 @@ impl DuckDBDialect { let this = args.remove(0); let path = args.remove(0); Ok(Expression::JsonExtractScalar(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path, returning: None, @@ -4333,6 +4358,9 @@ impl DuckDBDialect { }; let json_path = format!("$.{}", s); Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path: Expression::Literal(Box::new(Literal::String(json_path))), returning: None, @@ -4364,6 +4392,9 @@ impl DuckDBDialect { _ => { // Unknown key type - use JSON arrow Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path: Expression::JSONPath(Box::new(JSONPath { expressions: vec![ @@ -4412,6 +4443,9 @@ impl DuckDBDialect { _ => path, }; Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path: json_path, returning: None, diff --git a/crates/polyglot-sql/src/dialects/mod.rs b/crates/polyglot-sql/src/dialects/mod.rs index c8f7b8bd..a08f3568 100644 --- a/crates/polyglot-sql/src/dialects/mod.rs +++ b/crates/polyglot-sql/src/dialects/mod.rs @@ -208,6 +208,7 @@ use std::sync::{Arc, LazyLock, RwLock}; /// Dialect names are case-insensitive when parsed from strings via [`FromStr`]. /// Some dialects accept aliases (e.g., "mssql" and "sqlserver" both resolve to [`TSQL`](DialectType::TSQL)). #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "bindings", derive(ts_rs::TS))] #[serde(rename_all = "lowercase")] pub enum DialectType { /// Standard SQL with no dialect-specific behavior (default). @@ -696,7 +697,7 @@ where // semantics even though all physical children are visible to traversal APIs. fn uses_generated_dispatch(expression: &Expression) -> bool { match expression { - Expression::CreateTable(create) if create.hana_storage => true, + Expression::CreateTable(_) => true, Expression::Select(select) => { select.joins.is_empty() && select.with.is_none() @@ -756,20 +757,25 @@ where | Expression::Like(_) | Expression::ILike(_) | Expression::Function(_) - | Expression::HanaFunction(_) - | Expression::HanaAggregateFunction(_) - | Expression::HanaRegex(_) - | Expression::HanaJson(_) - | Expression::HanaJsonColumn(_) - | Expression::HanaPartition(_) - | Expression::HanaStorageProperty(_) - | Expression::HanaHierarchy(_) - | Expression::HanaPlaceholder(_) - | Expression::HanaTableFunction(_) - | Expression::HanaCall(_) - | Expression::HanaHint(_) - | Expression::HanaGrouping(_) - | Expression::HanaTimezone(_) + | Expression::AggregateFunction(_) + | Expression::JSONValue(_) + | Expression::JSONTable(_) + | Expression::JSONColumnDef(_) + | Expression::JsonQuery(_) + | Expression::RegexpLike(_) + | Expression::RegexpReplace(_) + | Expression::RegexpExtract(_) + | Expression::RegexpInstr(_) + | Expression::RegexpCount(_) + | Expression::Cube(_) + | Expression::Rollup(_) + | Expression::GroupingSets(_) + | Expression::Hint(_) + | Expression::PartitionByProperty(_) + | Expression::StorageProperty(_) + | Expression::Hierarchy(_) + | Expression::ViewParameter(_) + | Expression::Call(_) | Expression::Lead(_) | Expression::Lag(_) | Expression::Array(_) @@ -1071,12 +1077,10 @@ where // First recursively transform children, then apply the transform function let expr = match expr { Expression::Select(mut select) => { - if let Some(options) = &mut select.hana_options { - options.hints = std::mem::take(&mut options.hints) - .into_iter() - .map(|hint| transform_recursive(hint, transform_fn)) - .collect::>>()?; - } + select.query_hints = std::mem::take(&mut select.query_hints) + .into_iter() + .map(|hint| transform_recursive(hint, transform_fn)) + .collect::>>()?; select.expressions = select .expressions .into_iter() @@ -2027,7 +2031,7 @@ where Expression::UnixToTime(e) } - Expression::HanaUpsert(mut upsert) => { + Expression::Upsert(mut upsert) => { upsert.table = transform_table_ref_recursive(upsert.table, transform_fn)?; upsert.source = transform_recursive(upsert.source, transform_fn)?; if let Some(partition) = upsert.partition.take() { @@ -2036,7 +2040,7 @@ where if let Some(condition) = upsert.condition.take() { upsert.condition = Some(transform_recursive(condition, transform_fn)?); } - Expression::HanaUpsert(upsert) + Expression::Upsert(upsert) } // CreateTable: recurse into column defaults, on_update expressions, and data types @@ -3226,7 +3230,17 @@ impl Dialect { // Apply preprocessing transforms based on dialect let preprocessed = self.preprocess(expr)?; // Then apply recursive transformation - transform_recursive(preprocessed, &self.transformer) + transform_recursive(preprocessed, &|node| { + // Calls with retained source semantics are lowered by the generator; + // ordinary AST visitors and optimizer passes still see their shared node kind. + if node.source_dialect().is_some() + || matches!(&node, Expression::Function(f) if !f.qualified_name.is_empty()) + { + Ok(node) + } else { + (self.transformer)(node) + } + }) } /// Apply dialect-specific preprocessing transforms @@ -3509,44 +3523,17 @@ impl Dialect { expressions .into_iter() .map(|expr| { - // Validate source-specific HANA semantics before target transforms - // can erase a cast or rebuild a SELECT without its native clauses. - // The same generator checks protect standalone AST generation. - if self.dialect_type == DialectType::HANA && target != DialectType::HANA { - for node in expr.dfs() { - let protected = match node { - Expression::HanaFunction(_) - | Expression::HanaAggregateFunction(_) - | Expression::HanaRegex(_) - | Expression::HanaJson(_) - | Expression::HanaJsonColumn(_) - | Expression::HanaUpsert(_) - | Expression::HanaPartition(_) - | Expression::HanaHierarchy(_) - | Expression::HanaGrouping(_) - | Expression::HanaTimezone(_) - | Expression::HanaPlaceholder(_) - | Expression::HanaTableFunction(_) - | Expression::HanaCall(_) - | Expression::HanaHint(_) - | Expression::HanaStorageProperty(_) - | Expression::CreateTable(_) - | Expression::AlterTable(_) => true, - Expression::Cast(c) => matches!(c.to, DataType::Hana { .. }), - Expression::Select(s) => { - s.hana_options.is_some() || s.locks.iter().any(|l| l.ignore_locked) - } - Expression::DataType(DataType::Hana { .. }) => true, - _ => false, - }; - if protected { - target_dialect.generate_with_transpile_options( - node, - self.dialect_type, - opts, - )?; + // Validate source-bound semantics before normalization can erase them. + // Generating each outermost protected subtree checks its descendants too. + let mut pending = vec![&expr]; + while let Some(node) = pending.pop() { + if let Some(source) = node.source_dialect() { + if source != target { + target_dialect.generate_with_transpile_options(node, source, opts)?; + continue; } } + crate::ast_children::for_each_child(node, |_, child| pending.push(child)); } // DuckDB source: normalize VARCHAR/CHAR to TEXT (DuckDB doesn't support @@ -3692,6 +3679,10 @@ impl Dialect { )); return Ok(Expression::Function(Box::new( crate::expressions::Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: f.name.clone(), args: new_args, distinct: f.distinct, @@ -4063,6 +4054,8 @@ impl Dialect { }; Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "COUNT_BIG".to_string(), args, distinct: c.distinct, diff --git a/crates/polyglot-sql/src/dialects/mysql.rs b/crates/polyglot-sql/src/dialects/mysql.rs index 7a58c82e..f944281f 100644 --- a/crates/polyglot-sql/src/dialects/mysql.rs +++ b/crates/polyglot-sql/src/dialects/mysql.rs @@ -1246,6 +1246,9 @@ impl MySQLDialect { _ => path, }; Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path: json_path, returning: None, diff --git a/crates/polyglot-sql/src/dialects/normalization/aggregates.rs b/crates/polyglot-sql/src/dialects/normalization/aggregates.rs index ed93f23a..f093a4eb 100644 --- a/crates/polyglot-sql/src/dialects/normalization/aggregates.rs +++ b/crates/polyglot-sql/src/dialects/normalization/aggregates.rs @@ -99,6 +99,8 @@ pub(super) fn rewrite( } Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "medianExactWeightedInterpolatedOrNull".to_string(), args: vec![input, Expression::number(1)], distinct: false, @@ -193,6 +195,8 @@ pub(super) fn rewrite( "ARG_MIN_NULL" }; Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: func_name.to_string(), args: vec![agg.this, *having_expr], distinct: agg.distinct, @@ -741,6 +745,8 @@ pub(super) fn rewrite( let preserves_order = agg.limit.is_some(); Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "COLLECT_LIST".to_string(), args: vec![agg.this.clone()], distinct: agg.distinct, @@ -1101,6 +1107,8 @@ pub(super) fn rewrite( match target { DialectType::Presto => Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "SET_AGG".to_string(), args: f.args, distinct: false, @@ -1113,6 +1121,8 @@ pub(super) fn rewrite( ))), DialectType::Snowflake => Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "ARRAY_UNIQUE_AGG".to_string(), args: f.args, distinct: false, @@ -1158,6 +1168,8 @@ pub(super) fn rewrite( }; Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: name.to_string(), args: f.args, distinct: f.distinct, diff --git a/crates/polyglot-sql/src/dialects/normalization/json.rs b/crates/polyglot-sql/src/dialects/normalization/json.rs index 2205e9e6..a209f0a5 100644 --- a/crates/polyglot-sql/src/dialects/normalization/json.rs +++ b/crates/polyglot-sql/src/dialects/normalization/json.rs @@ -197,6 +197,9 @@ pub(super) fn rewrite( // json -> path arrow syntax Ok(Expression::JsonExtract(Box::new( crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this: f.this, path: f.path, returning: f.returning, @@ -733,6 +736,9 @@ pub(super) fn rewrite( // JSON_EXTRACT_SCALAR(x, '$.path') -> x ->> '$.path' Ok(Expression::JsonExtractScalar(Box::new( crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this: f.this, path: f.path, returning: f.returning, diff --git a/crates/polyglot-sql/src/dialects/normalization/mod.rs b/crates/polyglot-sql/src/dialects/normalization/mod.rs index 1ca6eb0e..246710d3 100644 --- a/crates/polyglot-sql/src/dialects/normalization/mod.rs +++ b/crates/polyglot-sql/src/dialects/normalization/mod.rs @@ -86,6 +86,14 @@ pub(super) fn normalize( let expr = statements::normalize_root(expr, &context); transform_recursive(expr, &|e| { + // Source-bound nodes share the ordinary AST categories, but their lowering + // must retain the semantics recorded by the parser through serialization. + if e.source_dialect().is_some() + || matches!(&e, Expression::Function(f) if !f.qualified_name.is_empty()) + { + return Ok(e); + } + if matches!(source, DialectType::DataFusion) && matches!(target, DialectType::DuckDB) { if let Expression::Function(ref function) = e { if function.name.eq_ignore_ascii_case("NOW") && function.args.is_empty() { diff --git a/crates/polyglot-sql/src/dialects/normalization/scalar.rs b/crates/polyglot-sql/src/dialects/normalization/scalar.rs index ac339d69..1aa176e8 100644 --- a/crates/polyglot-sql/src/dialects/normalization/scalar.rs +++ b/crates/polyglot-sql/src/dialects/normalization/scalar.rs @@ -374,6 +374,8 @@ pub(super) fn rewrite( }; Ok(Expression::RegexpLike(Box::new( crate::expressions::RegexpFunc { + options: None, + this, pattern, flags, @@ -396,6 +398,8 @@ pub(super) fn rewrite( }; Ok(Expression::RegexpLike(Box::new( crate::expressions::RegexpFunc { + options: None, + this, pattern, flags, @@ -1395,6 +1399,9 @@ pub(super) fn rewrite( if is_text { Ok(Expression::JsonExtractScalar(Box::new( crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this: json_expr, path: Expression::string(&json_path), returning: None, @@ -1409,6 +1416,9 @@ pub(super) fn rewrite( } else { Ok(Expression::JsonExtract(Box::new( crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this: json_expr, path: Expression::string(&json_path), returning: None, @@ -1554,6 +1564,8 @@ pub(super) fn rewrite( // Convert to RegexpLike which generates as RLIKE/~/REGEXP_LIKE per dialect Ok(Expression::RegexpLike(Box::new( crate::expressions::RegexpFunc { + options: None, + this: str_expr, pattern, flags: None, @@ -2427,6 +2439,9 @@ pub(super) fn rewrite( let path = args.remove(0); Ok(Expression::JsonExtract(Box::new( crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this: json_expr, path, returning: None, @@ -2570,6 +2585,10 @@ pub(super) fn rewrite( // ARRAY_SUM(lambda, array) from Doris -> ClickHouse arraySum "ARRAY_SUM" if matches!(target, DialectType::ClickHouse) => { Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "arraySum".to_string(), args: f.args, distinct: f.distinct, @@ -3473,6 +3492,8 @@ pub(super) fn rewrite( { operators::snowflake_regexp_like_to_clickhouse( crate::expressions::RegexpFunc { + options: None, + this: str_expr, pattern, flags, @@ -3503,6 +3524,8 @@ pub(super) fn rewrite( } _ => Ok(Expression::RegexpLike(Box::new( crate::expressions::RegexpFunc { + options: None, + this: str_expr, pattern, flags, @@ -6975,6 +6998,9 @@ pub(super) fn rewrite( let this = args.remove(0); Ok(Expression::JsonExtract(Box::new( crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this, path, returning: None, @@ -9602,6 +9628,10 @@ pub(super) fn rewrite( DialectType::PostgreSQL => { // PostgreSQL: CURRENT_SCHEMA (no parens) Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_SCHEMA".to_string(), args: vec![], distinct: false, @@ -10993,6 +11023,8 @@ pub(super) fn rewrite( } Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "JSON_AGG".to_string(), args: vec![*ja.this], distinct: false, @@ -11761,6 +11793,8 @@ pub(super) fn rewrite( Ok(Expression::Paren(Box::new(Paren { this: Expression::RegexpLike(Box::new( crate::expressions::RegexpFunc { + options: None, + this: arg, pattern: Expression::Literal(Box::new(Literal::String( "^[[:ascii:]]*$".to_string(), @@ -14613,6 +14647,8 @@ pub(super) fn normalize_bigquery_function( let pattern = args.remove(0); Ok(Expression::RegexpLike(Box::new( crate::expressions::RegexpFunc { + options: None, + this: str_expr, pattern, flags: None, @@ -16466,6 +16502,9 @@ pub(super) fn normalize_bigquery_function( let path = args.remove(0); Ok(Expression::JsonExtract(Box::new( crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this: json_expr, path, returning: None, @@ -16503,6 +16542,9 @@ pub(super) fn normalize_bigquery_function( let path = args.remove(0); let arrow = Expression::JsonExtract(Box::new(crate::expressions::JsonExtractFunc { + options: None, + source_dialect: None, + this: json_expr, path, returning: None, @@ -16663,6 +16705,10 @@ pub(super) fn normalize_bigquery_function( } } else { Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: f.name, args, distinct: f.distinct, @@ -16686,6 +16732,10 @@ pub(super) fn normalize_bigquery_function( // For other targets (Hive/Spark/BigQuery): pass through as-is // BigQuery's default group behavior matches Hive/Spark for 2-arg case Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: f.name, args, distinct: f.distinct, @@ -17068,6 +17118,10 @@ pub(super) fn normalize_bigquery_function( // All others: pass through _ => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: f.name, args, distinct: f.distinct, diff --git a/crates/polyglot-sql/src/dialects/normalization/statements.rs b/crates/polyglot-sql/src/dialects/normalization/statements.rs index 6a8a2115..2da07bb8 100644 --- a/crates/polyglot-sql/src/dialects/normalization/statements.rs +++ b/crates/polyglot-sql/src/dialects/normalization/statements.rs @@ -908,7 +908,7 @@ pub(super) fn transform_select_into( temporary: is_temp, or_replace: false, table_modifier: None, - hana_storage: false, + source_dialect: None, as_select: Some(Expression::Select(new_select)), as_select_parenthesized: false, on_commit: None, diff --git a/crates/polyglot-sql/src/dialects/postgres.rs b/crates/polyglot-sql/src/dialects/postgres.rs index 62e7a623..a679ee58 100644 --- a/crates/polyglot-sql/src/dialects/postgres.rs +++ b/crates/polyglot-sql/src/dialects/postgres.rs @@ -268,6 +268,8 @@ impl DialectImpl for PostgresDialect { // LogicalAnd -> BOOL_AND Expression::LogicalAnd(f) => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "BOOL_AND".to_string(), args: vec![f.this], distinct: f.distinct, @@ -282,6 +284,8 @@ impl DialectImpl for PostgresDialect { // LogicalOr -> BOOL_OR Expression::LogicalOr(f) => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "BOOL_OR".to_string(), args: vec![f.this], distinct: f.distinct, @@ -806,6 +810,10 @@ impl DialectImpl for PostgresDialect { // ============================================ // CurrentTimestamp -> CURRENT_TIMESTAMP (no parens) Expression::CurrentTimestamp(_) => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_TIMESTAMP".to_string(), args: vec![], distinct: false, @@ -825,6 +833,10 @@ impl DialectImpl for PostgresDialect { // CurrentDate -> CURRENT_DATE (no parens) Expression::CurrentDate(_) => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_DATE".to_string(), args: vec![], distinct: false, diff --git a/crates/polyglot-sql/src/dialects/presto.rs b/crates/polyglot-sql/src/dialects/presto.rs index 43057a20..183e1901 100644 --- a/crates/polyglot-sql/src/dialects/presto.rs +++ b/crates/polyglot-sql/src/dialects/presto.rs @@ -180,6 +180,9 @@ impl DialectImpl for PrestoDialect { other => other, }; Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this: *e.this, path, returning: None, @@ -802,6 +805,9 @@ impl PrestoDialect { _ => path, }; Ok(Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this, path: json_path, returning: None, @@ -1021,6 +1027,8 @@ impl PrestoDialect { // VAR -> VAR_POP in Presto "VAR" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "VAR_POP".to_string(), args: f.args, distinct: f.distinct, @@ -1035,6 +1043,8 @@ impl PrestoDialect { // VARIANCE -> VAR_SAMP in Presto (for sample variance) "VARIANCE" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "VAR_SAMP".to_string(), args: f.args, distinct: f.distinct, diff --git a/crates/polyglot-sql/src/dialects/redshift.rs b/crates/polyglot-sql/src/dialects/redshift.rs index 388ed8fe..1cbca572 100644 --- a/crates/polyglot-sql/src/dialects/redshift.rs +++ b/crates/polyglot-sql/src/dialects/redshift.rs @@ -369,6 +369,8 @@ impl RedshiftDialect { let string = args.remove(0); let pattern = args.remove(0); Ok(Expression::RegexpLike(Box::new(RegexpFunc { + options: None, + this: string, pattern, flags: None, @@ -381,6 +383,8 @@ impl RedshiftDialect { let string = args.remove(0); let pattern = args.remove(0); Ok(Expression::RegexpLike(Box::new(RegexpFunc { + options: None, + this: string, pattern, flags: None, diff --git a/crates/polyglot-sql/src/dialects/snowflake.rs b/crates/polyglot-sql/src/dialects/snowflake.rs index 7deabe77..8f8f971a 100644 --- a/crates/polyglot-sql/src/dialects/snowflake.rs +++ b/crates/polyglot-sql/src/dialects/snowflake.rs @@ -1727,6 +1727,10 @@ impl SnowflakeDialect { .collect::>>()?; let f = Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: f.name, args: transformed_args, distinct: f.distinct, @@ -1790,6 +1794,10 @@ impl SnowflakeDialect { // NOW -> CURRENT_TIMESTAMP (preserving parens style) "NOW" => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_TIMESTAMP".to_string(), args: f.args, distinct: false, @@ -1803,6 +1811,10 @@ impl SnowflakeDialect { // GETDATE -> CURRENT_TIMESTAMP (preserving parens style) "GETDATE" => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_TIMESTAMP".to_string(), args: f.args, distinct: false, @@ -1819,6 +1831,10 @@ impl SnowflakeDialect { // but explicit CURRENT_TIMESTAMP calls should have parens "CURRENT_TIMESTAMP" if f.args.is_empty() => { Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_TIMESTAMP".to_string(), args: Vec::new(), distinct: false, @@ -2463,6 +2479,8 @@ impl SnowflakeDialect { let flags = args.next(); Ok(Expression::RegexpLike(Box::new( crate::expressions::RegexpFunc { + options: None, + this: left, pattern, flags, @@ -2761,6 +2779,10 @@ impl SnowflakeDialect { // SYSTIMESTAMP -> CURRENT_TIMESTAMP (preserving parens style) "SYSTIMESTAMP" => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_TIMESTAMP".to_string(), args: f.args, distinct: false, @@ -2774,6 +2796,10 @@ impl SnowflakeDialect { // LOCALTIMESTAMP -> CURRENT_TIMESTAMP (preserving parens style) "LOCALTIMESTAMP" => Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CURRENT_TIMESTAMP".to_string(), args: f.args, distinct: false, @@ -3847,6 +3873,8 @@ impl SnowflakeDialect { args.push(Expression::number(1)); Ok(Expression::AggregateFunction(Box::new( crate::expressions::AggregateFunction { + source_dialect: None, + name: "APPROX_TOP_K".to_string(), args, distinct: f.distinct, diff --git a/crates/polyglot-sql/src/dialects/spark.rs b/crates/polyglot-sql/src/dialects/spark.rs index cc71694c..6563a532 100644 --- a/crates/polyglot-sql/src/dialects/spark.rs +++ b/crates/polyglot-sql/src/dialects/spark.rs @@ -659,6 +659,10 @@ impl SparkDialect { }) .collect(); Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "STRUCT".to_string(), args: named_args, distinct: false, diff --git a/crates/polyglot-sql/src/dialects/trino.rs b/crates/polyglot-sql/src/dialects/trino.rs index 8eb0b5bb..63d22e77 100644 --- a/crates/polyglot-sql/src/dialects/trino.rs +++ b/crates/polyglot-sql/src/dialects/trino.rs @@ -472,6 +472,8 @@ impl TrinoDialect { // VAR -> VAR_POP in Trino "VAR" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "VAR_POP".to_string(), args: f.args, distinct: f.distinct, @@ -486,6 +488,8 @@ impl TrinoDialect { // VARIANCE -> VAR_SAMP in Trino "VARIANCE" if !f.args.is_empty() => { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "VAR_SAMP".to_string(), args: f.args, distinct: f.distinct, diff --git a/crates/polyglot-sql/src/expressions.rs b/crates/polyglot-sql/src/expressions.rs index 965162e1..d45ddfec 100644 --- a/crates/polyglot-sql/src/expressions.rs +++ b/crates/polyglot-sql/src/expressions.rs @@ -177,22 +177,13 @@ pub enum Expression { // Functions Function(Box), - /// A SAP HANA built-in retaining source semantics for independent generation. - HanaFunction(Box), - HanaAggregateFunction(Box), - HanaRegex(Box), - HanaJson(Box), - HanaJsonColumn(Box), - HanaUpsert(Box), - HanaPartition(Box), - HanaStorageProperty(Box), - HanaHierarchy(Box), - HanaPlaceholder(Box), - HanaTableFunction(Box), - HanaCall(Box), - HanaHint(Box), - HanaGrouping(Box), - HanaTimezone(Box), + + Upsert(Box), + StorageProperty(Box), + Hierarchy(Box), + ViewParameter(Box), + Call(Box), + AggregateFunction(Box), WindowFunction(Box), @@ -1131,6 +1122,42 @@ pub enum Expression { } impl Expression { + /// Source semantics that still require dialect-aware lowering. This metadata + /// survives JSON serialization and never changes generic traversal behavior. + pub fn source_dialect(&self) -> Option { + use crate::dialects::DialectType; + match self { + Self::Function(f) => f.source_dialect, + Self::AggregateFunction(f) => f.source_dialect, + Self::Select(s) => s.source_dialect, + Self::CreateTable(t) => t.source_dialect, + Self::Upsert(u) => u.source_dialect, + Self::Call(c) => c.source_dialect, + Self::Hierarchy(h) => h.source_dialect, + Self::ViewParameter(p) => p.source_dialect, + Self::StorageProperty(p) => p.source_dialect, + Self::Hint(h) => h.source_dialect, + Self::JSONValue(j) => j.source_dialect, + Self::JSONTable(j) => j.source_dialect, + Self::JSONColumnDef(j) => j.source_dialect, + Self::JsonQuery(j) | Self::JsonExtract(j) | Self::JsonExtractScalar(j) => { + j.source_dialect + } + Self::RegexpLike(r) => r.options.as_ref().and_then(|o| o.source_dialect), + Self::RegexpReplace(r) => r.options.as_ref().and_then(|o| o.source_dialect), + Self::RegexpExtract(r) => r.options.as_ref().and_then(|o| o.source_dialect), + Self::RegexpInstr(r) => r.options.as_ref().and_then(|o| o.source_dialect), + Self::RegexpCount(r) => r.options.as_ref().and_then(|o| o.source_dialect), + Self::Cube(g) => g.options.as_ref().and_then(|o| o.source_dialect), + Self::Rollup(g) => g.options.as_ref().and_then(|o| o.source_dialect), + Self::GroupingSets(g) => g.options.as_ref().and_then(|o| o.source_dialect), + Self::PartitionByProperty(p) => p.specification.as_ref().and_then(|s| s.source_dialect), + Self::DataType(DataType::Hana { .. }) => Some(DialectType::HANA), + Self::Cast(c) if matches!(c.to, DataType::Hana { .. }) => Some(DialectType::HANA), + _ => None, + } + } + /// Create a `Column` variant, boxing the value automatically. #[inline] pub fn boxed_column(col: Column) -> Self { @@ -1161,8 +1188,8 @@ impl Expression { | Expression::PipeOperator(_) // DML - | Expression::HanaUpsert(_) - | Expression::HanaCall(_) + | Expression::Upsert(_) + | Expression::Call(_) | Expression::Insert(_) | Expression::Update(_) | Expression::Delete(_) @@ -1337,10 +1364,8 @@ impl Expression { Expression::Column(c) => c.inferred_type.as_ref(), Expression::Dot(dot) => dot.inferred_type.as_ref(), - Expression::Function(f) | Expression::HanaFunction(f) => f.inferred_type.as_ref(), - Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => { - f.inferred_type.as_ref() - } + Expression::Function(f) => f.inferred_type.as_ref(), + Expression::AggregateFunction(f) => f.inferred_type.as_ref(), Expression::WindowFunction(f) => f.inferred_type.as_ref(), Expression::Case(c) => c.inferred_type.as_ref(), Expression::Array(a) => a.inferred_type.as_ref(), @@ -1573,10 +1598,8 @@ impl Expression { Expression::Column(c) => c.inferred_type = Some(dt), Expression::Dot(dot) => dot.inferred_type = Some(dt), - Expression::Function(f) | Expression::HanaFunction(f) => f.inferred_type = Some(dt), - Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => { - f.inferred_type = Some(dt) - } + Expression::Function(f) => f.inferred_type = Some(dt), + Expression::AggregateFunction(f) => f.inferred_type = Some(dt), Expression::WindowFunction(f) => f.inferred_type = Some(dt), Expression::Case(c) => c.inferred_type = Some(dt), Expression::Array(a) => a.inferred_type = Some(dt), @@ -1939,21 +1962,11 @@ impl Expression { Expression::Exists(_) => "exists", Expression::MemberOf(_) => "member_of", Expression::Function(_) => "function", - Expression::HanaFunction(_) => "hana_function", - Expression::HanaAggregateFunction(_) => "hana_aggregate_function", - Expression::HanaRegex(_) => "hana_regex", - Expression::HanaJson(_) => "hana_json", - Expression::HanaJsonColumn(_) => "hana_json_column", - Expression::HanaUpsert(_) => "hana_upsert", - Expression::HanaPartition(_) => "hana_partition", - Expression::HanaStorageProperty(_) => "hana_storage_property", - Expression::HanaHierarchy(_) => "hana_hierarchy", - Expression::HanaGrouping(_) => "hana_grouping", - Expression::HanaTimezone(_) => "hana_timezone", - Expression::HanaPlaceholder(_) => "hana_placeholder", - Expression::HanaTableFunction(_) => "hana_table_function", - Expression::HanaCall(_) => "hana_call", - Expression::HanaHint(_) => "hana_hint", + Expression::Upsert(_) => "upsert", + Expression::StorageProperty(_) => "storage_property", + Expression::Hierarchy(_) => "hierarchy", + Expression::ViewParameter(_) => "view_parameter", + Expression::Call(_) => "call", Expression::AggregateFunction(_) => "aggregate_function", Expression::WindowFunction(_) => "window_function", Expression::From(_) => "from", @@ -2814,10 +2827,11 @@ impl Expression { /// Returns the primary child expression (".this" in sqlglot). pub fn get_this(&self) -> Option<&Expression> { match self { - Expression::HanaJson(json) => Some(&json.input), - Expression::HanaRegex(regex) => Some(®ex.subject), - Expression::HanaHierarchy(hierarchy) => Some(&hierarchy.source), - Expression::HanaUpsert(upsert) => Some(&upsert.source), + Expression::JSONValue(j) => Some(&j.this), + Expression::JSONTable(j) => Some(&j.this), + Expression::JSONColumnDef(j) => j.this.as_deref(), + Expression::Hierarchy(hierarchy) => Some(&hierarchy.source), + Expression::Upsert(upsert) => Some(&upsert.source), // Unary ops Expression::Not(u) | Expression::Neg(u) | Expression::BitwiseNot(u) => Some(&u.this), // UnaryFunc variants @@ -3109,14 +3123,9 @@ impl Expression { pub fn get_expressions(&self) -> &[Expression] { match self { Expression::Select(s) => &s.expressions, - Expression::Function(f) | Expression::HanaFunction(f) => &f.args, - Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => &f.args, - Expression::HanaTimezone(f) => &f.arguments, - Expression::HanaTableFunction(f) => &f.arguments, - Expression::HanaCall(f) => &f.arguments, - Expression::HanaGrouping(g) => &g.expressions, - Expression::HanaJson(j) => &j.columns, - Expression::HanaJsonColumn(c) => &c.columns, + Expression::Function(f) => &f.args, + Expression::AggregateFunction(f) => &f.args, + Expression::Call(f) => &f.arguments, Expression::From(f) => &f.expressions, Expression::GroupBy(g) => &g.expressions, Expression::In(i) => &i.expressions, @@ -3138,17 +3147,17 @@ impl Expression { /// Returns the name of this expression as a string slice. pub fn get_name(&self) -> &str { match self { + Expression::JSONValue(_) => "JSON_VALUE", + Expression::JSONTable(_) => "JSON_TABLE", + Expression::JsonQuery(_) => "JSON_QUERY", Expression::Identifier(id) => &id.name, Expression::Column(col) => &col.name.name, Expression::Table(t) => &t.name.name, Expression::Literal(lit) => lit.value_str(), Expression::Star(_) => "*", - Expression::Function(f) | Expression::HanaFunction(f) => &f.name, - Expression::AggregateFunction(f) | Expression::HanaAggregateFunction(f) => &f.name, - Expression::HanaTimezone(f) => &f.name, - Expression::HanaJson(j) => &j.name, - Expression::HanaHierarchy(h) => &h.name, - Expression::HanaRegex(r) => &r.operation, + Expression::Function(f) => &f.name, + Expression::AggregateFunction(f) => &f.name, + Expression::Hierarchy(h) => &h.name, Expression::Alias(a) => a.this.get_name(), Expression::Boolean(b) => { if b.value { @@ -3216,9 +3225,7 @@ impl Expression { | Expression::BitwiseXor(op) => { op.trailing_comments.iter().map(|s| s.as_str()).collect() } - Expression::Function(f) | Expression::HanaFunction(f) => { - f.trailing_comments.iter().map(|s| s.as_str()).collect() - } + Expression::Function(f) => f.trailing_comments.iter().map(|s| s.as_str()).collect(), Expression::Subquery(s) => s.trailing_comments.iter().map(|s| s.as_str()).collect(), _ => Vec::new(), } @@ -3746,9 +3753,18 @@ pub struct Select { /// T-SQL FOR JSON clause options (PATH, AUTO, ROOT, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER) #[serde(default, skip_serializing_if = "Vec::is_empty")] pub for_json: Vec, - /// HANA result serialization and trailing query hints. + /// Structured result serialization, including a bare FOR JSON/XML clause. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub result_serialization: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub hana_options: Option, + pub query_collation: Option, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub query_hints: Vec, + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + pub total_rowcount: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, /// Leading comments before the statement #[serde(default)] pub leading_comments: Vec, @@ -3808,7 +3824,11 @@ impl Select { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), - hana_options: None, + result_serialization: None, + query_collation: None, + query_hints: Vec::new(), + total_rowcount: false, + source_dialect: None, leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, @@ -4944,7 +4964,12 @@ pub struct Exists { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaUpsert { +pub struct Upsert { + /// Retained source semantics; serialized independently of generator configuration. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + pub table: TableRef, pub partition: Option, pub columns: Vec, @@ -4955,19 +4980,24 @@ pub struct HanaUpsert { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaPartition { +pub struct PartitionSpec { + /// Retained source semantics; serialized independently of generator configuration. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + pub method: String, pub columns: Vec, pub partitions: Option, - pub ranges: Vec, + pub ranges: Vec, pub primary_key_check: Option, pub properties: Vec, - pub subpartition: Option>, + pub subpartition: Option>, } #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaPartitionRange { +pub struct PartitionRangeSpec { pub name: Option, pub kind: String, pub values: Vec, @@ -4980,14 +5010,24 @@ pub struct HanaPartitionRange { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaStorageProperty { +pub struct StorageProperty { + /// Retained source semantics; serialized independently of generator configuration. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + pub name: String, pub values: Vec, } #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaHierarchy { +pub struct Hierarchy { + /// Retained source semantics; serialized independently of generator configuration. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + pub name: String, pub source: Expression, pub start: Option, @@ -5001,66 +5041,43 @@ pub struct HanaHierarchy { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaPlaceholder { +pub struct ViewParameter { + /// Retained source semantics; serialized independently of generator configuration. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + pub name: Identifier, pub value: Expression, } -/// Qualified HANA table/calculation-view call; identifier quoting is structural. -#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaTableFunction { - pub name: Vec, - pub arguments: Vec, -} - -/// HANA JSON path operations retain default and error behavior across AST serialization. -#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaJson { - pub name: String, - pub input: Expression, - pub path: Expression, - pub columns: Vec, - pub options: HanaJsonOptions, -} - #[derive( polyglot_sql_ast_derive::AstNode, Debug, Clone, Default, PartialEq, Serialize, Deserialize, )] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaJsonOptions { - pub returning: Option, +pub struct JsonOptions { pub wrapper: Option, - pub on_empty: Option, - pub on_error: Option, + pub on_empty: Option, + pub on_error: Option, } #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaBehavior { +pub struct SqlBehavior { /// ERROR, NULL, DEFAULT, EMPTY ARRAY, or EMPTY OBJECT. pub kind: String, pub value: Option, } -#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaJsonColumn { - pub name: Option, - pub data_type: Option, - pub path: Option, - pub ordinality: bool, - pub format_json: bool, - pub encoding: Option, - pub columns: Vec, - pub options: HanaJsonOptions, -} - /// Procedure invocation, including library member calls and asynchronous execution. #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaCall { +pub struct Call { + /// Retained source semantics; serialized independently of generator configuration. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + pub name: Vec, pub member: Option, pub arguments: Vec, @@ -5068,48 +5085,30 @@ pub struct HanaCall { pub hints: Vec, } +/// Regex search options shared by predicates, extraction, replacement, and position calls. #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaHint { - pub name: Identifier, - pub arguments: Option>, - pub remote: bool, - pub cascade: bool, -} - -/// HANA PCRE predicate/function grammar. Arguments remain traversable. -#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaRegex { - pub operation: String, +pub struct RegexOptions { + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + /// Original spelling when a dialect has more than one native alias. + pub source_name: String, + #[serde(default)] pub negated: bool, - pub pattern: Expression, - pub subject: Expression, - pub flag: Option, pub start: Option, pub occurrence: Option, - pub group: Option, - pub replacement: Option, + pub flags: Option, pub position_after: Option, } -/// Native HANA SELECT clauses, including serialization with no options. -#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaSelectOptions { - #[serde(default)] - pub total_rowcount: bool, - pub serialization: Option, - pub collation: Option, - pub hints: Vec, -} - -/// HANA grouping-set selection and result delivery options. +/// Grouping-set selection and result-delivery options. #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaGrouping { - pub kind: String, - pub expressions: Vec, +pub struct GroupingOptions { + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, pub best: Option, pub limit: Option, pub offset: Option, @@ -5122,18 +5121,9 @@ pub struct HanaGrouping { pub multiple_resultsets: bool, } -/// Time-zone conversion using a HANA time-zone dataset and error policy. -#[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] -#[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaTimezone { - pub name: String, - pub arguments: Vec, - pub on_error: Option, -} - #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] -pub struct HanaSerialization { +pub struct ResultSerialization { /// JSON or XML, validated by the HANA parser. pub format: String, pub options: Vec<(String, String)>, @@ -5150,6 +5140,17 @@ pub struct HanaSerialization { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct Function { + /// Qualified name components preserve quoting without changing the node kind. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub qualified_name: Vec, + /// Optional DEFAULT/NULL/ERROR behavior after the arguments. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub on_error: Option, + /// Dialect whose call semantics must be retained through independent generation. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + /// The function name, as originally written (may be schema-qualified). pub name: String, /// Positional arguments to the function. @@ -5179,6 +5180,9 @@ pub struct Function { impl Default for Function { fn default() -> Self { Self { + source_dialect: None, + qualified_name: Vec::new(), + on_error: None, name: String::new(), args: Vec::new(), distinct: false, @@ -5193,8 +5197,24 @@ impl Default for Function { } impl Function { + /// Construct a call with individually quoted qualified name components. + pub fn qualified(name: Vec, args: Vec) -> Self { + Self { + name: name + .iter() + .map(|part| part.name.as_str()) + .collect::>() + .join("."), + qualified_name: name, + args, + ..Default::default() + } + } pub fn new(name: impl Into, args: Vec) -> Self { Self { + source_dialect: None, + qualified_name: Vec::new(), + on_error: None, name: name.into(), args, distinct: false, @@ -5219,6 +5239,11 @@ impl Function { )] #[cfg_attr(feature = "bindings", derive(TS))] pub struct AggregateFunction { + /// Dialect whose call semantics must be retained through independent generation. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + /// The aggregate function name (e.g. "JSON_AGG", "XMLAGG"). pub name: String, /// Positional arguments. @@ -5558,6 +5583,9 @@ pub struct LateralView { #[cfg_attr(feature = "bindings", derive(TS))] #[cfg_attr(feature = "bindings", ts(export))] pub struct Hint { + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, pub expressions: Vec, } @@ -5566,6 +5594,13 @@ pub struct Hint { #[cfg_attr(feature = "bindings", derive(TS))] #[cfg_attr(feature = "bindings", ts(export))] pub enum HintExpression { + /// A structured hint directive with optional execution scope modifiers. + Directive { + name: Identifier, + arguments: Option>, + remote: bool, + cascade: bool, + }, /// Function-style hint: USE_HASH(table) Function { name: String, args: Vec }, /// Simple identifier hint: PARALLEL @@ -6774,6 +6809,9 @@ pub struct SplitFunc { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct RegexpFunc { + /// Additional search boundaries and retained source semantics. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, pub this: Expression, pub pattern: Expression, pub flags: Option, @@ -6783,6 +6821,9 @@ pub struct RegexpFunc { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct RegexpReplaceFunc { + /// Additional search boundaries and retained source semantics. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, pub this: Expression, pub pattern: Expression, pub replacement: Expression, @@ -6793,6 +6834,9 @@ pub struct RegexpReplaceFunc { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct RegexpExtractFunc { + /// Additional search boundaries and retained source semantics. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, pub this: Expression, pub pattern: Expression, pub group: Option, @@ -7512,6 +7556,13 @@ pub struct FunctionEmits { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct JsonExtractFunc { + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + /// Structured SQL/JSON wrapper and error/empty behavior. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, + pub this: Expression, pub path: Expression, pub returning: Option, @@ -7904,9 +7955,10 @@ pub struct CreateTable { /// Table modifier: DYNAMIC, ICEBERG, EXTERNAL, HYBRID (Snowflake) #[serde(default, skip_serializing_if = "Option::is_none")] pub table_modifier: Option, - /// The storage modifier was parsed from HANA rather than another dialect. - #[serde(default, skip_serializing_if = "std::ops::Not::not")] - pub hana_storage: bool, + /// Dialect whose call semantics must be retained through independent generation. + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, pub as_select: Option, /// Whether the AS SELECT was wrapped in parentheses @@ -8036,7 +8088,7 @@ impl CreateTable { temporary: false, or_replace: false, table_modifier: None, - hana_storage: false, + source_dialect: None, as_select: None, as_select_parenthesized: false, on_commit: None, @@ -11508,6 +11560,9 @@ pub struct Group { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct Cube { + /// Selection, subtotal, and result-delivery options for this grouping operation. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, #[serde(default)] pub expressions: Vec, } @@ -11516,6 +11571,9 @@ pub struct Cube { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct Rollup { + /// Selection, subtotal, and result-delivery options for this grouping operation. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, #[serde(default)] pub expressions: Vec, } @@ -11524,6 +11582,9 @@ pub struct Rollup { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct GroupingSets { + /// Selection, subtotal, and result-delivery options for this grouping operation. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, #[serde(default)] pub expressions: Vec, } @@ -12052,6 +12113,9 @@ pub struct PartitionedByProperty { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct PartitionByProperty { + /// Structured partition scheme when the dialect supports methods and ranges. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub specification: Option, #[serde(default)] pub expressions: Vec, } @@ -14385,6 +14449,18 @@ pub struct JSONExists { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct JSONColumnDef { + /// Typed column definition; legacy dialects may use the textual kind field. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub data_type: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub encoding: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + /// Structured SQL/JSON wrapper and error/empty behavior. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, + #[serde(default)] pub this: Option>, #[serde(default)] @@ -14433,6 +14509,13 @@ pub struct JSONStripNulls { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct JSONValue { + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + /// Structured SQL/JSON wrapper and error/empty behavior. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, + pub this: Box, #[serde(default)] pub path: Option>, @@ -14464,6 +14547,13 @@ pub struct JSONRemove { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct JSONTable { + #[serde(default, skip_serializing_if = "Option::is_none")] + #[ast(skip)] + pub source_dialect: Option, + /// Structured SQL/JSON wrapper and error/empty behavior. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, + pub this: Box, #[serde(default)] pub schema: Option>, @@ -15066,6 +15156,9 @@ pub struct RegexpFullMatch { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct RegexpInstr { + /// Additional search boundaries and retained source semantics. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, pub this: Box, pub expression: Box, #[serde(default)] @@ -15094,6 +15187,9 @@ pub struct RegexpSplit { #[derive(polyglot_sql_ast_derive::AstNode, Debug, Clone, PartialEq, Serialize, Deserialize)] #[cfg_attr(feature = "bindings", derive(TS))] pub struct RegexpCount { + /// Additional search boundaries and retained source semantics. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub options: Option, pub this: Box, pub expression: Box, #[serde(default)] diff --git a/crates/polyglot-sql/src/generator.rs b/crates/polyglot-sql/src/generator.rs index c58bb010..c68562f3 100644 --- a/crates/polyglot-sql/src/generator.rs +++ b/crates/polyglot-sql/src/generator.rs @@ -2576,6 +2576,18 @@ impl Generator { ))); } + let regex_options = match expr { + Expression::RegexpLike(r) => r.options.as_ref(), + Expression::RegexpReplace(r) => r.options.as_ref(), + Expression::RegexpExtract(r) => r.options.as_ref(), + Expression::RegexpInstr(r) => r.options.as_ref(), + Expression::RegexpCount(r) => r.options.as_ref(), + _ => None, + }; + if let Some(options) = regex_options { + return self.generate_source_regex(expr, options); + } + match expr { Expression::Select(select) => self.generate_select(select), Expression::Union(union) => self.generate_union(union), @@ -2608,58 +2620,11 @@ impl Generator { Expression::Collation(coll) => self.generate_collation(coll), Expression::Case(case) => self.generate_case(case), Expression::Function(func) => self.generate_function(func), - Expression::HanaFunction(func) => self.generate_hana_function(func), - Expression::HanaGrouping(grouping) => self.generate_hana_grouping(grouping), - Expression::HanaTimezone(timezone) => self.generate_hana_timezone(timezone), - Expression::HanaRegex(regex) => self.generate_hana_regex(regex), - Expression::HanaJson(json) => self.generate_hana_json(json), - Expression::HanaJsonColumn(column) => self.generate_hana_json_column(column), - Expression::HanaUpsert(upsert) => self.generate_hana_upsert(upsert), - Expression::HanaHierarchy(hierarchy) => self.generate_hana_hierarchy(hierarchy), - Expression::HanaCall(call) => self.generate_hana_call(call), - Expression::HanaHint(hint) => { - if self.config.dialect != Some(DialectType::HANA) { - return Err( - self.hana_unsupported("HANA optimizer hint has no verified target mapping") - ); - } - self.generate_identifier(&hint.name)?; - if let Some(arguments) = &hint.arguments { - self.write("("); - for (i, arg) in arguments.iter().enumerate() { - if i > 0 { - self.write(", "); - } - self.generate_expression(arg)?; - } - self.write(")"); - } - if hint.remote { - self.write(" REMOTE"); - } - if hint.cascade { - self.write(" CASCADE"); - } - Ok(()) - } - Expression::HanaTableFunction(function) => { - for (i, name) in function.name.iter().enumerate() { - if i > 0 { - self.write("."); - } - self.generate_identifier(name)?; - } - self.write("("); - for (i, argument) in function.arguments.iter().enumerate() { - if i > 0 { - self.write(", "); - } - self.generate_expression(argument)?; - } - self.write(")"); - Ok(()) - } - Expression::HanaPlaceholder(placeholder) => { + Expression::Hint(hint) => self.generate_hint(hint), + Expression::Upsert(upsert) => self.generate_hana_upsert(upsert), + Expression::Hierarchy(hierarchy) => self.generate_hana_hierarchy(hierarchy), + Expression::Call(call) => self.generate_hana_call(call), + Expression::ViewParameter(placeholder) => { if self.config.dialect != Some(DialectType::HANA) { return Err(self.hana_unsupported( "HANA calculation-view PLACEHOLDER has no verified target mapping", @@ -2670,8 +2635,7 @@ impl Generator { self.write(" => "); self.generate_expression(&placeholder.value) } - Expression::HanaPartition(partition) => self.generate_hana_partition(partition, false), - Expression::HanaStorageProperty(property) => { + Expression::StorageProperty(property) => { if self.config.dialect != Some(DialectType::HANA) { return Err(self .hana_unsupported("HANA storage property has no verified target mapping")); @@ -2683,15 +2647,6 @@ impl Generator { } Ok(()) } - Expression::HanaAggregateFunction(func) => { - if self.config.dialect != Some(DialectType::HANA) { - return Err(self.hana_unsupported(format!( - "HANA aggregate {} has no verified target mapping", - func.name - ))); - } - self.generate_aggregate_function(func) - } Expression::FunctionEmits(fe) => self.generate_function_emits(fe), Expression::AggregateFunction(func) => self.generate_aggregate_function(func), Expression::WindowFunction(wf) => self.generate_window_function(wf), @@ -4778,7 +4733,11 @@ impl Generator { } fn generate_select(&mut self, select: &Select) -> Result<()> { - if (select.hana_options.is_some() || select.locks.iter().any(|lock| lock.ignore_locked)) + if (select.result_serialization.is_some() + || select.query_collation.is_some() + || !select.query_hints.is_empty() + || select.total_rowcount + || select.locks.iter().any(|lock| lock.ignore_locked)) && self.config.dialect != Some(DialectType::HANA) { return Err(crate::error::Error::unsupported( @@ -5872,11 +5831,7 @@ impl Generator { } } - if select - .hana_options - .as_ref() - .is_some_and(|o| o.total_rowcount) - { + if select.total_rowcount { self.write(" TOTAL ROWCOUNT"); } @@ -5894,8 +5849,8 @@ impl Generator { } } - if let Some(options) = &select.hana_options { - if let Some(serialization) = &options.serialization { + { + if let Some(serialization) = &select.result_serialization { self.write(" FOR "); self.write(&serialization.format); if !serialization.options.is_empty() { @@ -5911,21 +5866,21 @@ impl Generator { self.write(")"); } } - if let Some(returning) = options - .serialization + if let Some(returning) = select + .result_serialization .as_ref() .and_then(|s| s.returning.as_ref()) { self.write(" RETURNS "); self.generate_data_type(returning)?; } - if let Some(collation) = &options.collation { + if let Some(collation) = &select.query_collation { self.write(" WITH COLLATION "); self.generate_identifier(collation)?; } - if !options.hints.is_empty() { + if !select.query_hints.is_empty() { self.write(" WITH HINT ("); - for (i, hint) in options.hints.iter().enumerate() { + for (i, hint) in select.query_hints.iter().enumerate() { if i > 0 { self.write(", "); } @@ -8650,7 +8605,7 @@ impl Generator { // ==================== DDL Generation ==================== fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> { - if ct.hana_storage + if ct.source_dialect == Some(DialectType::HANA) && self.config.dialect != Some(DialectType::HANA) && ct.table_modifier.as_ref().is_some_and(|m| { m.split_whitespace() @@ -17524,6 +17479,20 @@ impl Generator { /// Generate a query hint /*+ ... */ fn generate_hint(&mut self, hint: &Hint) -> Result<()> { + if hint.source_dialect.is_some() { + if hint.source_dialect != self.config.dialect { + return Err(self.hana_unsupported("Optimizer hint has no verified target mapping")); + } + for (i, expression) in hint.expressions.iter().enumerate() { + if i > 0 { + self.write(", "); + } + let text = self.hint_expression_to_string(expression)?; + self.write(&text); + } + return Ok(()); + } + use crate::dialects::DialectType; // Output hints for dialects that support them, or when no dialect is specified (identity tests) @@ -17707,6 +17676,33 @@ impl Generator { /// Convert a hint expression to a string, handling multiline formatting for long arguments fn hint_expression_to_string(&mut self, expr: &HintExpression) -> Result { match expr { + HintExpression::Directive { + name, + arguments, + remote, + cascade, + } => { + let mut generator = self.child_generator(); + generator.generate_identifier(name)?; + if let Some(arguments) = arguments { + generator.write("("); + for (i, argument) in arguments.iter().enumerate() { + if i > 0 { + generator.write(", "); + } + generator.generate_expression(argument)?; + } + generator.write(")"); + } + if *remote { + generator.write(" REMOTE"); + } + if *cascade { + generator.write(" CASCADE"); + } + Ok(generator.output) + } + HintExpression::Function { name, args } => { // Generate each argument to a string let arg_strings: Vec = args @@ -18809,7 +18805,7 @@ impl Generator { fn generate_hana_partition( &mut self, - partition: &HanaPartition, + partition: &PartitionSpec, subpartition: bool, ) -> Result<()> { if self.config.dialect != Some(DialectType::HANA) { @@ -18907,7 +18903,7 @@ impl Generator { Ok(()) } - fn generate_hana_call(&mut self, call: &HanaCall) -> Result<()> { + fn generate_hana_call(&mut self, call: &Call) -> Result<()> { if self.config.dialect != Some(DialectType::HANA) { return Err( self.hana_unsupported("HANA CALL requires a verified target procedure signature") @@ -18948,77 +18944,25 @@ impl Generator { Ok(()) } - fn generate_hana_json(&mut self, json: &HanaJson) -> Result<()> { - if self.config.dialect != Some(DialectType::HANA) { + fn check_json_source( + &self, + source: Option, + options: Option<&JsonOptions>, + ) -> Result<()> { + if source == Some(DialectType::HANA) && self.config.dialect != source { return Err(self.hana_unsupported( - "HANA JSON path and error semantics have no verified target mapping", + "SQL/JSON path and error semantics have no verified target mapping", )); } - self.write(&json.name); - self.write("("); - self.generate_expression(&json.input)?; - self.write(", "); - self.generate_expression(&json.path)?; - if !json.columns.is_empty() { - self.generate_hana_json_columns(&json.columns)?; - } - self.generate_hana_json_options(&json.options)?; - self.write(")"); - Ok(()) - } - - fn generate_hana_json_columns(&mut self, columns: &[Expression]) -> Result<()> { - self.write(" COLUMNS ("); - for (i, column) in columns.iter().enumerate() { - if i > 0 { - self.write(", "); - } - self.generate_expression(column)?; - } - self.write(")"); - Ok(()) - } - - fn generate_hana_json_column(&mut self, column: &HanaJsonColumn) -> Result<()> { - if self.config.dialect != Some(DialectType::HANA) { + if options.is_some() && self.config.dialect != Some(DialectType::HANA) { return Err( - self.hana_unsupported("HANA JSON_TABLE column has no verified target mapping") + self.hana_unsupported("SQL/JSON behavior options have no verified target mapping") ); } - if let Some(name) = &column.name { - self.generate_identifier(name)?; - } else { - self.write("NESTED"); - } - if column.ordinality { - self.write(" FOR ORDINALITY"); - } - if let Some(data_type) = &column.data_type { - self.write(" "); - self.generate_data_type(data_type)?; - } - if column.format_json { - self.write(" FORMAT JSON"); - } - if let Some(encoding) = &column.encoding { - self.write(" ENCODING "); - self.write(encoding); - } - if let Some(path) = &column.path { - self.write(" PATH "); - self.generate_expression(path)?; - } - if !column.columns.is_empty() { - self.generate_hana_json_columns(&column.columns)?; - } - self.generate_hana_json_options(&column.options) + Ok(()) } - fn generate_hana_json_options(&mut self, options: &HanaJsonOptions) -> Result<()> { - if let Some(returning) = &options.returning { - self.write(" RETURNING "); - self.generate_data_type(returning)?; - } + fn generate_json_options(&mut self, options: &JsonOptions) -> Result<()> { if let Some(wrapper) = &options.wrapper { self.write(" "); self.write(wrapper); @@ -19041,7 +18985,7 @@ impl Generator { Ok(()) } - fn generate_hana_hierarchy(&mut self, hierarchy: &HanaHierarchy) -> Result<()> { + fn generate_hana_hierarchy(&mut self, hierarchy: &Hierarchy) -> Result<()> { if self.config.dialect != Some(DialectType::HANA) { return Err(self.hana_unsupported("HANA hierarchy has no verified target mapping")); } @@ -19087,7 +19031,7 @@ impl Generator { Ok(()) } - fn generate_hana_upsert(&mut self, upsert: &HanaUpsert) -> Result<()> { + fn generate_hana_upsert(&mut self, upsert: &Upsert) -> Result<()> { if self.config.dialect != Some(DialectType::HANA) { return Err(self.hana_unsupported( "HANA UPSERT requires target-specific key and update semantics", @@ -19122,39 +19066,89 @@ impl Generator { Ok(()) } - fn generate_hana_regex(&mut self, regex: &HanaRegex) -> Result<()> { + fn generate_source_regex(&mut self, expr: &Expression, options: &RegexOptions) -> Result<()> { if self.config.dialect != Some(DialectType::HANA) { - return Err(self.hana_unsupported("HANA PCRE operation has no verified target mapping")); + return Err(self.hana_unsupported( + "Regular-expression source semantics have no verified target mapping", + )); } - let predicate = regex.operation == "LIKE_REGEXPR"; + let (subject, pattern, flag, start, occurrence, group, replacement) = match expr { + Expression::RegexpLike(r) => ( + &r.this, + &r.pattern, + r.flags.as_ref(), + None, + None, + None, + None, + ), + Expression::RegexpExtract(r) => ( + &r.this, + &r.pattern, + options.flags.as_ref(), + options.start.as_ref(), + options.occurrence.as_ref(), + r.group.as_ref(), + None, + ), + Expression::RegexpReplace(r) => ( + &r.this, + &r.pattern, + r.flags.as_ref(), + options.start.as_ref(), + options.occurrence.as_ref(), + None, + Some(&r.replacement), + ), + Expression::RegexpInstr(r) => ( + r.this.as_ref(), + r.expression.as_ref(), + r.parameters.as_deref(), + r.position.as_deref(), + r.occurrence.as_deref(), + r.group.as_deref(), + None, + ), + Expression::RegexpCount(r) => ( + r.this.as_ref(), + r.expression.as_ref(), + r.parameters.as_deref(), + r.position.as_deref(), + None, + None, + None, + ), + _ => unreachable!("regex options belong to regex expressions"), + }; + let predicate = options.source_name == "LIKE_REGEXPR"; if predicate { - self.generate_expression(®ex.subject)?; - self.write(if regex.negated { + self.generate_expression(subject)?; + self.write(if options.negated { " NOT LIKE_REGEXPR " } else { " LIKE_REGEXPR " }); } else { - self.write(®ex.operation); + self.write(&options.source_name); self.write("("); - if let Some(after) = regex.position_after { + if let Some(after) = options.position_after { self.write(if after { "AFTER " } else { "START " }); } } - self.generate_expression(®ex.pattern)?; - if let Some(flag) = ®ex.flag { + self.generate_expression(pattern)?; + if let Some(flag) = flag { self.write(" FLAG "); self.generate_expression(flag)?; } if !predicate { self.write(" IN "); - self.generate_expression(®ex.subject)?; + self.generate_expression(subject)?; } for (keyword, argument) in [ - (" WITH ", ®ex.replacement), - (" FROM ", ®ex.start), - (" OCCURRENCE ", ®ex.occurrence), - (" GROUP ", ®ex.group), + (" WITH ", replacement), + (" FROM ", start), + (" OCCURRENCE ", occurrence), + (" GROUP ", group), ] { if let Some(argument) = argument { self.write(keyword); @@ -19210,13 +19204,18 @@ impl Generator { ) } - fn generate_hana_grouping(&mut self, grouping: &HanaGrouping) -> Result<()> { + fn generate_grouping_options( + &mut self, + kind: &str, + expressions: &[Expression], + grouping: &GroupingOptions, + ) -> Result<()> { if self.config.dialect != Some(DialectType::HANA) { return Err( self.hana_unsupported("HANA grouping-set selection and result delivery options") ); } - self.write(&grouping.kind); + self.write(kind); for (keyword, value) in [ (" BEST ", &grouping.best), (" LIMIT ", &grouping.limit), @@ -19246,7 +19245,7 @@ impl Generator { self.write(" MULTIPLE RESULTSETS"); } self.write(" ("); - for (i, expression) in grouping.expressions.iter().enumerate() { + for (i, expression) in expressions.iter().enumerate() { if i > 0 { self.write(", "); } @@ -19256,28 +19255,12 @@ impl Generator { Ok(()) } - fn generate_hana_timezone(&mut self, timezone: &HanaTimezone) -> Result<()> { - if self.config.dialect != Some(DialectType::HANA) { - return Err(self.hana_unsupported("HANA timezone datasets and conversion error policy")); - } - self.write(&timezone.name); - self.write("("); - for (i, argument) in timezone.arguments.iter().enumerate() { - if i > 0 { - self.write(", "); - } - self.generate_expression(argument)?; - } - if let Some(behavior) = &timezone.on_error { + fn generate_sql_behavior(&mut self, behavior: &SqlBehavior) -> Result<()> { + self.write(&behavior.kind); + if let Some(value) = &behavior.value { self.write(" "); - self.write(&behavior.kind); - if let Some(value) = &behavior.value { - self.write(" "); - self.generate_expression(value)?; - } - self.write(" ON ERROR"); + self.generate_expression(value)?; } - self.write(")"); Ok(()) } @@ -19543,6 +19526,53 @@ impl Generator { } fn generate_function(&mut self, func: &Function) -> Result<()> { + if func.source_dialect == Some(DialectType::HANA) + && self.config.dialect != Some(DialectType::HANA) + { + return self.generate_hana_function(func); + } + if !func.qualified_name.is_empty() { + for (i, component) in func.qualified_name.iter().enumerate() { + if i > 0 { + self.write("."); + } + self.generate_identifier(component)?; + } + if !func.no_parens { + self.write("("); + if func.distinct { + self.write("DISTINCT "); + } + for (i, argument) in func.args.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(argument)?; + } + if let Some(behavior) = &func.on_error { + if self.config.dialect != Some(DialectType::HANA) { + return Err(self.hana_unsupported( + "Function error behavior has no verified target mapping", + )); + } + self.write(" "); + self.generate_sql_behavior(behavior)?; + self.write(" ON ERROR"); + } + self.write(")"); + } + for comment in &func.trailing_comments { + self.write_space(); + self.write_formatted_comment(comment); + } + return Ok(()); + } + if func.on_error.is_some() && self.config.dialect != Some(DialectType::HANA) { + return Err( + self.hana_unsupported("Function error behavior has no verified target mapping") + ); + } + if self.config.dialect == Some(DialectType::HANA) && !func.quoted && matches!( @@ -20265,6 +20295,11 @@ impl Generator { } } + if let Some(behavior) = &func.on_error { + self.write(" "); + self.generate_sql_behavior(behavior)?; + self.write(" ON ERROR"); + } if use_brackets { self.write("]"); } else { @@ -20291,6 +20326,15 @@ impl Generator { } fn generate_aggregate_function(&mut self, func: &AggregateFunction) -> Result<()> { + if func.source_dialect == Some(DialectType::HANA) + && self.config.dialect != Some(DialectType::HANA) + { + return Err(self.hana_unsupported(format!( + "HANA aggregate {} has no verified target mapping", + func.name + ))); + } + // Normalize function name based on dialect settings let mut normalized_name = self.normalize_func_name(&func.name); @@ -23372,6 +23416,10 @@ impl Generator { } } Expression::Function(Box::new(crate::expressions::Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: f.name.clone(), args: new_args, distinct: f.distinct, @@ -24008,6 +24056,23 @@ impl Generator { // JSON function generators fn generate_json_extract(&mut self, name: &str, f: &JsonExtractFunc) -> Result<()> { + self.check_json_source(f.source_dialect, f.options.as_ref())?; + if f.source_dialect == Some(DialectType::HANA) { + self.write(name); + self.write("("); + self.generate_expression(&f.this)?; + self.write(", "); + self.generate_expression(&f.path)?; + if let Some(returning) = &f.returning { + self.write(" RETURNING "); + self.generate_data_type(returning)?; + } + if let Some(options) = &f.options { + self.generate_json_options(options)?; + } + self.write(")"); + return Ok(()); + } use crate::dialects::DialectType; // Check if we should use arrow syntax (-> or ->>) @@ -30633,6 +30698,9 @@ impl Generator { } } self.write_keyword("COLUMNS"); + if self.config.dialect == Some(DialectType::HANA) { + self.write(" "); + } self.write("("); self.generate_expression(&e.this)?; self.write(")"); @@ -31600,6 +31668,9 @@ impl Generator { } fn generate_cube(&mut self, e: &Cube) -> Result<()> { + if let Some(options) = &e.options { + return self.generate_grouping_options("CUBE", &e.expressions, options); + } // Python: return f"CUBE {self.wrap(expressions)}" if expressions else "WITH CUBE" if e.expressions.is_empty() { self.write_keyword("WITH CUBE"); @@ -33470,6 +33541,9 @@ impl Generator { } fn generate_grouping_sets(&mut self, e: &GroupingSets) -> Result<()> { + if let Some(options) = &e.options { + return self.generate_grouping_options("GROUPING SETS", &e.expressions, options); + } // Python: return f"GROUPING SETS {self.wrap(grouping_sets)}" self.write_keyword("GROUPING SETS"); self.write(" ("); @@ -34151,6 +34225,7 @@ impl Generator { } fn generate_json_column_def(&mut self, e: &JSONColumnDef) -> Result<()> { + self.check_json_source(e.source_dialect, e.options.as_ref())?; // Python: NESTED PATH path schema | this kind PATH path [FOR ORDINALITY] if let Some(nested_schema) = &e.nested_schema { self.write_keyword("NESTED"); @@ -34166,6 +34241,10 @@ impl Generator { if let Some(this) = &e.this { self.generate_expression(this)?; } + if let Some(data_type) = &e.data_type { + self.write_space(); + self.generate_data_type(data_type)?; + } if let Some(kind) = &e.kind { self.write_space(); self.write(kind); @@ -34174,6 +34253,10 @@ impl Generator { self.write_space(); self.write_keyword("FORMAT JSON"); } + if let Some(encoding) = &e.encoding { + self.write(" ENCODING "); + self.write(encoding); + } if let Some(path) = &e.path { self.write_space(); self.write_keyword("PATH"); @@ -34184,6 +34267,9 @@ impl Generator { self.write_keyword(" FOR ORDINALITY"); } } + if let Some(options) = &e.options { + self.generate_json_options(options)?; + } Ok(()) } @@ -34583,6 +34669,9 @@ impl Generator { // COLUMNS(col1 type, col2 type, ...) // When pretty printing and content is too wide, format with each column on a separate line self.write_keyword("COLUMNS"); + if self.config.dialect == Some(DialectType::HANA) { + self.write(" "); + } self.write("("); if self.config.pretty && !e.expressions.is_empty() { @@ -34659,6 +34748,7 @@ impl Generator { } fn generate_json_table(&mut self, e: &JSONTable) -> Result<()> { + self.check_json_source(e.source_dialect, e.options.as_ref())?; // JSON_TABLE(this, path [error_handling] [empty_handling] schema) self.write_keyword("JSON_TABLE"); self.write("("); @@ -34679,6 +34769,9 @@ impl Generator { self.write_space(); self.generate_expression(schema)?; } + if let Some(options) = &e.options { + self.generate_json_options(options)?; + } self.write(")"); Ok(()) } @@ -34693,6 +34786,7 @@ impl Generator { } fn generate_json_value(&mut self, e: &JSONValue) -> Result<()> { + self.check_json_source(e.source_dialect, e.options.as_ref())?; // JSON_VALUE(this, path RETURNING type ON condition) self.write_keyword("JSON_VALUE"); self.write("("); @@ -34711,6 +34805,9 @@ impl Generator { self.write_space(); self.generate_expression(on_condition)?; } + if let Some(options) = &e.options { + self.generate_json_options(options)?; + } self.write(")"); Ok(()) } @@ -36628,6 +36725,9 @@ impl Generator { } fn generate_partition_by_property(&mut self, e: &PartitionByProperty) -> Result<()> { + if let Some(specification) = &e.specification { + return self.generate_hana_partition(specification, false); + } // BigQuery table property: PARTITION BY expression [, expression ...] self.write_keyword("PARTITION BY"); self.write_space(); @@ -37771,6 +37871,9 @@ impl Generator { } fn generate_rollup(&mut self, e: &Rollup) -> Result<()> { + if let Some(options) = &e.options { + return self.generate_grouping_options("ROLLUP", &e.expressions, options); + } // Python: return f"ROLLUP {self.wrap(expressions)}" if expressions else "WITH ROLLUP" if e.expressions.is_empty() { self.write_keyword("WITH ROLLUP"); diff --git a/crates/polyglot-sql/src/lineage.rs b/crates/polyglot-sql/src/lineage.rs index 451555d2..5e105786 100644 --- a/crates/polyglot-sql/src/lineage.rs +++ b/crates/polyglot-sql/src/lineage.rs @@ -373,7 +373,7 @@ fn lineage_normalized_expression(sql: &Expression) -> Expression { .map(|query| attach_with_to_query(query.clone(), create.with_cte.clone())) .unwrap_or_else(|| sql.clone()), Expression::CreateView(create) => lineage_normalized_expression(&create.query), - Expression::HanaUpsert(upsert) => lineage_normalized_expression(&upsert.source), + Expression::Upsert(upsert) => lineage_normalized_expression(&upsert.source), Expression::Insert(insert) => insert .query .as_ref() diff --git a/crates/polyglot-sql/src/optimizer/annotate_types.rs b/crates/polyglot-sql/src/optimizer/annotate_types.rs index a40a45a5..ace29527 100644 --- a/crates/polyglot-sql/src/optimizer/annotate_types.rs +++ b/crates/polyglot-sql/src/optimizer/annotate_types.rs @@ -927,7 +927,7 @@ impl<'a> TypeAnnotator<'a> { } // Function - Expression::Function(f) | Expression::HanaFunction(f) => { + Expression::Function(f) => { for arg in &mut f.args { self.annotate_in_place(arg); } diff --git a/crates/polyglot-sql/src/optimizer/canonicalize.rs b/crates/polyglot-sql/src/optimizer/canonicalize.rs index e4d0ac6e..1f4d7b29 100644 --- a/crates/polyglot-sql/src/optimizer/canonicalize.rs +++ b/crates/polyglot-sql/src/optimizer/canonicalize.rs @@ -170,42 +170,32 @@ fn canonicalize_recursive(expression: Expression, dialect: Option) remove_redundant_casts(result) } - // Function expressions - Expression::Function(func) => { - let args = func + // Preserve source metadata while canonicalizing shared function children. + Expression::Function(mut func) => { + func.args = func .args .into_iter() .map(|e| canonicalize_recursive(e, dialect)) .collect(); - Expression::Function(Box::new(crate::expressions::Function { - name: func.name, - args, - distinct: func.distinct, - trailing_comments: func.trailing_comments, - use_bracket_syntax: func.use_bracket_syntax, - no_parens: func.no_parens, - quoted: func.quoted, - span: None, - inferred_type: None, - })) + if let Some(behavior) = &mut func.on_error { + behavior.value = behavior + .value + .take() + .map(|e| canonicalize_recursive(e, dialect)); + } + func.span = None; + func.inferred_type = None; + Expression::Function(func) } - - Expression::AggregateFunction(agg) => { - let args = agg + Expression::AggregateFunction(mut agg) => { + agg.args = agg .args .into_iter() .map(|e| canonicalize_recursive(e, dialect)) .collect(); - Expression::AggregateFunction(Box::new(crate::expressions::AggregateFunction { - name: agg.name, - args, - distinct: agg.distinct, - filter: agg.filter.map(|f| canonicalize_recursive(f, dialect)), - order_by: agg.order_by, - limit: agg.limit, - ignore_nulls: agg.ignore_nulls, - inferred_type: None, - })) + agg.filter = agg.filter.map(|e| canonicalize_recursive(e, dialect)); + agg.inferred_type = None; + Expression::AggregateFunction(agg) } // Alias diff --git a/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs b/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs index 505af754..08b20362 100644 --- a/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs +++ b/crates/polyglot-sql/src/optimizer/normalize_identifiers.rs @@ -248,6 +248,17 @@ fn normalize_expression(expression: Expression, strategy: NormalizationStrategy) .into_iter() .map(|e| normalize_expression(e, strategy)) .collect(); + func.qualified_name = func + .qualified_name + .into_iter() + .map(|i| normalize_identifier(i, strategy)) + .collect(); + if let Some(behavior) = &mut func.on_error { + behavior.value = behavior + .value + .take() + .map(|e| normalize_expression(e, strategy)); + } Expression::Function(Box::new(func)) } Expression::AggregateFunction(agg) => { diff --git a/crates/polyglot-sql/src/optimizer/pushdown_projections.rs b/crates/polyglot-sql/src/optimizer/pushdown_projections.rs index 79fcbb3b..cf87d095 100644 --- a/crates/polyglot-sql/src/optimizer/pushdown_projections.rs +++ b/crates/polyglot-sql/src/optimizer/pushdown_projections.rs @@ -310,6 +310,8 @@ pub fn default_selection(is_agg: bool) -> Expression { // MAX(1) AS _ Expression::Alias(Box::new(Alias { this: Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: "MAX".to_string(), args: vec![Expression::Literal(Box::new(Literal::Number( "1".to_string(), diff --git a/crates/polyglot-sql/src/parser.rs b/crates/polyglot-sql/src/parser.rs index 1acd5c95..e4a0974f 100644 --- a/crates/polyglot-sql/src/parser.rs +++ b/crates/polyglot-sql/src/parser.rs @@ -2746,10 +2746,14 @@ impl Parser { let mut expressions = Vec::new(); if self.match_token(TokenType::Rollup) { expressions.push(Expression::Rollup(Box::new(Rollup { + options: None, + expressions: Vec::new(), }))); } else if self.match_token(TokenType::Cube) { expressions.push(Expression::Cube(Box::new(Cube { + options: None, + expressions: Vec::new(), }))); } @@ -3047,7 +3051,8 @@ impl Parser { // Parse FOR UPDATE/SHARE locks or FOR XML/JSON (T-SQL) let (locks, for_xml, for_json) = self.parse_locks_and_for_xml()?; - let hana_options = self.parse_hana_select_options(hana_total_rowcount)?; + let (result_serialization, query_collation, query_hints) = + self.parse_hana_select_options()?; let option = if matches!( self.config.dialect, @@ -3106,10 +3111,21 @@ impl Parser { hint, connect, into, - locks, for_xml, for_json, - hana_options, + source_dialect: self.config.dialect.filter(|d| { + *d == crate::dialects::DialectType::HANA + && (hana_total_rowcount + || result_serialization.is_some() + || query_collation.is_some() + || !query_hints.is_empty() + || locks.iter().any(|lock| lock.ignore_locked)) + }), + result_serialization, + query_collation, + query_hints, + total_rowcount: hana_total_rowcount, + locks, leading_comments, post_select_comments, kind, @@ -4276,6 +4292,13 @@ impl Parser { // Build SELECT expression let select = Select { + source_dialect: None, + total_rowcount: false, + + query_collation: None, + query_hints: Vec::new(), + result_serialization: None, + expressions, from: Some(from), joins, @@ -4307,7 +4330,7 @@ impl Parser { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), - hana_options: None, + leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, @@ -4593,6 +4616,10 @@ impl Parser { })) } else { Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: first_name, args, distinct: false, @@ -5275,10 +5302,10 @@ impl Parser { self.parse_function_arguments()? }; self.expect(TokenType::RParen)?; - Expression::HanaTableFunction(Box::new(HanaTableFunction { - name: vec![first_ident, second_ident, third_ident], + Expression::Function(Box::new(Function::qualified( + vec![first_ident, second_ident, third_ident], arguments, - })) + ))) } else if self.match_token(TokenType::LParen) { // catalog.schema.function() - table-valued function let args = if self.check(TokenType::RParen) { @@ -5289,6 +5316,10 @@ impl Parser { self.expect(TokenType::RParen)?; let trailing_comments = self.previous_trailing_comments().to_vec(); Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: format!("{}.{}.{}", first_name, second_name, third_name), args, distinct: false, @@ -5344,10 +5375,10 @@ impl Parser { self.parse_function_arguments()? }; self.expect(TokenType::RParen)?; - Expression::HanaTableFunction(Box::new(HanaTableFunction { - name: vec![first_ident, second_ident], + Expression::Function(Box::new(Function::qualified( + vec![first_ident, second_ident], arguments, - })) + ))) } else if self.match_token(TokenType::LParen) { // schema.function() - table-valued function let args = if self.check(TokenType::RParen) { @@ -5358,6 +5389,10 @@ impl Parser { self.expect(TokenType::RParen)?; let trailing_comments = self.previous_trailing_comments().to_vec(); Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: format!("{}.{}", first_name, second_name), args, distinct: false, @@ -5476,6 +5511,9 @@ impl Parser { self.expect(TokenType::RParen)?; Expression::JSONTable(Box::new(JSONTable { + options: None, + source_dialect: None, + this: Box::new(this_with_format), schema: schema.map(Box::new), path, @@ -5522,6 +5560,10 @@ impl Parser { self.expect(TokenType::RParen)?; let trailing_comments = self.previous_trailing_comments().to_vec(); Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: first_name.to_string(), args: vec![query], distinct: false, @@ -5595,6 +5637,10 @@ impl Parser { first_name.clone() }; let func = Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: func_name, args, distinct: false, @@ -7542,6 +7588,10 @@ impl Parser { let trailing_comments = self.previous_trailing_comments().to_vec(); // Create a Function expression to represent IDENTIFIER(arg) let identifier_func = Expression::Function(Box::new(crate::expressions::Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "IDENTIFIER".to_string(), args: vec![arg], distinct: false, @@ -8412,10 +8462,14 @@ impl Parser { self.skip(); // consume WITH if self.match_token(TokenType::Cube) { expressions.push(Expression::Cube(Box::new(Cube { + options: None, + expressions: Vec::new(), }))); } else if self.match_token(TokenType::Rollup) { expressions.push(Expression::Rollup(Box::new(Rollup { + options: None, + expressions: Vec::new(), }))); } @@ -8457,6 +8511,10 @@ impl Parser { let args = self.parse_grouping_sets_args()?; self.expect(TokenType::RParen)?; Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "GROUPING SETS".to_string(), args, distinct: false, @@ -8473,6 +8531,10 @@ impl Parser { let args = self.parse_expression_list()?; self.expect(TokenType::RParen)?; Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CUBE".to_string(), args, distinct: false, @@ -8489,6 +8551,10 @@ impl Parser { let args = self.parse_expression_list()?; self.expect(TokenType::RParen)?; Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "ROLLUP".to_string(), args, distinct: false, @@ -8546,11 +8612,15 @@ impl Parser { if self.match_token(TokenType::Cube) { // WITH CUBE - add Cube with empty expressions expressions.push(Expression::Cube(Box::new(Cube { + options: None, + expressions: Vec::new(), }))); } else if self.match_token(TokenType::Rollup) { // WITH ROLLUP - add Rollup with empty expressions expressions.push(Expression::Rollup(Box::new(Rollup { + options: None, + expressions: Vec::new(), }))); } @@ -8605,6 +8675,10 @@ impl Parser { let inner_args = self.parse_grouping_sets_args()?; self.expect(TokenType::RParen)?; Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "GROUPING SETS".to_string(), args: inner_args, distinct: false, @@ -8621,6 +8695,10 @@ impl Parser { let inner_args = self.parse_expression_list()?; self.expect(TokenType::RParen)?; Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "CUBE".to_string(), args: inner_args, distinct: false, @@ -8637,6 +8715,10 @@ impl Parser { let inner_args = self.parse_expression_list()?; self.expect(TokenType::RParen)?; Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "ROLLUP".to_string(), args: inner_args, distinct: false, @@ -9286,15 +9368,43 @@ impl Parser { } else { Vec::new() }; - let options = self.parse_hana_json_options(name == "JSON_QUERY", name != "JSON_TABLE")?; + let (returning, options) = + self.parse_hana_json_options(name == "JSON_QUERY", name != "JSON_TABLE")?; self.expect(TokenType::RParen)?; - Ok(Expression::HanaJson(Box::new(HanaJson { - name: name.to_owned(), - input, - path, - columns, - options, - }))) + Ok(match name { + "JSON_TABLE" => Expression::JSONTable(Box::new(JSONTable { + source_dialect: self.config.dialect, + this: Box::new(input), + path: Some(Box::new(path)), + schema: Some(Box::new(Expression::JSONSchema(Box::new(JSONSchema { + expressions: columns, + })))), + error_handling: None, + empty_handling: None, + options: Some(options), + })), + "JSON_QUERY" => Expression::JsonQuery(Box::new(JsonExtractFunc { + source_dialect: self.config.dialect, + this: input, + path, + returning, + options: Some(options), + arrow_syntax: false, + hash_arrow_syntax: false, + wrapper_option: None, + quotes_option: None, + on_scalar_string: false, + on_error: None, + })), + _ => Expression::JSONValue(Box::new(JSONValue { + source_dialect: self.config.dialect, + this: Box::new(input), + path: Some(Box::new(path)), + returning: returning.map(|t| Box::new(Expression::DataType(t))), + on_condition: None, + options: Some(options), + })), + }) } fn parse_hana_json_columns(&mut self) -> Result> { @@ -9343,19 +9453,26 @@ impl Parser { Vec::new() }; let options = if !nested && !ordinality { - self.parse_hana_json_options(format_json, false)? + self.parse_hana_json_options(format_json, false)?.1 } else { - HanaJsonOptions::default() + JsonOptions::default() }; - result.push(Expression::HanaJsonColumn(Box::new(HanaJsonColumn { - name, + result.push(Expression::JSONColumnDef(Box::new(JSONColumnDef { + source_dialect: self.config.dialect, + this: name.map(|n| Box::new(Expression::Identifier(n))), + kind: None, data_type, - path, - ordinality, + path: path.map(Box::new), + ordinality: ordinality + .then(|| Box::new(Expression::Boolean(BooleanLiteral { value: true }))), format_json, encoding, - columns, - options, + nested_schema: nested.then(|| { + Box::new(Expression::JSONSchema(Box::new(JSONSchema { + expressions: columns, + }))) + }), + options: Some(options), }))); if !self.match_token(TokenType::Comma) { break; @@ -9369,7 +9486,7 @@ impl Parser { &mut self, query: bool, returning_allowed: bool, - ) -> Result { + ) -> Result<(Option, JsonOptions)> { let returning = if returning_allowed && self.match_token(TokenType::Returning) { Some(self.parse_data_type()?) } else { @@ -9393,8 +9510,7 @@ impl Parser { } else { None }; - let mut options = HanaJsonOptions { - returning, + let mut options = JsonOptions { wrapper, ..Default::default() }; @@ -9433,9 +9549,9 @@ impl Parser { if field.is_some() { return Err(self.parse_error("Duplicate JSON behavior clause")); } - *field = Some(HanaBehavior { kind, value }); + *field = Some(SqlBehavior { kind, value }); } - Ok(options) + Ok((returning, options)) } fn parse_hana_hierarchy(&mut self, name: &str) -> Result { @@ -9522,7 +9638,8 @@ impl Parser { ); } self.expect(TokenType::RParen)?; - Ok(Expression::HanaHierarchy(Box::new(HanaHierarchy { + Ok(Expression::Hierarchy(Box::new(Hierarchy { + source_dialect: self.config.dialect, name: name.to_owned(), source, start, @@ -9573,7 +9690,8 @@ impl Parser { } else { false }; - Ok(Expression::HanaUpsert(Box::new(HanaUpsert { + Ok(Expression::Upsert(Box::new(Upsert { + source_dialect: self.config.dialect, table, partition, columns, @@ -9588,16 +9706,19 @@ impl Parser { self.expect(TokenType::Partition)?; self.expect(TokenType::By)?; } - Ok(Expression::HanaPartition(Box::new( - self.parse_hana_partition_spec()?, + Ok(Expression::PartitionByProperty(Box::new( + PartitionByProperty { + expressions: Vec::new(), + specification: Some(self.parse_hana_partition_spec()?), + }, ))) } - fn parse_hana_partition_spec(&mut self) -> Result { + fn parse_hana_partition_spec(&mut self) -> Result { self.with_parser_depth(|parser| parser.parse_hana_partition_spec_inner()) } - fn parse_hana_partition_spec_inner(&mut self) -> Result { + fn parse_hana_partition_spec_inner(&mut self) -> Result { let method = self.expect_identifier_or_keyword()?.to_ascii_uppercase(); if !matches!(method.as_str(), "HASH" | "ROUNDROBIN" | "RANGE") { return Err(self.parse_error("Expected HASH, ROUNDROBIN, or RANGE partitioning")); @@ -9685,7 +9806,7 @@ impl Parser { while let Some(property) = self.parse_hana_storage_property()? { properties.push(property); } - ranges.push(HanaPartitionRange { + ranges.push(PartitionRangeSpec { name, kind: kind.to_owned(), values, @@ -9717,7 +9838,8 @@ impl Parser { } else { None }; - Ok(HanaPartition { + Ok(PartitionSpec { + source_dialect: self.config.dialect, method, columns, partitions, @@ -9799,8 +9921,9 @@ impl Parser { } _ => return Ok(None), } - Ok(Some(Expression::HanaStorageProperty(Box::new( - HanaStorageProperty { + Ok(Some(Expression::StorageProperty(Box::new( + StorageProperty { + source_dialect: self.config.dialect, name: words.join(" "), values, }, @@ -9871,18 +9994,64 @@ impl Parser { if !predicate { self.expect(TokenType::RParen)?; } - Ok(Expression::HanaRegex(Box::new(HanaRegex { - operation: operation.to_owned(), + let mut options = RegexOptions { + source_dialect: self.config.dialect, + source_name: operation.to_owned(), negated: false, - pattern, - subject, - flag, - start, - occurrence, - group, - replacement, + start: None, + occurrence: None, + flags: None, position_after, - }))) + }; + Ok(match operation { + "LIKE_REGEXPR" => Expression::RegexpLike(Box::new(RegexpFunc { + this: subject, + pattern, + flags: flag, + options: Some(options), + })), + "LOCATE_REGEXPR" => Expression::RegexpInstr(Box::new(RegexpInstr { + this: Box::new(subject), + expression: Box::new(pattern), + position: start.map(Box::new), + occurrence: occurrence.map(Box::new), + parameters: flag.map(Box::new), + group: group.map(Box::new), + option: None, + options: Some(options), + })), + "OCCURRENCES_REGEXPR" => Expression::RegexpCount(Box::new(RegexpCount { + this: Box::new(subject), + expression: Box::new(pattern), + position: start.map(Box::new), + parameters: flag.map(Box::new), + options: Some(options), + })), + "REPLACE_REGEXPR" => { + options.start = start; + options.occurrence = occurrence; + Expression::RegexpReplace(Box::new(RegexpReplaceFunc { + this: subject, + pattern, + flags: flag, + replacement: replacement.ok_or_else(|| { + self.parse_error("REPLACE_REGEXPR requires WITH replacement") + })?, + options: Some(options), + })) + } + _ => { + options.start = start; + options.occurrence = occurrence; + options.flags = flag; + Expression::RegexpExtract(Box::new(RegexpExtractFunc { + this: subject, + pattern, + group, + options: Some(options), + })) + } + }) } fn parse_hana_grouping(&mut self) -> Result { @@ -9925,19 +10094,15 @@ impl Parser { self.expect(TokenType::LParen)?; let expressions = self.parse_grouping_sets_args()?; self.expect(TokenType::RParen)?; - if best.is_none() - && limit.is_none() - && !subtotal - && !balance - && !total - && !structured - && !multiple_resultsets - { - return Ok(Self::make_unquoted_function(&kind, expressions)); - } - Ok(Expression::HanaGrouping(Box::new(HanaGrouping { - kind, - expressions, + let has_options = best.is_some() + || limit.is_some() + || subtotal + || balance + || total + || structured + || multiple_resultsets; + let options = has_options.then_some(GroupingOptions { + source_dialect: self.config.dialect, best, limit, offset, @@ -9948,7 +10113,21 @@ impl Parser { overview, prefix, multiple_resultsets, - }))) + }); + Ok(match kind.as_str() { + "ROLLUP" => Expression::Rollup(Box::new(Rollup { + expressions, + options, + })), + "CUBE" => Expression::Cube(Box::new(Cube { + expressions, + options, + })), + _ => Expression::GroupingSets(Box::new(GroupingSets { + expressions, + options, + })), + }) } fn parse_hana_grouping_integer(&mut self, signed: bool) -> Result { @@ -9983,7 +10162,7 @@ impl Parser { if !self.match_keyword("ERROR") { return Err(self.parse_error("Expected ON ERROR")); } - on_error = Some(HanaBehavior { + on_error = Some(SqlBehavior { kind: behavior, value, }); @@ -10007,19 +10186,21 @@ impl Parser { if !(1..=4).contains(&arguments.len()) { return Err(self.parse_error("HANA timezone conversion expects one to four arguments")); } - Ok(Expression::HanaTimezone(Box::new(HanaTimezone { - name: name.to_owned(), - arguments, - on_error, - }))) + let mut function = Function::new(name, arguments); + function.source_dialect = self.config.dialect; + function.on_error = on_error; + Ok(Expression::Function(Box::new(function))) } fn parse_hana_select_options( &mut self, - total_rowcount: bool, - ) -> Result> { + ) -> Result<( + Option, + Option, + Vec, + )> { if self.config.dialect != Some(crate::dialects::DialectType::HANA) { - return Ok(None); + return Ok((None, None, Vec::new())); } let mut serialization = None; if self.check(TokenType::For) @@ -10045,7 +10226,7 @@ impl Parser { } else { None }; - serialization = Some(HanaSerialization { + serialization = Some(ResultSerialization { format, options, returning, @@ -10059,15 +10240,7 @@ impl Parser { None }; let hints = self.parse_hana_hints()?; - Ok( - (total_rowcount || serialization.is_some() || collation.is_some() || !hints.is_empty()) - .then_some(HanaSelectOptions { - total_rowcount, - serialization, - collation, - hints, - }), - ) + Ok((serialization, collation, hints)) } fn parse_hana_hints(&mut self) -> Result> { @@ -10091,11 +10264,14 @@ impl Parser { }; let remote = self.match_keyword("REMOTE"); let cascade = self.match_keyword("CASCADE"); - hints.push(Expression::HanaHint(Box::new(HanaHint { - name, - arguments, - remote, - cascade, + hints.push(Expression::Hint(Box::new(Hint { + source_dialect: self.config.dialect, + expressions: vec![HintExpression::Directive { + name, + arguments, + remote, + cascade, + }], }))); if !self.match_token(TokenType::Comma) { break; @@ -10922,7 +11098,10 @@ impl Parser { vec![HintExpression::Raw(hint_text)] }; - Ok(Hint { expressions }) + Ok(Hint { + source_dialect: None, + expressions, + }) } /// Parse SAMPLE / TABLESAMPLE / USING SAMPLE clause @@ -12049,6 +12228,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; function_target = Some(Box::new(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: func_name, args, distinct: false, @@ -12735,6 +12918,10 @@ impl Parser { let args = self.parse_expression_list()?; self.expect(TokenType::RParen)?; return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "REPLACE".to_string(), args, distinct: false, @@ -14129,7 +14316,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -14235,7 +14425,10 @@ impl Parser { temporary, or_replace, table_modifier: Some("EXTERNAL".to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), // BigQuery EXTERNAL tables don't support AS SELECT as_select: None, as_select_parenthesized: false, @@ -14302,7 +14495,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -14513,7 +14709,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -14629,7 +14828,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: Some(query), as_select_parenthesized, on_commit, @@ -14695,7 +14897,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select, as_select_parenthesized, on_commit: None, @@ -14783,7 +14988,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select, as_select_parenthesized: false, on_commit: None, @@ -14831,7 +15039,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -14877,7 +15088,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -14939,7 +15153,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select, as_select_parenthesized: false, on_commit: None, @@ -14996,7 +15213,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: Some(query), as_select_parenthesized: true, on_commit: None, @@ -15139,7 +15359,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -16207,7 +16430,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select, as_select_parenthesized: false, on_commit, @@ -16360,7 +16586,10 @@ impl Parser { temporary, or_replace, table_modifier: table_modifier.map(|s| s.to_string()), - hana_storage: self.config.dialect == Some(crate::dialects::DialectType::HANA), + source_dialect: self + .config + .dialect + .filter(|d| *d == crate::dialects::DialectType::HANA), as_select: None, as_select_parenthesized: false, on_commit: None, @@ -18644,6 +18873,10 @@ impl Parser { // Create a Function expression for BUCKET/TRUNCATE partition_exprs.push(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: func_name, args, distinct: false, @@ -26301,7 +26534,8 @@ impl Parser { if member.is_some() && (asynchronous || !hints.is_empty()) { return Err(self.parse_error("Library member CALL does not support ASYNC or hints")); } - return Ok(Expression::HanaCall(Box::new(HanaCall { + return Ok(Expression::Call(Box::new(Call { + source_dialect: self.config.dialect, name, member, arguments, @@ -30350,8 +30584,10 @@ impl Parser { let negated = self.match_token(TokenType::Not); self.skip(); let mut regex = self.parse_hana_regex("LIKE_REGEXPR", Some(left))?; - if let Expression::HanaRegex(ref mut r) = regex { - r.negated = negated; + if let Expression::RegexpLike(ref mut r) = regex { + if let Some(options) = &mut r.options { + options.negated = negated; + } } regex } else if self.match_token(TokenType::Eq) { @@ -30690,6 +30926,8 @@ impl Parser { // PostgreSQL ~ (regexp match) operator / RLIKE / REGEXP let right = self.parse_bitwise_or()?; Expression::RegexpLike(Box::new(RegexpFunc { + options: None, + this: left, pattern: right, flags: None, @@ -30703,6 +30941,8 @@ impl Parser { self.skip(); // consume REGEXP_LIKE let right = self.parse_bitwise_or()?; Expression::RegexpLike(Box::new(RegexpFunc { + options: None, + this: left, pattern: right, flags: None, @@ -30751,6 +30991,8 @@ impl Parser { // PostgreSQL !~ (NOT regexp match) operator let right = self.parse_bitwise_or()?; let regexp_expr = Expression::RegexpLike(Box::new(RegexpFunc { + options: None, + this: left, pattern: right, flags: None, @@ -31036,6 +31278,8 @@ impl Parser { } else if self.match_token(TokenType::RLike) { let right = self.parse_bitwise_or()?; let regexp_expr = Expression::RegexpLike(Box::new(RegexpFunc { + options: None, + this: left, pattern: right, flags: None, @@ -33442,7 +33686,8 @@ impl Parser { { let mut function = Function::new(self.advance()?.text, Vec::new()); function.no_parens = true; - return Ok(Expression::HanaFunction(Box::new(function))); + function.source_dialect = self.config.dialect; + return Ok(Expression::Function(Box::new(function))); } if !(self.config.dialect == Some(crate::dialects::DialectType::HANA) && self.check(TokenType::QuotedIdentifier)) @@ -33456,6 +33701,10 @@ impl Parser { { let token = self.advance()?; let func = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: token.text.to_string(), args: Vec::new(), distinct: false, @@ -33514,6 +33763,10 @@ impl Parser { let args = self.parse_function_args_list()?; self.expect(TokenType::RParen)?; return self.maybe_parse_over(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: dynamic_name, args, distinct: false, @@ -33968,7 +34221,8 @@ impl Parser { }; let mut function = Function::new(name, args); function.no_parens = !parenthesized; - return Ok(Expression::HanaFunction(Box::new(function))); + function.source_dialect = self.config.dialect; + return Ok(Expression::Function(Box::new(function))); } // Handle APPROXIMATE COUNT(DISTINCT expr) - Redshift syntax // Parses as ApproxDistinct expression @@ -33991,6 +34245,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; let func = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: format!("APPROXIMATE {}", name), args, distinct: false, @@ -34403,6 +34661,10 @@ impl Parser { let predicate = self.parse_expression()?; self.expect(TokenType::RParen)?; return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "EXISTS".to_string(), args: vec![array_expr, predicate], distinct: false, @@ -34748,6 +35010,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; let func_expr = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "ROW".to_string(), args, distinct: false, @@ -35285,6 +35551,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; let func = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: token.text.to_string(), // Preserve original case; generator handles normalization args, distinct: false, @@ -35311,6 +35581,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; let func = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: token.text.to_string(), args, distinct: false, @@ -35343,6 +35617,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; let func = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: token.text.to_string(), args, distinct: false, @@ -35399,6 +35677,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; let func = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: token.text.to_string(), args, distinct: false, @@ -35414,6 +35696,10 @@ impl Parser { // No parens - parse as no-paren function let token = self.advance()?; let func = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: token.text.to_string(), args: Vec::new(), distinct: false, @@ -36088,6 +36374,10 @@ impl Parser { let args = self.parse_function_args_list()?; self.expect(TokenType::RParen)?; return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: token.text, args, distinct: false, @@ -36139,6 +36429,10 @@ impl Parser { if self.check(TokenType::RParen) { self.skip(); return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -36199,6 +36493,10 @@ impl Parser { } Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -36544,6 +36842,10 @@ impl Parser { all_args.extend(remaining); self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: all_args, distinct: false, @@ -36655,6 +36957,10 @@ impl Parser { let dimension = self.parse_expression()?; self.expect(TokenType::RParen)?; return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![this, dimension], distinct: false, @@ -36819,6 +37125,10 @@ impl Parser { self.expect(TokenType::RParen)?; // Treat as function call Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![this], distinct: false, @@ -36863,6 +37173,10 @@ impl Parser { let mut args = vec![part, from_expr]; self.normalize_date_part_arg("DATE_PART", &mut args); Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "DATE_PART".to_string(), args, distinct: false, @@ -36900,6 +37214,10 @@ impl Parser { let mut args = vec![first_arg, second_arg, third_arg]; self.normalize_date_part_arg(name, &mut args); Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -36914,6 +37232,10 @@ impl Parser { // BigQuery 2-arg syntax: DATE_ADD(date, interval) self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![first_arg, second_arg], distinct: false, @@ -36962,6 +37284,10 @@ impl Parser { } self.normalize_date_part_arg(name, &mut args); Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37056,6 +37382,10 @@ impl Parser { if self.check(TokenType::RParen) { self.skip(); return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![], distinct: false, @@ -37071,6 +37401,10 @@ impl Parser { if !self.check(TokenType::Comma) && self.check(TokenType::RParen) { self.skip(); return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![first], distinct: false, @@ -37167,6 +37501,10 @@ impl Parser { } self.expect(TokenType::RParen)?; return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37215,6 +37553,10 @@ impl Parser { let args = self.parse_function_arguments()?; self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37293,6 +37635,10 @@ impl Parser { )))) } else { Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37310,6 +37656,10 @@ impl Parser { self.expect(TokenType::RParen)?; if args.len() > 2 { Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "COALESCE".to_string(), args, distinct: false, @@ -37331,6 +37681,10 @@ impl Parser { )))) } else { Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37357,6 +37711,10 @@ impl Parser { )))) } else { Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37387,6 +37745,10 @@ impl Parser { let args = self.parse_function_arguments()?; self.expect(TokenType::RParen)?; return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37407,6 +37769,10 @@ impl Parser { let args = self.parse_expression_list()?; self.expect(TokenType::RParen)?; return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37439,6 +37805,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37469,6 +37839,10 @@ impl Parser { )))) } else { Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37500,6 +37874,10 @@ impl Parser { )))) } else { Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -37549,6 +37927,10 @@ impl Parser { } else { self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: Vec::new(), distinct: false, @@ -37588,6 +37970,10 @@ impl Parser { } self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "XMLATTRIBUTES".to_string(), args: attrs, distinct: false, @@ -37607,6 +37993,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "XMLCOMMENT".to_string(), args, distinct: false, @@ -37637,6 +38027,10 @@ impl Parser { if !self.check_keyword_text("AGAINST") { return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "MATCH".to_string(), args: expressions, distinct: false, @@ -37734,6 +38128,10 @@ impl Parser { })))) } else { Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: expressions, distinct: false, @@ -37804,6 +38202,10 @@ impl Parser { args.push(s); } return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: func_name.to_string(), args, distinct: false, @@ -37845,6 +38247,10 @@ impl Parser { self.expect(TokenType::RParen)?; let func_name = if is_try { "TRY_CONVERT" } else { "CONVERT" }; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: func_name.to_string(), args, distinct: false, @@ -37859,6 +38265,10 @@ impl Parser { self.expect(TokenType::RParen)?; let func_name = if is_try { "TRY_CONVERT" } else { "CONVERT" }; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: func_name.to_string(), args: vec![this], distinct: false, @@ -38006,6 +38416,10 @@ impl Parser { } else { self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![this, replacement], distinct: false, @@ -38020,6 +38434,10 @@ impl Parser { } else { self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![this], distinct: false, @@ -38062,6 +38480,10 @@ impl Parser { let args = self.parse_expression_list()?; self.expect(TokenType::RParen)?; Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -38093,6 +38515,10 @@ impl Parser { if self.check(TokenType::RParen) { self.skip(); return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![], distinct: false, @@ -38174,6 +38600,10 @@ impl Parser { fn make_unquoted_function(name: &str, args: Vec) -> Expression { Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -38193,6 +38623,8 @@ impl Parser { filter: Option, ) -> Expression { Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: name.to_string(), args, distinct, @@ -38349,11 +38781,13 @@ impl Parser { quoted: bool, ) -> Result { if quoted { - let expression = self.parse_generic_function(name, true)?; - return Ok(match expression { - Expression::Function(function) => Expression::HanaFunction(function), - other => other, - }); + let mut expression = self.parse_generic_function(name, true)?; + if let Expression::Function(function) = &mut expression { + let mut identifier = Identifier::new(name); + identifier.quoted = true; + function.qualified_name = vec![identifier]; + } + return Ok(expression); } if matches!(upper_name, "LOCALTOUTC" | "UTCTOLOCAL") { return self.parse_hana_timezone(upper_name); @@ -38400,7 +38834,7 @@ impl Parser { ) { let expr = self.parse_generic_function(name, false)?; - if let Expression::Function(f) = expr { + if let Expression::Function(mut f) = expr { let arity_valid = match upper_name { "LOCATE" => (2..=4).contains(&f.args.len()), "SUBSTRING" | "SUBSTR" => (2..=3).contains(&f.args.len()), @@ -38424,13 +38858,18 @@ impl Parser { self.parse_error(format!("Invalid arguments for HANA {upper_name}")) ); } - return Ok(Expression::HanaFunction(f)); + f.source_dialect = self.config.dialect; + return Ok(Expression::Function(f)); } return Ok(match expr { - Expression::AggregateFunction(f) => Expression::HanaAggregateFunction(f), + Expression::AggregateFunction(mut f) => { + f.source_dialect = self.config.dialect; + Expression::AggregateFunction(f) + } Expression::WithinGroup(mut w) => { - if let Expression::AggregateFunction(f) = w.this { - w.this = Expression::HanaAggregateFunction(f); + if let Expression::AggregateFunction(mut f) = w.this { + f.source_dialect = self.config.dialect; + w.this = Expression::AggregateFunction(f); } Expression::WithinGroup(w) } @@ -38521,6 +38960,10 @@ impl Parser { } _ => { return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -38642,6 +39085,10 @@ impl Parser { self.expect(TokenType::RParen)?; // Multiple args without DISTINCT - treat as generic function return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -38732,6 +39179,8 @@ impl Parser { || filter.is_some() { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: name.to_string(), args, distinct, @@ -38743,6 +39192,10 @@ impl Parser { }))) } else { Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -38777,6 +39230,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -38799,6 +39256,10 @@ impl Parser { // Pass the query directly as an argument to ARRAY function // The generator will handle it correctly return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![query], distinct: false, @@ -38871,6 +39332,10 @@ impl Parser { })); return Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: vec![subquery], distinct: false, @@ -38895,6 +39360,10 @@ impl Parser { }; self.expect(TokenType::RParen)?; Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -38966,6 +39435,10 @@ impl Parser { Some(crate::dialects::DialectType::ClickHouse) ) { Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: Vec::new(), distinct: false, @@ -39046,6 +39519,8 @@ impl Parser { if is_duckdb_top_n { let filter = self.parse_filter_clause()?; Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: name.to_string(), args, distinct, @@ -39057,6 +39532,10 @@ impl Parser { }))) } else { Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -39412,6 +39891,10 @@ impl Parser { self.expect(TokenType::RParen)?; let trailing_comments = self.previous_trailing_comments().to_vec(); Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -39719,6 +40202,10 @@ impl Parser { } self.expect(TokenType::RParen)?; let func_expr = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -39808,6 +40295,9 @@ impl Parser { self.expect(TokenType::RParen)?; let func = JsonExtractFunc { + options: None, + source_dialect: None, + this, path, returning, @@ -39842,6 +40332,10 @@ impl Parser { all_args.extend(remaining); self.expect(TokenType::RParen)?; Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args: all_args, distinct: false, @@ -40258,6 +40752,9 @@ impl Parser { self.expect(TokenType::RParen)?; Ok(Expression::JSONTable(Box::new(JSONTable { + options: None, + source_dialect: None, + this: Box::new(this_with_format), schema: schema.map(Box::new), path, @@ -40312,6 +40809,10 @@ impl Parser { } self.expect(TokenType::RParen)?; Ok(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: name.to_string(), args, distinct: false, @@ -40447,6 +40948,8 @@ impl Parser { self.expect(TokenType::RParen)?; let func_expr = Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: name.to_string(), args, distinct, @@ -40466,6 +40969,8 @@ impl Parser { let filter = self.parse_filter_clause()?; if let Some(filter_expr) = filter { return Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: format!("__WITHIN_GROUP_{}", name), args: vec![within, filter_expr], distinct: false, @@ -40496,6 +41001,8 @@ impl Parser { if filter.is_some() || is_known_agg || ignore_nulls.is_some() { Ok(Expression::AggregateFunction(Box::new(AggregateFunction { + source_dialect: None, + name: name.to_string(), args, distinct, @@ -40573,7 +41080,8 @@ impl Parser { let name = self.expect_identifier_with_quoted()?; self.expect(TokenType::FArrow)?; let value = self.parse_expression()?; - return Ok(Expression::HanaPlaceholder(Box::new(HanaPlaceholder { + return Ok(Expression::ViewParameter(Box::new(ViewParameter { + source_dialect: self.config.dialect, name, value, }))); @@ -41416,6 +41924,10 @@ impl Parser { let values = self.parse_expression()?; self.expect(TokenType::RBracket)?; expr = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "MAP".to_string(), args: vec![keys, values], distinct: false, @@ -41893,6 +42405,9 @@ impl Parser { // Use parse_json_path_operand to get only the immediate operand for proper left-to-right associativity let path = self.parse_json_path_operand()?; expr = Expression::JsonExtract(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this: expr, path, returning: None, @@ -41908,6 +42423,9 @@ impl Parser { // Use parse_json_path_operand to get only the immediate operand for proper left-to-right associativity let path = self.parse_json_path_operand()?; expr = Expression::JsonExtractScalar(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this: expr, path, returning: None, @@ -41932,6 +42450,9 @@ impl Parser { // Use parse_json_path_operand to get only the immediate operand for proper left-to-right associativity let path = self.parse_json_path_operand()?; expr = Expression::JsonExtractScalar(Box::new(JsonExtractFunc { + options: None, + source_dialect: None, + this: expr, path, returning: None, @@ -52245,9 +52766,15 @@ impl Parser { self.expect(TokenType::RParen)?; if is_cube { - Ok(Some(Expression::Cube(Box::new(Cube { expressions })))) + Ok(Some(Expression::Cube(Box::new(Cube { + options: None, + expressions, + })))) } else { - Ok(Some(Expression::Rollup(Box::new(Rollup { expressions })))) + Ok(Some(Expression::Rollup(Box::new(Rollup { + options: None, + expressions, + })))) } } @@ -53628,6 +54155,10 @@ impl Parser { if !self.check_next(TokenType::LParen) { self.skip(); return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name, // Preserve original case; generator handles normalization args: Vec::new(), distinct: false, @@ -53676,6 +54207,10 @@ impl Parser { // Handle window specifications let func_expr = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name, // Preserve original case; generator handles normalization args, distinct, @@ -54208,6 +54743,8 @@ impl Parser { self.expect(TokenType::RParen)?; Ok(Some(Expression::GroupingSets(Box::new(GroupingSets { + options: None, + expressions, })))) } @@ -54342,6 +54879,8 @@ impl Parser { let hint_text = parts.join(" "); Ok(Some(Expression::Hint(Box::new(Hint { + source_dialect: None, + expressions: vec![HintExpression::Raw(hint_text)], })))) } @@ -54555,6 +55094,10 @@ impl Parser { if self.check(TokenType::RParen) { self.skip(); // consume RParen return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: original_name.clone().unwrap_or_else(|| "IF".to_string()), args: vec![], distinct: false, @@ -54587,6 +55130,10 @@ impl Parser { })))); } else if args.len() == 1 { return Ok(Some(Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: original_name.clone().unwrap_or_else(|| "IF".to_string()), args, distinct: false, @@ -55216,6 +55763,12 @@ impl Parser { pub fn parse_json_column_def(&mut self) -> Result> { if self.match_text_seq(&["NESTED"]) { return Ok(Some(Expression::JSONColumnDef(Box::new(JSONColumnDef { + source_dialect: None, + + data_type: None, + encoding: None, + options: None, + this: None, kind: None, format_json: false, @@ -55466,6 +56019,12 @@ impl Parser { let nested_schema = self.parse_json_table_columns()?; return Ok(Some(Expression::JSONColumnDef(Box::new(JSONColumnDef { + source_dialect: None, + + data_type: None, + encoding: None, + options: None, + this: None, kind: None, format_json: false, @@ -55509,6 +56068,12 @@ impl Parser { }; Ok(Some(Expression::JSONColumnDef(Box::new(JSONColumnDef { + source_dialect: None, + + data_type: None, + encoding: None, + options: None, + this: name.map(Box::new), kind, format_json, @@ -55573,6 +56138,9 @@ impl Parser { let schema = self.parse_json_schema()?; Ok(Some(Expression::JSONTable(Box::new(JSONTable { + options: None, + source_dialect: None, + this: Box::new(this), schema: schema.map(Box::new), path, @@ -55608,6 +56176,9 @@ impl Parser { }; Ok(Some(Expression::JSONValue(Box::new(JSONValue { + options: None, + source_dialect: None, + this: Box::new(this), path: Some(Box::new(path)), returning, @@ -58310,6 +58881,13 @@ impl Parser { pub fn parse_pipe_syntax_aggregate(&mut self) -> Result> { if self.match_text_seq(&["AGGREGATE"]) { return Ok(Some(Expression::Select(Box::new(Select { + source_dialect: None, + total_rowcount: false, + + query_collation: None, + query_hints: Vec::new(), + result_serialization: None, + expressions: Vec::new(), from: None, joins: Vec::new(), @@ -58341,7 +58919,7 @@ impl Parser { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), - hana_options: None, + leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, @@ -58434,6 +59012,13 @@ impl Parser { pub fn parse_pipe_syntax_extend(&mut self) -> Result> { if self.match_text_seq(&["EXTEND"]) { return Ok(Some(Expression::Select(Box::new(Select { + source_dialect: None, + total_rowcount: false, + + query_collation: None, + query_hints: Vec::new(), + result_serialization: None, + expressions: Vec::new(), from: None, joins: Vec::new(), @@ -58465,7 +59050,7 @@ impl Parser { locks: Vec::new(), for_xml: Vec::new(), for_json: Vec::new(), - hana_options: None, + leading_comments: Vec::new(), post_select_comments: Vec::new(), kind: None, @@ -62392,6 +62977,10 @@ impl Parser { self.expect(TokenType::RParen)?; let func_expr = Expression::Function(Box::new(Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: func_name, args, distinct: false, @@ -64472,7 +65061,10 @@ impl Parser { } Ok(Some(Expression::PartitionByProperty(Box::new( - PartitionByProperty { expressions }, + PartitionByProperty { + specification: None, + expressions, + }, )))) } diff --git a/crates/polyglot-sql/src/transforms.rs b/crates/polyglot-sql/src/transforms.rs index 1ffb8489..24f548f0 100644 --- a/crates/polyglot-sql/src/transforms.rs +++ b/crates/polyglot-sql/src/transforms.rs @@ -3749,6 +3749,10 @@ pub fn no_ilike_sql(expr: Expression) -> Result { Expression::ILike(ilike) => { // Create LOWER(left) LIKE LOWER(right) let lower_left = Expression::Function(Box::new(crate::expressions::Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "LOWER".to_string(), args: vec![ilike.left], distinct: false, @@ -3761,6 +3765,10 @@ pub fn no_ilike_sql(expr: Expression) -> Result { })); let lower_right = Expression::Function(Box::new(crate::expressions::Function { + on_error: None, + qualified_name: Vec::new(), + source_dialect: None, + name: "LOWER".to_string(), args: vec![ilike.right], distinct: false, diff --git a/crates/polyglot-sql/src/traversal.rs b/crates/polyglot-sql/src/traversal.rs index de27f689..acebe63a 100644 --- a/crates/polyglot-sql/src/traversal.rs +++ b/crates/polyglot-sql/src/traversal.rs @@ -480,15 +480,7 @@ pub fn is_literal(expr: &Expression) -> bool { pub fn is_function(expr: &Expression) -> bool { matches!( expr, - Expression::Function(_) - | Expression::HanaFunction(_) - | Expression::AggregateFunction(_) - | Expression::HanaAggregateFunction(_) - | Expression::HanaJson(_) - | Expression::HanaTableFunction(_) - | Expression::HanaHierarchy(_) - | Expression::HanaTimezone(_) - | Expression::HanaRegex(_) + Expression::Function(_) | Expression::AggregateFunction(_) | Expression::Hierarchy(_) ) } @@ -511,7 +503,6 @@ pub fn is_aggregate(expr: &Expression) -> bool { matches!( expr, Expression::AggregateFunction(_) - | Expression::HanaAggregateFunction(_) | Expression::Count(_) | Expression::Sum(_) | Expression::Avg(_) diff --git a/crates/polyglot-sql/src/validation.rs b/crates/polyglot-sql/src/validation.rs index 4dbec295..38f17220 100644 --- a/crates/polyglot-sql/src/validation.rs +++ b/crates/polyglot-sql/src/validation.rs @@ -2582,7 +2582,7 @@ fn check_types( )); } } - Expression::Function(function) | Expression::HanaFunction(function) => { + Expression::Function(function) => { check_function_catalog(function, dialect, function_catalog, strict, &mut errors); check_generic_function(function, schema_map, &context, strict, &mut errors); } diff --git a/crates/polyglot-sql/tests/dialect_matrix.rs b/crates/polyglot-sql/tests/dialect_matrix.rs index 81919074..0906746e 100644 --- a/crates/polyglot-sql/tests/dialect_matrix.rs +++ b/crates/polyglot-sql/tests/dialect_matrix.rs @@ -4919,6 +4919,151 @@ mod hana_regressions { use polyglot_sql::expressions::Expression; use polyglot_sql::ExpressionWalk; + #[test] + fn shared_function_nodes_participate_in_generic_analysis() { + use polyglot_sql::optimizer::{normalize_identifiers, TypeAnnotator}; + let hana = Dialect::get(DialectType::HANA); + let ast = hana + .parse("SELECT COALESCE(mixed, 1), mixed FROM tab") + .unwrap() + .remove(0); + assert!(ast.dfs().any(|e| matches!(e, Expression::Function(_)))); + let normalized = normalize_identifiers(ast, Some(DialectType::HANA)); + assert_eq!( + hana.generate(&normalized).unwrap(), + "SELECT COALESCE(MIXED, 1), MIXED FROM TAB" + ); + let ast = hana + .parse("SELECT COALESCE(1, 2) FROM DUMMY") + .unwrap() + .remove(0); + let call = ast + .dfs() + .find(|e| matches!(e, Expression::Function(_))) + .unwrap(); + assert_eq!(call.source_dialect(), Some(DialectType::HANA)); + assert!(matches!( + TypeAnnotator::new(None, Some(DialectType::HANA)).annotate(call), + Some(polyglot_sql::expressions::DataType::Int { .. }) + )); + for dialect in [DialectType::HANA, DialectType::PostgreSQL] { + let ast = Dialect::get(dialect) + .parse(r#"SELECT "f"(x) FROM t"#) + .unwrap() + .remove(0); + let call = ast + .dfs() + .find(|e| matches!(e, Expression::Function(_))) + .unwrap(); + assert_eq!( + call.source_dialect(), + None, + "quoted UDFs are not native built-ins" + ); + } + } + + #[test] + fn source_metadata_survives_optimizers_and_standalone_generation() { + use polyglot_sql::optimizer::{canonicalize, normalize_identifiers}; + let hana = Dialect::get(DialectType::HANA); + let trino = Dialect::get(DialectType::Trino); + let ast = hana + .parse("SELECT LOCATE('abcabc', 'bc', 1, 2) FROM DUMMY") + .unwrap() + .remove(0); + let ast = canonicalize( + normalize_identifiers(ast, Some(DialectType::HANA)), + Some(DialectType::HANA), + ); + let call = ast + .dfs() + .find(|e| matches!(e, Expression::Function(_))) + .unwrap(); + let json = serde_json::to_string(call).unwrap(); + assert!(json.contains("\"source_dialect\":\"hana\"")); + assert!(!json.contains("hana_function")); + let call: Expression = serde_json::from_str(&json).unwrap(); + assert_eq!(trino.generate(&call).unwrap(), "STRPOS('abcabc', 'bc', 2)"); + assert_eq!( + hana.generate(&call).unwrap(), + "LOCATE('abcabc', 'bc', 1, 2)" + ); + for sql in [ + "SELECT SUBSTR_REGEXPR('a' IN value OCCURRENCE 2) FROM t", + "SELECT JSON_VALUE(payload, '$.n' DEFAULT 0 ON EMPTY) FROM t", + "SELECT STRING_AGG(value, ',' ORDER BY id) FROM t", + ] { + let ast = hana.parse(sql).unwrap().remove(0); + let json = serde_json::to_string(&ast).unwrap(); + let decoded: Expression = serde_json::from_str(&json).unwrap(); + assert_eq!(hana.generate(&decoded).unwrap(), sql); + assert!(trino.generate(&decoded).is_err(), "{sql}"); + assert!(!decoded.dfs().any(|e| e.variant_name().starts_with("hana_"))); + } + } + + #[test] + fn create_table_traversal_is_independent_of_source_metadata() { + use polyglot_sql::ast_transforms::rename_columns; + let hana = Dialect::get(DialectType::HANA); + let ast = hana + .parse("CREATE TABLE t (value INT CHECK (value > 0))") + .unwrap() + .remove(0); + let mut outputs = Vec::new(); + for source in [None, Some(DialectType::HANA)] { + let mut ast = ast.clone(); + if let Expression::CreateTable(table) = &mut ast { + table.source_dialect = source; + } + let renamed = + rename_columns(ast, &[("value".to_owned(), "new_value".to_owned())].into()); + outputs.push(hana.generate(&renamed).unwrap()); + } + assert_eq!(outputs[0], outputs[1]); + assert!(outputs[0].contains("CHECK (new_value > 0)")); + } + + #[test] + fn native_syntax_uses_shared_expression_categories() { + let hana = Dialect::get(DialectType::HANA); + for (sql, expected) in [ + ("SELECT JSON_VALUE(j, '$.a') FROM t", "j_s_o_n_value"), + ("SELECT JSON_QUERY(j, '$.a') FROM t", "json_query"), + ( + "SELECT * FROM JSON_TABLE(j, '$' COLUMNS (v INT PATH '$.v'))", + "j_s_o_n_table", + ), + ( + "SELECT * FROM t WHERE value LIKE_REGEXPR 'a'", + "regexp_like", + ), + ( + "SELECT SUBSTR_REGEXPR('a' IN value) FROM t", + "regexp_extract", + ), + ( + "SELECT a FROM t GROUP BY ROLLUP STRUCTURED RESULT (a)", + "rollup", + ), + ("SELECT * FROM t WITH HINT (NO_INLINE)", "hint"), + ( + "CREATE TABLE t (id INT) PARTITION BY HASH (id) PARTITIONS 4", + "partition_by_property", + ), + ("CALL demo.proc(1)", "call"), + ("UPSERT t VALUES (1) WITH PRIMARY KEY", "upsert"), + ] { + let ast = hana.parse(sql).unwrap().remove(0); + assert!( + ast.dfs().any(|e| e.variant_name() == expected), + "{sql}: expected {expected}" + ); + assert_eq!(hana.generate(&ast).unwrap(), sql); + } + } + #[test] fn native_semantics_survive_transpile_and_json() { let hana = Dialect::get(DialectType::HANA); @@ -5035,11 +5180,15 @@ mod hana_regressions { #[test] fn quoted_reserved_names_and_qualified_calls_are_not_builtins() { - for sql in [ - r#"SELECT "CURRENT_USER", t.CURRENT_SCHEMA, demo."ADD_DAYS"(d, 1) FROM t"#, - r#"SELECT "COUNT"(x) FROM t"#, + for (sql, trino) in [ + ( + r#"SELECT "CURRENT_USER", t.CURRENT_SCHEMA, demo."ADD_DAYS"(d, 1) FROM t"#, + r#"SELECT "CURRENT_USER", t."CURRENT_SCHEMA", demo."ADD_DAYS"(d, 1) FROM t"#, + ), + (r#"SELECT "COUNT"(x) FROM t"#, r#"SELECT "COUNT"(x) FROM t"#), ] { assert_eq!(transpile(sql, DialectType::HANA, DialectType::HANA), sql); + assert_eq!(transpile(sql, DialectType::HANA, DialectType::Trino), trino); } } diff --git a/docs/hana/README.md b/docs/hana/README.md index 83824c15..347d64f7 100644 --- a/docs/hana/README.md +++ b/docs/hana/README.md @@ -63,8 +63,16 @@ rendered with `FROM DUMMY` for a HANA target. ## Translation policy -HANA-specific AST nodes retain source semantics through JSON serialization and -independent target generation. A known HANA function is not automatically treated +Shared AST nodes retain source semantics through serialized `source_dialect` +metadata and typed options, including during independent target generation. +Functions, aggregates, JSON, regex, grouping, hints, and partition properties use +the existing expression categories. Procedure calls, upserts, hierarchy queries, +view parameters, and storage properties have dialect-neutral node names. Native +data types retain `HanaDataType` because their domains and precision differ from +otherwise similar SQL types. TypeScript guards and Python expression classes use +these shared categories rather than HANA-specific counterparts. + +A known HANA function is not automatically treated as a compatible target function. Unverified mappings return an unsupported error, including at `Ignore` and `Warn`, rather than silently dropping a result-shaping clause or emitting a known incompatible operation. Checks run before target @@ -124,11 +132,13 @@ Verified locally on 2026-09-22: - `make test-rust-verify`, including existing SQLGlot fixtures, the 132 native HANA fixtures, ClickHouse parser and round-trip suites, and FFI tests. -- All 12 focused HANA regression tests in `dialect_matrix.rs`. +- All 16 focused HANA regression tests in `dialect_matrix.rs`, including generic + identifier normalization, type annotation, traversal, and source metadata + preservation across optimization and standalone JSON AST generation. - Parse-only, generation, and transpilation builds with only `dialect-hana`, plus a HANA-only WASM discovery/native parsing test. - Rebuilt WASM and TypeScript SDK: 613 tests; TypeScript type checking. -- Rebuilt Python extension: 321 tests passed, one skipped; Python type checking. +- Rebuilt Python extension: 322 tests passed, one skipped; Python type checking. - Go tests against the rebuilt FFI library, with the test cache disabled. - Formatting, project consistency, and unchanged released changelog entries. diff --git a/packages/go/integration_test.go b/packages/go/integration_test.go index f7708159..b951c3cd 100644 --- a/packages/go/integration_test.go +++ b/packages/go/integration_test.go @@ -1562,4 +1562,30 @@ func TestIntegrationHana(t *testing.T) { if err != nil || len(output) != 1 || output[0] != "SELECT STRPOS('abcabc', 'bc')" { t.Fatalf("HANA LOCATE: %v, %v", output, err) } + for _, tc := range []struct{ sql, target, want string }{ + {"SELECT LOCATE('abcabc', 'bc', 1, 2)", "trino", "SELECT STRPOS('abcabc', 'bc', 2)"}, + {sql, "duckdb", ""}, + } { + parsed, err := client.Parse(tc.sql, "hana") + if err != nil { + t.Fatal(err) + } + var decoded any + if err := json.Unmarshal(parsed, &decoded); err != nil { + t.Fatal(err) + } + serialized, err := json.Marshal(decoded) + if err != nil { + t.Fatal(err) + } + // Independent generation receives only the serialized AST and target. + generated, err := client.Generate(serialized, tc.target) + if tc.want == "" { + if err == nil { + t.Fatal("serialized AST lost unsupported source semantics") + } + } else if err != nil || len(generated) != 1 || generated[0] != tc.want { + t.Fatalf("serialized HANA AST generation: %v, %v", generated, err) + } + } } diff --git a/packages/sdk/plugins/wasmCjsPlugin.ts b/packages/sdk/plugins/wasmCjsPlugin.ts index 1b12e9d6..31032b3d 100644 --- a/packages/sdk/plugins/wasmCjsPlugin.ts +++ b/packages/sdk/plugins/wasmCjsPlugin.ts @@ -100,6 +100,17 @@ export function wasmCjsPlugin(): Plugin { '\n', ); + // wasm-bindgen may emit a startup call as well. Its export is only + // available after instantiation, just like the deferred bindings above. + if (code.includes('\n__wbindgen_start();\n')) { + code = code.replace('\n__wbindgen_start();\n', '\n'); + code = code.replace( + ' __wbg_set_wasm(__vite__wasmModule);', + ' __wbg_set_wasm(__vite__wasmModule);\n' + + ' __vite__wasmModule.__wbindgen_start();', + ); + } + // ── Transform 5: Replace init() and isInitialized() ───────── code = code.replace( /async function init\(\)\s*\{[\s\S]*?return Promise\.resolve\(\);\s*\}/, diff --git a/packages/sdk/src/ast/types/guards.ts b/packages/sdk/src/ast/types/guards.ts index 8110a601..523e89b0 100644 --- a/packages/sdk/src/ast/types/guards.ts +++ b/packages/sdk/src/ast/types/guards.ts @@ -178,23 +178,6 @@ export const isExists = isType('exists'); /** Type guard for generic function calls */ export const isFunction = isType('function'); -/** HANA source nodes retain dialect-specific semantics until generation. */ -export const isHanaFunction = isType('hana_function'); -export const isHanaAggregateFunction = isType('hana_aggregate_function'); -export const isHanaJson = isType('hana_json'); -export const isHanaHierarchy = isType('hana_hierarchy'); -export const isHanaUpsert = isType('hana_upsert'); -export const isHanaGrouping = isType('hana_grouping'); -export const isHanaTimezone = isType('hana_timezone'); -export const isHanaRegex = isType('hana_regex'); -export const isHanaJsonColumn = isType('hana_json_column'); -export const isHanaPartition = isType('hana_partition'); -export const isHanaStorageProperty = isType('hana_storage_property'); -export const isHanaPlaceholder = isType('hana_placeholder'); -export const isHanaTableFunction = isType('hana_table_function'); -export const isHanaCall = isType('hana_call'); -export const isHanaHint = isType('hana_hint'); - /** Type guard for aggregate function calls */ export const isAggregateFunction = isType('aggregate_function'); @@ -318,7 +301,7 @@ export function isQuery(expr: Expression): boolean { t === 'insert' || t === 'update' || t === 'delete' || - t === 'hana_upsert' + t === 'upsert' ); } diff --git a/packages/sdk/src/ast/visitor/visitor.test.ts b/packages/sdk/src/ast/visitor/visitor.test.ts index fc897dfb..4c3148ec 100644 --- a/packages/sdk/src/ast/visitor/visitor.test.ts +++ b/packages/sdk/src/ast/visitor/visitor.test.ts @@ -18,7 +18,7 @@ import { isExpressionValue, makeExpr, } from '../helpers'; -import { isExpressionType } from '../types/guards'; +import { isExpressionType, isFunction } from '../types/guards'; import { addSelectColumns, addWhere, @@ -1460,18 +1460,19 @@ describe('Integration Tests', () => { }); describe('HANA AST traversal', () => { - it('visits and replaces arguments retained in HANA source nodes', () => { + it('uses shared node guards and retains source semantics after JSON serialization', () => { const sql = "SELECT LOCATE(value, 'a', 1, 2), JSON_VALUE(payload, '$.n' DEFAULT 0 ON EMPTY) FROM records"; const ast = parseFirstWithDialect(sql, Dialect.HANA); + expect(findAll(ast, isFunction)).toHaveLength(1); + const call = findAll(ast, isFunction)[0]; + if (!isFunction(call)) throw new Error('Expected shared Function node'); + expect(call.function.source_dialect).toBe('hana'); expect( - findAll(ast, (node) => isExpressionType(node, 'hana_function')), - ).toHaveLength(1); - expect( - findAll(ast, (node) => isExpressionType(node, 'hana_json')), + findAll(ast, (node) => isExpressionType(node, 'j_s_o_n_value')), ).toHaveLength(1); expect(getColumns(ast).map(columnReference)).toEqual(['value', 'payload']); - const copied = clone(ast); + const copied: Expression = JSON.parse(JSON.stringify(clone(ast))); expect(generate([copied], Dialect.HANA)).toEqual( generate([ast], Dialect.HANA), ); From c911978f58a4548de027fc5e57135d908c0a0a0d Mon Sep 17 00:00:00 2001 From: tobilg Date: Tue, 22 Sep 2026 17:44:28 +0200 Subject: [PATCH 3/8] Cleanup --- CHANGELOG.md | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 911e4dbf..05cf2c33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,21 +4,6 @@ All notable changes to this project are documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning. -## [Unreleased] - -### Added - -- Initial SAP HANA Cloud and Platform dialect support, based on - [PR #276](https://github.com/tobilg/polyglot/pull/276): source-aware functions and - types, JSON operations and query serialization, UPSERT, range/hash partitioning, - hierarchy queries, calculation-view parameters, regex operations, hints, and - locking clauses. HANA is discoverable through Rust, WASM, Python, Go/FFI, and - the TypeScript SDK. The [coverage guide](docs/hana/README.md) records supported - forms and remaining reference gaps. -- Verified HANA scalar translations and explicit errors for unverified conversions, - including preservation of decimal truncation, string positions, type domains, - UTC meaning, and timestamp precision. - ## [0.12.1] - 2026-09-21 ### Added From 8b91bf5a798138b1618e2ce1ce37223d18e79705 Mon Sep 17 00:00:00 2001 From: tobilg Date: Tue, 22 Sep 2026 17:50:26 +0200 Subject: [PATCH 4/8] Cleanup --- README.md | 2 - docs/hana/README.md | 158 - docs/hana/cloud-reference.json | 6824 -------------------------------- docs/hana/functions.json | 1795 --------- docs/hana/statements.json | 1042 ----- 5 files changed, 9821 deletions(-) delete mode 100644 docs/hana/README.md delete mode 100644 docs/hana/cloud-reference.json delete mode 100644 docs/hana/functions.json delete mode 100644 docs/hana/statements.json diff --git a/README.md b/README.md index 3cac1580..19309ae8 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,6 @@ Release notes are tracked in [`CHANGELOG.md`](CHANGELOG.md). | SQLite | StarRocks | Tableau | Teradata | TiDB | | Trino | TSQL | DataFusion | Generic SQL | SAP HANA | -SAP HANA coverage and translation limits are documented in [the HANA support guide](docs/hana/README.md). - ## Quick Start ### Rust diff --git a/docs/hana/README.md b/docs/hana/README.md deleted file mode 100644 index 347d64f7..00000000 --- a/docs/hana/README.md +++ /dev/null @@ -1,158 +0,0 @@ -# SAP HANA support - -The `hana` dialect targets SAP HANA Cloud QRC 2/2026 and HANA Platform 2.0 SPS 08. -`hana`, `saphana`, and `sap_hana` are accepted Rust dialect names. The public SDK -name is `hana` (`Dialect.HANA` in TypeScript). - -This implementation starts from [Torsten Glunde's PR #276](https://github.com/tobilg/polyglot/pull/276), -reviewed at `a452c0acd0a38892ef05e424b5ba94dc247bf3f0`, and replaces its unconditional -function and custom-type rewrites. Parser, expression, and generator changes are -integrated into the existing shared files. - -## Coverage and limits - -**This is not complete coverage of either SQL reference.** The inventories below -track the reference surface, including remaining work. Recognizing a function name, -parsing one example, and implementing every documented form are different levels -of support. A successful parse does not validate server privileges, object -existence, installed components, or runtime argument values. - -Native forms covered by regression tests include: - -- Ordinary queries, joins, CTEs, aggregates, window functions, common DML, and - basic table/view DDL, using the existing shared AST. -- HANA function calls with source provenance, including conversion, date/time, - string, bitwise, series-generation, and vector function names. Special argument - grammars need explicit parser support; registration alone does not provide it. -- `LOCATE` with two to four arguments; `SUBSTRING`/`SUBSTR`; decimal and formatted - date/string conversions; local and UTC current-time expressions and precision. -- Native numeric, string, LOB, spatial, and vector type names, including HANA's - unsigned `TINYINT`, precision-dependent `FLOAT`, and floating-decimal types. -- `FOR JSON`/`FOR XML`, including options and `RETURNS`; `WITH HINT`; query collation; - `FOR UPDATE` and `FOR SHARE LOCK`, including `IGNORE LOCKED`; `LIMIT ... TOTAL ROWCOUNT`. -- Grouping-set, rollup, and cube selection options (`BEST`, `LIMIT`, `OFFSET`, - subtotal/balance/total), structured results, prefixes, and multiple result sets. -- `LOCALTOUTC` and `UTCTOLOCAL` dataset/schema arguments and `ON ERROR` policies. -- `JSON_VALUE`, `JSON_QUERY`, and `JSON_TABLE`, with structured paths, return types, - wrapper behavior, defaults, error/empty behavior, ordinality, and nested columns. -- `UPSERT` values/query forms, partition and column lists, conditions, and - `WITH PRIMARY KEY`. -- Row/column and local/global temporary table modifiers; parenthesized `ALTER - TABLE ... ADD`; postfix array types; hash, round-robin, and balanced range - partitioning, subpartitioning, selected storage properties, and generated columns. -- Boolean `UNKNOWN` as the documented synonym for `NULL`, while retaining quoted names. -- `LIKE_REGEXPR`, `SUBSTR_REGEXPR`/`SUBSTRING_REGEXPR`, `LOCATE_REGEXPR`, - `OCCURRENCES_REGEXPR`, and `REPLACE_REGEXPR` clauses. -- `HIERARCHY` and `HIERARCHY_SPANTREE` source/options syntax; calculation-view - `PLACEHOLDER` arguments and qualified, quoted table function names. -- Procedure and library-member `CALL`, including asynchronous calls and hints. - -Remaining gaps include administrative and access-control grammar, advanced table, -view, index and temporal DDL, heterogeneous partition trees, association paths, -series specifications inside aggregates/windows, -additional hierarchy families, spatial method mappings, advanced search scoring, and special function -clauses. Procedure/function definitions are not implemented by the supported -`CALL` syntax. These are not covered merely because another spelling or a simpler -form parses. SQLScript body grammar is outside this dialect's scope. - -Unknown statement fallbacks that would produce `Raw` or `Command` nodes are -rejected. Unsupported forms can therefore fail native parsing rather than appear -to have structured support. The shared parser is permissive and is not a complete -HANA grammar validator; for example, accepted SELECTs without a FROM clause are -rendered with `FROM DUMMY` for a HANA target. - -## Translation policy - -Shared AST nodes retain source semantics through serialized `source_dialect` -metadata and typed options, including during independent target generation. -Functions, aggregates, JSON, regex, grouping, hints, and partition properties use -the existing expression categories. Procedure calls, upserts, hierarchy queries, -view parameters, and storage properties have dialect-neutral node names. Native -data types retain `HanaDataType` because their domains and precision differ from -otherwise similar SQL types. TypeScript guards and Python expression classes use -these shared categories rather than HANA-specific counterparts. - -A known HANA function is not automatically treated -as a compatible target function. Unverified mappings return an unsupported error, -including at `Ignore` and `Warn`, rather than silently dropping a result-shaping -clause or emitting a known incompatible operation. Checks run before target -normalization can erase protected casts or query options. - -Implemented scalar mappings are deliberately bounded: - -| Source operation | Targets | Conditions | -|---|---|---| -| `COALESCE`, `IFNULL` | Existing SQL targets | Standard coalescing form | -| `LOCATE` | Trino family, PostgreSQL family, DuckDB | Literal BMP strings, nonnegative constant start, positive occurrence; repeated occurrence requires Trino family | -| `SUBSTRING`, `SUBSTR` | Same families | Literal BMP string and constant bounds; starts below 1 clamp to 1 and lengths below 1 clamp to 0 | -| `TO_DECIMAL(value,p,s)` and fixed-decimal casts | Same families | Proven exact numeric input and valid constant precision/scale; truncate before cast | -| Formatted date parsing/formatting | Trino family, DuckDB | Supported literal datetime mask; formatting requires datetime type evidence; date parsing retains a DATE result; timestamp parsing is restricted to Trino with an explicit TIMESTAMP(7) result | -| UTC clock expressions | Selected Trino/PostgreSQL/DuckDB forms | Explicit UTC zone and representable precision; other forms report unsupported | -| `TIMESTAMP` / `LONGDATE`, `TIME` | Trino | Explicit `TIMESTAMP(7)` / `TIME(0)`; targets with unverified precision report unsupported | -| `FLOAT(p)` | Trino, Presto, PostgreSQL, DuckDB | `p <= 24` maps to REAL; larger/default precision maps to double precision | -| `TINYINT` | DuckDB, ClickHouse | Unsigned type; selected constant casts also widen safely on Trino/Presto/PostgreSQL | - -Unknown/binary/supplementary-Unicode string inputs, dynamic bounds or masks, -negative-start searches, empty-needle searches with offsets/repetition, floating-decimal conversions, and unsupported timestamp -precision are not approximated. HANA indexes CESU-8/UTF-16 character units, which -can differ from target Unicode code-point indexing. The `DEC`, `DAYDATE`, and `LONGDATE` aliases retain their canonical type semantics. -Qualified/quoted user-defined -names remain distinct from unqualified built-ins. - -Basic SQL can be generated for a HANA target. Foreign operations with unverified -HANA semantics, including positional strings, formatted time conversion, -time-zone-sensitive clocks, and dialect date arithmetic, can report unsupported. -Transpilation does not migrate procedures, calculation views, catalogs, privileges, -or system tables such as `DUMMY` into another database. - -## Reference inventory and evidence - -- [Cloud reference inventory](cloud-reference.json): pinned QRC 2/2026 topics. -- [Platform function inventory](functions.json): Platform 2.0 SPS 08 function topics. -- [Platform statement inventory](statements.json): Platform 2.0 SPS 08 statement topics. -- Native fixtures: `crates/polyglot-sql/tests/custom_fixtures/hana/`. -- Source semantics, JSON AST round trips, quoting, boundary and all-target error - policy tests: the existing `tests/dialect_matrix.rs` HANA regression module. -- Binding regressions: existing WASM, FFI, Python, Go, and TypeScript test files. - -Reference-example probes are a syntax audit, not a HANA server execution suite. -Documentation examples containing placeholders, omitted separators, typographical -errors, or excluded SQLScript require manual review before becoming test fixtures. -DuckDB execution checks verify selected scalar result values. HANA server execution -has not been performed. - -The adjacent SQLGlot Oracle, MySQL, Snowflake, and Presto/Trino implementations -informed argument ordering, format-token handling, and source/target separation. -The checked-in SQLGlot has no HANA dialect; its output is not a HANA specification. -No SQLGlot fixture exclusions were added for this implementation. - -## Validation - -Verified locally on 2026-09-22: - -- `make test-rust-verify`, including existing SQLGlot fixtures, the 132 native - HANA fixtures, ClickHouse parser and round-trip suites, and FFI tests. -- All 16 focused HANA regression tests in `dialect_matrix.rs`, including generic - identifier normalization, type annotation, traversal, and source metadata - preservation across optimization and standalone JSON AST generation. -- Parse-only, generation, and transpilation builds with only `dialect-hana`, - plus a HANA-only WASM discovery/native parsing test. -- Rebuilt WASM and TypeScript SDK: 613 tests; TypeScript type checking. -- Rebuilt Python extension: 322 tests passed, one skipped; Python type checking. -- Go tests against the rebuilt FFI library, with the test cache disabled. -- Formatting, project consistency, and unchanged released changelog entries. - -Passing these checks establishes the tested behavior and regression baseline; -it does not establish complete SQL-reference or server-execution coverage. - -## References - -- [HANA Cloud SQL reference](https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209f5020751910148fd8fe88aa4d79d9.html?version=2026_2_QRC) -- [Platform 2.0 SPS 08 SQL reference](https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf) -- [HANA character encoding](https://help.sap.com/docs/SAP_HANA_CLIENT/f1b440ded6144a54ada97ff95dac7adf/5d221fc0e8b54c9d8eddd7748cdf398b.html) -- [Trino datetime functions](https://trino.io/docs/current/functions/datetime.html) -- [Trino string functions](https://trino.io/docs/current/functions/string.html) -- [Trino data types](https://trino.io/docs/current/language/types.html) -- [Trino numeric functions](https://trino.io/docs/current/functions/math.html) - -Timestamp mappings are checked per target. See also the [Presto types reference](https://www.prestodb.io/docs/current/language/types.html) and [Athena timestamp restrictions](https://docs.aws.amazon.com/athena/latest/ug/engine-versions-reference-0003.html). diff --git a/docs/hana/cloud-reference.json b/docs/hana/cloud-reference.json deleted file mode 100644 index d243ff76..00000000 --- a/docs/hana/cloud-reference.json +++ /dev/null @@ -1,6824 +0,0 @@ -[ - { - "title": "Introduction to SQL", - "path": [ - "SQL Reference" - ], - "file": "209f5020751910148fd8fe88aa4d79d9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209f5020751910148fd8fe88aa4d79d9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SQL Notation Conventions", - "path": [ - "SQL Reference" - ], - "file": "209e0cde751910149114be53649a1fb7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209e0cde751910149114be53649a1fb7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Binary Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "6b977a21b1d64dfca67c4f9d1c47f4e2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6b977a21b1d64dfca67c4f9d1c47f4e2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Boolean Data Type", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "f044a9c7fb7b49159384f92f147345fb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f044a9c7fb7b49159384f92f147345fb.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Character String Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "a33f7884b0c14c00b1a76ecd8af5feca.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a33f7884b0c14c00b1a76ecd8af5feca.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Data Type Conversion", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "46ff9650c7f44461a6146269c1e2a4c6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/46ff9650c7f44461a6146269c1e2a4c6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Datetime Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "3f81ccc7e35d44cbbc595c7d552c202a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3f81ccc7e35d44cbbc595c7d552c202a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "JSON as a SQL Data Type", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "735f74fc82d94e88a9b7040f4c49d051.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/735f74fc82d94e88a9b7040f4c49d051.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Large Object (LOB) Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "c374aca91944460b834ef1d5ceb82acf.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c374aca91944460b834ef1d5ceb82acf.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Multi-valued Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "cae8b00a6a964cb8a06d2c00dac4ad05.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/cae8b00a6a964cb8a06d2c00dac4ad05.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Numeric Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "4ee2f261e9c44003807d08ccc2e249ac.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4ee2f261e9c44003807d08ccc2e249ac.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Spatial Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "8efe5a4fe55a4607b6befd83807f79df.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8efe5a4fe55a4607b6befd83807f79df.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Vector Data Types", - "path": [ - "SQL Reference", - "Data Types" - ], - "file": "04cfbb84101145d283680d28edb1e26e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/04cfbb84101145d283680d28edb1e26e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Reserved Words", - "path": [ - "SQL Reference" - ], - "file": "28bcd6af3eb6437892719f7c27a8a285.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/28bcd6af3eb6437892719f7c27a8a285.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Operators", - "path": [ - "SQL Reference" - ], - "file": "20a380977519101494ceddd944e87527.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a380977519101494ceddd944e87527.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Expressions", - "path": [ - "SQL Reference" - ], - "file": "20a4389775191014b5a6bf2ccc0df2ed.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a4389775191014b5a6bf2ccc0df2ed.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Comparison Predicates (ANY, SOME, and ALL)", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "20f91040751910148e96d6cb73119afc.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f91040751910148e96d6cb73119afc.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "BETWEEN Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "20faa69a75191014b3c8e132b035d5a8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20faa69a75191014b3c8e132b035d5a8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CONTAINS Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "20f952437519101487edc3d9aba84238.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f952437519101487edc3d9aba84238.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "EXISTS Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "20f9915f75191014a3d7aa14a0637e41.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f9915f75191014a3d7aa14a0637e41.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "IN Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "20f9d29a7519101483fb90fe2fadc959.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f9d29a7519101483fb90fe2fadc959.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "LIKE Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "20fa17f375191014a4d8d8cbfddfe340.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fa17f375191014a4d8d8cbfddfe340.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "LIKE_REGEXPR Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "b40d483dd34d47aa9cc89b4d8a6e617e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b40d483dd34d47aa9cc89b4d8a6e617e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "MEMBER OF Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "f666b950e5d34f84bb5b6f125e7e85c4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f666b950e5d34f84bb5b6f125e7e85c4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "NULL Predicate", - "path": [ - "SQL Reference", - "Predicates" - ], - "file": "20fa62ef75191014a797dae048566adc.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fa62ef75191014a797dae048566adc.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Session Variables", - "path": [ - "SQL Reference" - ], - "file": "a16678c085bf475f832c10b2629f3997.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a16678c085bf475f832c10b2629f3997.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "HANA_CLOUD Macro", - "path": [ - "SQL Reference" - ], - "file": "6694324fbf4f4e1eb3b82f32ae0ffddd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6694324fbf4f4e1eb3b82f32ae0ffddd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ABAP_ALPHANUM Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "e4887a42a3eb4d5d88bf84da66c07668.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e4887a42a3eb4d5d88bf84da66c07668.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ABAP_DF16RAW_TO_SMALLDECIMAL Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "323345041b9343479807a1c3dff38715.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/323345041b9343479807a1c3dff38715.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ABAP_DF34RAW_TO_DECIMAL Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d88c19d816db4a58805bdc575c78e70c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d88c19d816db4a58805bdc575c78e70c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ABAP_LOWER Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f59d04cc4cc740ed80fbfd4b422f9842.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f59d04cc4cc740ed80fbfd4b422f9842.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ABAP_NUMC Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "6ccf1d971bca4bb6bb59f19fe6e1e6c9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6ccf1d971bca4bb6bb59f19fe6e1e6c9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ABAP_UPPER Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "0e34e8f7185e4909a35ed89dc5ee1229.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0e34e8f7185e4909a35ed89dc5ee1229.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ABS Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20da27c175191014b7b3ecbd7dd130b2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da27c175191014b7b3ecbd7dd130b2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ACOS Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20da43ce751910148d53a3c6f36d4873.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da43ce751910148d53a3c6f36d4873.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ADD_DAYS Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20da5fa8751910148969da2572b25ed8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da5fa8751910148969da2572b25ed8.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "ADD_MONTHS Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20da7b237519101489f3e2e1a284355a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da7b237519101489f3e2e1a284355a.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "ADD_MONTHS_LAST Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "0eda0f731fb34bd2a6237cd7d33374ef.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0eda0f731fb34bd2a6237cd7d33374ef.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "ADD_NANO100 Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "3962389a62b149b69d497bb25f4ec01a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3962389a62b149b69d497bb25f4ec01a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ADD_SECONDS Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20da994e75191014a6e4bf620c179299.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da994e75191014a6e4bf620c179299.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "ADD_WORKDAYS Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22c8391d2951014815a84e76cf66501.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22c8391d2951014815a84e76cf66501.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ADD_YEARS Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dab50375191014bd8fe42e781bdaa0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dab50375191014bd8fe42e781bdaa0.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "AI_TABULAR_PREDICTION (Procedural)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "05d1298b43e849d6896345a0ba2b4c72.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/05d1298b43e849d6896345a0ba2b4c72.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "AI_TEXT_COMPLETION Function (AI)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "036f73d0fd374d1492f61499cdcd29af.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/036f73d0fd374d1492f61499cdcd29af.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ALLOW_PRECISION_LOSS Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "5fd2a1b5a00649be90a77e6a712c164b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5fd2a1b5a00649be90a77e6a712c164b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ASCII Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dad083751910149584c5724f67488b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dad083751910149584c5724f67488b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ASIN Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20daebda751910148c77ac06bb049df2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20daebda751910148c77ac06bb049df2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ATAN Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db38e775191014b31aa470840e14c6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db38e775191014b31aa470840e14c6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ATAN2 Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db65417519101484eded495b2526ae.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db65417519101484eded495b2526ae.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "AUTO_CORR Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "e279ce4d3fbb41a2801057f93dced141.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e279ce4d3fbb41a2801057f93dced141.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "AVG Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "2c93334adf654054a948cc7f151887de.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2c93334adf654054a948cc7f151887de.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "BINNING Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "9a78dfb3cd8240f4be22495a098e65ea.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9a78dfb3cd8240f4be22495a098e65ea.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "BINTOHEX Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db6dd27519101485b2978452f92bbd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd27519101485b2978452f92bbd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "BINTONHEX Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "0662e967cf0342679ce7adf1a0e16aca.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0662e967cf0342679ce7adf1a0e16aca.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "BINTOSTR Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22ce32dd295101481d58e6625b2112d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22ce32dd295101481d58e6625b2112d.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "BITAND Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db6dd3751910148a57978452f92bbd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd3751910148a57978452f92bbd.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "BITCOUNT Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "12501aa67d624a87a60be1eda9c1d093.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/12501aa67d624a87a60be1eda9c1d093.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "BITNOT Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "7c5d6f9cea634b1ab572a8d358aee825.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7c5d6f9cea634b1ab572a8d358aee825.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "BITOR Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "8c10a2303bc34150921debf745c25fe6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8c10a2303bc34150921debf745c25fe6.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "BITSET Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22d0974d29510149373deadadc83fe4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22d0974d29510149373deadadc83fe4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "BITUNSET Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22d21ddd2951014a15dcdbdf3fc5e00.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22d21ddd2951014a15dcdbdf3fc5e00.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "BITXOR Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "bab52a76fde24045bce31993aa3b3c82.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bab52a76fde24045bce31993aa3b3c82.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CARDINALITY Function (Array)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "21c6746955ce4cc2809801c5b0e93817.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/21c6746955ce4cc2809801c5b0e93817.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CARDINALITY Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "5659861eb0254db9a6673f7913d82b43.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5659861eb0254db9a6673f7913d82b43.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CAST Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db6dd475191014aa7b978452f92bbd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd475191014aa7b978452f92bbd.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "CEIL Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db6dd575191014b704978452f92bbd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd575191014b704978452f92bbd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CHAR Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db6dd675191014a4fd978452f92bbd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd675191014a4fd978452f92bbd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "COALESCE Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20db6dd7751910149105978452f92bbd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20db6dd7751910149105978452f92bbd.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "CONCAT Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dd51f775191014990682ac74bbefe8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dd51f775191014990682ac74bbefe8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CONCAT_NAZ Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "5e7c8dd968d74c009bef98028837d5a9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5e7c8dd968d74c009bef98028837d5a9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CONVERT_CURRENCY Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22d746ed2951014bb7fb0114ffdaf96.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22d746ed2951014bb7fb0114ffdaf96.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CONVERT_UNIT Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f43ae7bb6f5b1014a345adb9db626de0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f43ae7bb6f5b1014a345adb9db626de0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CORR Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "aa049c2602824ba091b1b58153a310e5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/aa049c2602824ba091b1b58153a310e5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CORR_SPEARMAN Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "0579a6540e89468998e0ecfaff69acb0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0579a6540e89468998e0ecfaff69acb0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "COS Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dd798b7519101492ec8026cecb3aea.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dd798b7519101492ec8026cecb3aea.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "COSH Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dd990b751910148cefe6fae4ca1c3d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dd990b751910148cefe6fae4ca1c3d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "COSINE_SIMILARITY Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "063e1366a7d54735b98b2513ea4a88c9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/063e1366a7d54735b98b2513ea4a88c9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "COT Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ddc091751910148f72db8d34f39adf.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ddc091751910148f72db8d34f39adf.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "COUNT Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "28c3b573c4354f75a1931202e2271d7c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/28c3b573c4354f75a1931202e2271d7c.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "CROSS_CORR Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "b2197a4784044933ae7c9ed240939dff.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b2197a4784044933ae7c9ed240939dff.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CUBIC_SPLINE_APPROX Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "4300f0ccdf024a11a40a82615832e430.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4300f0ccdf024a11a40a82615832e430.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CUME_DIST Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f4351278aade4ac3be7618181acd2ea4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f4351278aade4ac3be7618181acd2ea4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_CONNECTION Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dde16475191014bf3090e6b2e9857f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dde16475191014bf3090e6b2e9857f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_DATABASE Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "7ddcb499036a483ab18ecb19816e6708.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7ddcb499036a483ab18ecb19816e6708.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_DATE Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ddfe5d75191014af50837e2818462d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ddfe5d75191014af50837e2818462d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_IDENTITY_VALUE Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "01e1a30aa542448da56da76233fea779.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/01e1a30aa542448da56da76233fea779.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_MVCC_SNAPSHOT_TIMESTAMP Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f15c8a4db42b46849c62c4f70d47abd2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f15c8a4db42b46849c62c4f70d47abd2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_OBJECT_SCHEMA Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "8feedda0f93b4b5aa66af0714d62c83a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8feedda0f93b4b5aa66af0714d62c83a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_ROLEGROUP Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "5132e3b06f8a45e9917269e1366e1602.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5132e3b06f8a45e9917269e1366e1602.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_SCHEMA Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20de1a3775191014b155e3a757a193d2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de1a3775191014b155e3a757a193d2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_SITE_ID Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "9ac7d1b81eb642f98a97c9682097e44f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9ac7d1b81eb642f98a97c9682097e44f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_TIME Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20de382f7519101482ca9a2865a86014.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de382f7519101482ca9a2865a86014.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_TIMESTAMP Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20de551c751910149bcfc30eaf359b03.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de551c751910149bcfc30eaf359b03.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_TRANSACTION_ISOLATION_LEVEL Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22ded87d2951014bce8cab9a11d55a2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22ded87d2951014bce8cab9a11d55a2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_UPDATE_STATEMENT_SEQUENCE Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "9ae97edbfee241138fcc1c45c079b3e2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9ae97edbfee241138fcc1c45c079b3e2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_UPDATE_TRANSACTION Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "e04d1f42467544a38ac2125f046793ae.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e04d1f42467544a38ac2125f046793ae.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_USER Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20de8b3775191014acc4e9ee60df1746.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20de8b3775191014acc4e9ee60df1746.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_USER_ID Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "75262ff0734c40cdb9fe2f2d15b6e750.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/75262ff0734c40cdb9fe2f2d15b6e750.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_USERGROUP Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "95fb067f7c5f43f9aaab61a809547d0b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/95fb067f7c5f43f9aaab61a809547d0b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_UTCDATE Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dea8e57519101499438ff2eb028eff.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dea8e57519101499438ff2eb028eff.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_UTCTIME Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20dec53a751910149b5e8425a022f9cd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20dec53a751910149b5e8425a022f9cd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "CURRENT_UTCTIMESTAMP Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e0f06c751910148d388dacfe4b0b58.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e0f06c751910148d388dacfe4b0b58.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "DAYNAME Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e115c375191014a259acd3d72e3722.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e115c375191014a259acd3d72e3722.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "DAYOFMONTH Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e133a875191014a958bb2c7dd5d960.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e133a875191014a958bb2c7dd5d960.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "DAYOFYEAR Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e1505475191014ade2f3f22fc139e9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1505475191014ade2f3f22fc139e9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "DAYS_BETWEEN Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e16ca5751910148da4fc7ec69bae03.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e16ca5751910148da4fc7ec69bae03.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "DENSE_RANK Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "1a116cbd04a942e498ffef3a37b47461.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1a116cbd04a942e498ffef3a37b47461.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "DFT Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "fcf204141f89497bb07f8efbb1bb92da.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fcf204141f89497bb07f8efbb1bb92da.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ESCAPE_DOUBLE_QUOTES Function (Security)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "46c5fecd565c4623b03ad316e27aa22a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/46c5fecd565c4623b03ad316e27aa22a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ESCAPE_SINGLE_QUOTES Function (Security)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "885b059cc20340979c8927c9301ceb63.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/885b059cc20340979c8927c9301ceb63.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "EXP Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e1894075191014b86fe8a17ff0301d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1894075191014b86fe8a17ff0301d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "EXPRESSION_MACRO Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "a8d114522b3a445bb877039fa208f9ba.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a8d114522b3a445bb877039fa208f9ba.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "EXTRACT Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e1a58475191014a343f6fe96c9846c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1a58475191014a343f6fe96c9846c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "FIRST_VALUE Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "034b17549b5d4b7d913e2c2770eea45b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/034b17549b5d4b7d913e2c2770eea45b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "FLOOR Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e1c2b47519101484d8af631b6845f9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e1c2b47519101484d8af631b6845f9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "GENERATE_PASSWORD Function (Security)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "5157398354a14cf49110fac593f83997.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5157398354a14cf49110fac593f83997.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "GET_DELTA_LAKE_TABLE_CHANGES Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "7f38a110382e4635a87a8091e7d7f2af.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7f38a110382e4635a87a8091e7d7f2af.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "GET_DELTA_LAKE_TABLE_VERSION Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "e12e6b52d1c94300a40065f3111fe551.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e12e6b52d1c94300a40065f3111fe551.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "GREATEST Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e20038751910148ed9fadf866413e0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e20038751910148ed9fadf866413e0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "GROUP_SCORE Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "89bc59e4df254c29b66f8feed2b785dc.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/89bc59e4df254c29b66f8feed2b785dc.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "GROUPING Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22eb360d2951014b6f0b9f1e84edce9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22eb360d2951014b6f0b9f1e84edce9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "GROUPING_ID Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e21cfd75191014a5cbbea031962073.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e21cfd75191014a5cbbea031962073.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "HAMMING_DISTANCE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d0878e31868b4f0392c71a299125148d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d0878e31868b4f0392c71a299125148d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "HASH_MD5 Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "881159b167a246e88926075e0c59ea36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/881159b167a246e88926075e0c59ea36.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "HASH_SHA256 Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d22ecca9d2951014850492e8c88d498c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d22ecca9d2951014850492e8c88d498c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "HEXTOBIN Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e2390b75191014be86bf1562fcaf1b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e2390b75191014be86bf1562fcaf1b.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "HEXTONUM Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "0fe4116d8e7347d6a22923c6d7b8c6e2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0fe4116d8e7347d6a22923c6d7b8c6e2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "HOUR Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e23eda75191014a64ce3271722de36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23eda75191014a64ce3271722de36.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "IFNULL Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e23edb75191014b906e3271722de36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23edb75191014b906e3271722de36.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "INITCAP Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d1e67902534d426180459ae45a264667.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d1e67902534d426180459ae45a264667.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "IS_SQL_INJECTION_SAFE Function (Security)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "4496cc5717e847feb7daa41516047df9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4496cc5717e847feb7daa41516047df9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ISOWEEK Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e23edc7519101482eae3271722de36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23edc7519101482eae3271722de36.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "JSON_QUERY Function (JSON)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "3126ea33d50d42d19517a08fe22ec5a1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3126ea33d50d42d19517a08fe22ec5a1.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "JSON_TABLE Function (JSON)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f8f6916b5c434a6fbd1bb7e0dc65acd4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f8f6916b5c434a6fbd1bb7e0dc65acd4.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "JSON_VALUE Function (JSON)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "9355cb9e45a149c1a6ddb2bd2392d864.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9355cb9e45a149c1a6ddb2bd2392d864.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "L2DISTANCE Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "0d48be92cebd4fec8944d208fbf923fc.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0d48be92cebd4fec8944d208fbf923fc.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "L2NORM Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "1225d640200147279b45db92457b5612.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1225d640200147279b45db92457b5612.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "L2NORMALIZE Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f068dc71d41d492bbbd893105b9edced.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f068dc71d41d492bbbd893105b9edced.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LAG Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "e7ef7cc478f14a408e1af27fc1a78624.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e7ef7cc478f14a408e1af27fc1a78624.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LAST_DAY Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e23ede75191014a1c2e3271722de36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23ede75191014a1c2e3271722de36.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LAST_VALUE Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "32e95b7fac5c4b489d938c11ce5b4695.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/32e95b7fac5c4b489d938c11ce5b4695.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LCASE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e23edf7519101490eee3271722de36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e23edf7519101490eee3271722de36.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "LEAD Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "5932eebb6208406590071eb65c6caa83.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5932eebb6208406590071eb65c6caa83.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LEAST Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e2fddb75191014a794e3271722de36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e2fddb75191014a794e3271722de36.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LEFT Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e3428a75191014a9949b4f90076dee.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3428a75191014a9949b4f90076dee.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LENGTH Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e35f5275191014ba6df6dc5f8bad5b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e35f5275191014ba6df6dc5f8bad5b.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "LINEAR_APPROX Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "b06f3e60d29e4968ab2da3cca7333db0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b06f3e60d29e4968ab2da3cca7333db0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LN Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e37b49751910148948cbf4dbb66310.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e37b49751910148948cbf4dbb66310.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LOCALTOUTC Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e39ac67519101486b49c65d9aa5174.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e39ac67519101486b49c65d9aa5174.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs" - ], - "builtin_recognized": true - }, - { - "title": "LOCATE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e3b6b77519101485e6bd62f7018f75.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3b6b77519101485e6bd62f7018f75.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "LOCATE_REGEXPR Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "cb4866494bd647cd8926763aa940f613.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/cb4866494bd647cd8926763aa940f613.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "LOG Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e3d2fe7519101481a1fc67a4370740.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3d2fe7519101481a1fc67a4370740.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LOWER Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e3eff7751910148366dfb349020b4c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e3eff7751910148366dfb349020b4c.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "LPAD Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e40bdb75191014bc66f14fa7a3d769.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e40bdb75191014bc66f14fa7a3d769.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "LTRIM Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e43dd175191014bee9ed5ab9ae44f7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e43dd175191014bee9ed5ab9ae44f7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MAP Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e4654f75191014b58bdd5ea7423a15.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e4654f75191014b58bdd5ea7423a15.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MAX Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "69290904995f47d3a06f70f561c4efca.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/69290904995f47d3a06f70f561c4efca.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "MEDIAN Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "0531b496ea0c463d8c9ddfc15cbdbf04.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0531b496ea0c463d8c9ddfc15cbdbf04.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MEMBER_AT Function (Array)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f17a873883164d958449a94af689895e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f17a873883164d958449a94af689895e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MEMBER_AT Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "559502d670d84bd498780c254354b0ac.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/559502d670d84bd498780c254354b0ac.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MIN Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "4409b0c5441f401486f1c4d4328d4905.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4409b0c5441f401486f1c4d4328d4905.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "MINUTE Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e4ff2275191014825297d563cd0b85.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e4ff2275191014825297d563cd0b85.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MOD Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e51e5c751910149879aa97a95d564b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e51e5c751910149879aa97a95d564b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MONTH Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e544ea75191014b8209a9fc217ce0e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e544ea75191014b8209a9fc217ce0e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MONTHNAME Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e562537519101499c6a760e719afbd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e562537519101499c6a760e719afbd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "MONTHS_BETWEEN Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "9f9eb73468b04bbc9d6014d22d2bfb90.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9f9eb73468b04bbc9d6014d22d2bfb90.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "NANO100_BETWEEN Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e57ed975191014be39aeb6e5fd3d89.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e57ed975191014be39aeb6e5fd3d89.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NCHAR Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e59b1d751910149321c5c68efb5905.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e59b1d751910149321c5c68efb5905.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NDIV0 Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "bcbb7ba0f4f2495ca954132382226929.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bcbb7ba0f4f2495ca954132382226929.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NEXT_DAY Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e5a75e75191014b2539bd2c7772cf2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e5a75e75191014b2539bd2c7772cf2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NEWUID Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "fe7b7fede9aa4287ae69ffe3986e9c25.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fe7b7fede9aa4287ae69ffe3986e9c25.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NORMALIZE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "8fa2d19e3dae4de2a4613a4987858894.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8fa2d19e3dae4de2a4613a4987858894.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NOW Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e5db42751910148cebadec507448b5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e5db42751910148cebadec507448b5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NTH_VALUE Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "6522df94eee542d5b1700a7766e6e6a2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6522df94eee542d5b1700a7766e6e6a2.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "NTILE Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "886723669fb34ff8b5c51eabc003cbd2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/886723669fb34ff8b5c51eabc003cbd2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NULLIF Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e5f7fe751910149ecdc8ee8a8a5c85.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e5f7fe751910149ecdc8ee8a8a5c85.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "NUMTOHEX Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "3688c8288c024907b4d933cd7c9a72c9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3688c8288c024907b4d933cd7c9a72c9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "OCCURRENCES_REGEXPR Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "4114b026f750429c8eeef9f54258edfa.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4114b026f750429c8eeef9f54258edfa.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "PARSE_CERTIFICATES Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "fec4e28a12a946ce86fe789318e85b01.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fec4e28a12a946ce86fe789318e85b01.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "PARSE_JSON Function (JSON)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "58d203e84ed2431d9465d504c69b20ef.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/58d203e84ed2431d9465d504c69b20ef.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "PARTITION_ALLOCATION Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "028be0c864734d2b9e10402a4c7065f2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/028be0c864734d2b9e10402a4c7065f2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "PARTITION_HASH Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "e1e79a1230234c6699f8054d0e42d413.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e1e79a1230234c6699f8054d0e42d413.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "PERCENT_RANK Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "90f4533f07d34269a47924c963f1d5ec.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/90f4533f07d34269a47924c963f1d5ec.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "PERCENTILE_CONT Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "3028c19181b14bdf80fcc5333c5dc7b1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3028c19181b14bdf80fcc5333c5dc7b1.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "PERCENTILE_DISC Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d8394326f65e4fd9aa5a9750755b4665.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d8394326f65e4fd9aa5a9750755b4665.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "POWER Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e6141e75191014a599dce99d5f9ba9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6141e75191014a599dce99d5f9ba9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "QUARTER Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e62fe875191014b78bd015a16966fb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e62fe875191014b78bd015a16966fb.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RAND Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e64d8675191014bba389d65920392d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e64d8675191014bba389d65920392d.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "RANDOM_PARTITION Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "abf3dd7576464c30a7897a05d1ef8cb2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/abf3dd7576464c30a7897a05d1ef8cb2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RAND_SECURE Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d18abab24ad9470d98a760b61955d073.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d18abab24ad9470d98a760b61955d073.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RANK Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "10bb583b586e47a09790eb8f8eeeab62.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/10bb583b586e47a09790eb8f8eeeab62.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RECORD_COMMIT_TIMESTAMP Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "a85896b8b0de48089f76b73ae7388740.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a85896b8b0de48089f76b73ae7388740.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RECORD_ID Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "fba3ff40198c4504b3693ad376e2bfbf.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fba3ff40198c4504b3693ad376e2bfbf.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "REPLACE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e66a2c75191014bac6a279955db665.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e66a2c75191014bac6a279955db665.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "REPLACE_REGEXPR Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "dcf1045ce51d45119cfe8ba17cf9da4f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dcf1045ce51d45119cfe8ba17cf9da4f.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "RESULT_CACHE_ID Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "9e9da58b772a4df4811e3d0845679d5d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9e9da58b772a4df4811e3d0845679d5d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RESULT_CACHE_REFRESH_TIME Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "be8d87e527aa499fbcbcd75357af73bf.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/be8d87e527aa499fbcbcd75357af73bf.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RIGHT Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e6862e75191014af8d997e620c1ee8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6862e75191014af8d997e620c1ee8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ROUND Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e6a27575191014bd54a07fd86c585d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6a27575191014bd54a07fd86c585d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RPAD Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e6be627519101487989fa5c2fceccd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6be627519101487989fa5c2fceccd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "RTRIM Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e6da0175191014a632fe729f839d44.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6da0175191014a632fe729f839d44.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "ROW_NUMBER Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "87f0d4985c4a49bfb64682dcb325173d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/87f0d4985c4a49bfb64682dcb325173d.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "SCORE Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e6f8e97519101489a0cd3c29991e72.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e6f8e97519101489a0cd3c29991e72.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SECOND Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e7152675191014bb54fed5d26b9e6f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7152675191014bb54fed5d26b9e6f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SECONDS_BETWEEN Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e73218751910148528de57be340475.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e73218751910148528de57be340475.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "SERIES_DISAGGREGATE Function (Series Data)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "7c34535972b94f74b1a9c1760f9e4a8e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7c34535972b94f74b1a9c1760f9e4a8e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SERIES_ELEMENT_TO_PERIOD Function (Series Data)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "c266e91b94484674b7da636f3f477158.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c266e91b94484674b7da636f3f477158.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SERIES_FILTER Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "c097a58f3a7c4a3a8d851371bcc8e5ba.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c097a58f3a7c4a3a8d851371bcc8e5ba.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SERIES_GENERATE Function (Series Data)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "c8101037ad4344768db31e68e4d30eb4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c8101037ad4344768db31e68e4d30eb4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SERIES_PERIOD_TO_ELEMENT Function (Series Data)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "eb21d794c95341a9816bb528f134d491.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/eb21d794c95341a9816bb528f134d491.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SERIES_ROUND Function (Series Data)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "435ec476ab494ad6b8409f22abec13fe.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/435ec476ab494ad6b8409f22abec13fe.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SESSION_CONTEXT Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e74dc875191014b20c81d140d67e42.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e74dc875191014b20c81d140d67e42.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SESSION_USER Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e76c1a7519101496b1f32f0d1128d9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e76c1a7519101496b1f32f0d1128d9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SIGN Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e788537519101487829d6ad0ba5244.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e788537519101487829d6ad0ba5244.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SIN Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e7a62475191014b6c499e5f954d817.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7a62475191014b6c499e5f954d817.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SINH Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e7c25e751910148a11981903397e9c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7c25e751910148a11981903397e9c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SOUNDEX Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "3ca8ac5cb49d401993b5dfcca925c22f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3ca8ac5cb49d401993b5dfcca925c22f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SQRT Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e7de8875191014ba5dc4f74fa82376.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7de8875191014ba5dc4f74fa82376.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "STATEMENT_EXECUTION_HOST Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d42113dcde234542919d610a739ffcc1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d42113dcde234542919d610a739ffcc1.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "STATEMENT_EXECUTION_PORT Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "4b410ddd8e8041eb89772717d20a29e0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4b410ddd8e8041eb89772717d20a29e0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "STDDEV Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "c0c42b56360144e99bd443db90847597.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c0c42b56360144e99bd443db90847597.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "STDDEV_POP Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "67d48b64f0d048bfb028767cb377fbb2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/67d48b64f0d048bfb028767cb377fbb2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "STDDEV_SAMP Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "303513466051489dbe926bd482bfc5d9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/303513466051489dbe926bd482bfc5d9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "STRING_AGG Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "a924ee1e98ab435a874efa32e6f0ae14.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a924ee1e98ab435a874efa32e6f0ae14.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "STRTOBIN Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d230efaad295101481708a3a9aea9254.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d230efaad295101481708a3a9aea9254.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SUBARRAY Function (Array)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "49d7752679f643539eaddcf4a2d7cb8e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/49d7752679f643539eaddcf4a2d7cb8e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SUBSTR_AFTER Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e7fb71751910148292a53e1b4a9bba.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e7fb71751910148292a53e1b4a9bba.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SUBSTR_BEFORE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e8174b751910149796bd4aad28bdca.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8174b751910149796bd4aad28bdca.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SUBSTRING Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e8341275191014a4cfdcd3c830fc98.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8341275191014a4cfdcd3c830fc98.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "SUBSTRING_REGEXPR Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "a2f80e8ac8904c13959c69bfc3058f19.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a2f80e8ac8904c13959c69bfc3058f19.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SUBVECTOR Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "5f2979b935ff4831875a8ef0f8cb10be.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5f2979b935ff4831875a8ef0f8cb10be.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "SUM Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "03958a1eb0ad4950b00dedd8fdda475a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/03958a1eb0ad4950b00dedd8fdda475a.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "SYSUUID Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e8cdfc7519101498c5ab902aee5306.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8cdfc7519101498c5ab902aee5306.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TAN Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e8ee6e75191014a8b3b47e4f8c296d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e8ee6e75191014a8b3b47e4f8c296d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TANH Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20e90bf975191014b967c5d414e8b167.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20e90bf975191014b967c5d414e8b167.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_ARRAY Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "877008aee4ad4467a1d5ae38f325671d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/877008aee4ad4467a1d5ae38f325671d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_BIGINT Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20eae5e1751910148391d3079da8527e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20eae5e1751910148391d3079da8527e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_BINARY Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20eb65d4751910149a7dc10f93a24a75.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20eb65d4751910149a7dc10f93a24a75.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_BLOB Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20eba7c375191014b9bfbf21581ee86a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20eba7c375191014b9bfbf21581ee86a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_BOOLEAN Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "258b5350ad43487397d47f2ab309952d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/258b5350ad43487397d47f2ab309952d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_CLOB Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ebe72e75191014b314da7e6f95e73b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ebe72e75191014b314da7e6f95e73b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_DATE Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ec6b6975191014b835eb436e4827df.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ec6b6975191014b835eb436e4827df.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "TO_DATS Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ecb35c75191014b225b00e53f9c1b8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ecb35c75191014b225b00e53f9c1b8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_DECIMAL Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ee237775191014924e81b18c73c831.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ee237775191014924e81b18c73c831.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "TO_DOUBLE Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ee824a751910148a149311d1aa0f32.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ee824a751910148a149311d1aa0f32.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_HALF_VECTOR Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f4f80d5254a94db79ce01cddc724c105.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f4f80d5254a94db79ce01cddc724c105.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_INT Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ef08b775191014b8f4f7fad1c7f0f1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ef08b775191014b8f4f7fad1c7f0f1.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_INTEGER Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ef488375191014888a939fbf0acd6b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ef488375191014888a939fbf0acd6b.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "TO_JSON_BOOLEAN (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "8791a379ef08455c9bc95f88d4b18630.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8791a379ef08455c9bc95f88d4b18630.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "TO_NCLOB Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20ef8d6f751910148aa787ac113859f0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ef8d6f751910148aa787ac113859f0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_NVARCHAR Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20efce3f751910149e20b0068fd68287.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20efce3f751910149e20b0068fd68287.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_REAL Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f017bc7519101490f792fb956eb045.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f017bc7519101490f792fb956eb045.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_REAL_VECTOR Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "2c10279264a04affbb018753641b01cf.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2c10279264a04affbb018753641b01cf.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_SECONDDATE Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f057b075191014809a8f010c03d7c2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f057b075191014809a8f010c03d7c2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_SMALLDECIMAL Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f0d4aa75191014a96ef18b874d6f2d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f0d4aa75191014a96ef18b874d6f2d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_SMALLINT Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f11dbf75191014972cc8c3d639d432.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f11dbf75191014972cc8c3d639d432.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_TIME Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f1662775191014a6f7cead37a5937a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f1662775191014a6f7cead37a5937a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_TIMESTAMP Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f1a5b075191014b773acf0dc277cae.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f1a5b075191014b773acf0dc277cae.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "TO_TINYINT Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f1e6a175191014a59583315d023b7f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f1e6a175191014a59583315d023b7f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_VARBINARY Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "048f39f4577d4f929b5eda86797ba8d7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/048f39f4577d4f929b5eda86797ba8d7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "TO_VARCHAR Function (Data Type Conversion)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f226a1751910149edd8969c469d54d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f226a1751910149edd8969c469d54d.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ], - "builtin_recognized": true - }, - { - "title": "TRIM Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f266137519101480abfc0aeb6c9dc3.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f266137519101480abfc0aeb6c9dc3.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "TRIM_ARRAY Function (Array)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "565f8f65e5324117b5435682150f45f3.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/565f8f65e5324117b5435682150f45f3.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "UCASE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f4073275191014a8418376b0a184eb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4073275191014a8418376b0a184eb.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "UMINUS Function (Numeric)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f4667a75191014a8acfc814316001f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4667a75191014a8acfc814316001f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "UNICODE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f4a5fb75191014a75be5e25682ea6f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4a5fb75191014a75be5e25682ea6f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "UPPER Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f4ef8775191014bb2d94bbf2fe50d7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f4ef8775191014bb2d94bbf2fe50d7.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "UTCTOLOCAL Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f52f4475191014a1089242486060c1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f52f4475191014a1089242486060c1.html?version=2026_2_QRC", - "status": "regression_tested_forms", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs" - ], - "builtin_recognized": true - }, - { - "title": "VALIDATE_USERGROUP_CONNECT_RESTRICTION_DETAILS Function (Security)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "508e1735f86a4c97a9072627e1e265de.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/508e1735f86a4c97a9072627e1e265de.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "VALIDATE_USERGROUP_CONNECT_RESTRICTION Function (Security)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "c7a96e0bcc51447fa2af31413dbaff41.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c7a96e0bcc51447fa2af31413dbaff41.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "VAR Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "21a8eb1267d549c6a3eb0e15f82943e6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/21a8eb1267d549c6a3eb0e15f82943e6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "VAR_POP Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "4faac7bced8140b0a703eb32b420edf8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4faac7bced8140b0a703eb32b420edf8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "VAR_SAMP Function (Aggregate)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d1e36dfe43854bf5853fb7cca64b771b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d1e36dfe43854bf5853fb7cca64b771b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "VECTOR_EMBEDDING Function (Vector)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "87bbd2c23b8342a0b70c6022664465a9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/87bbd2c23b8342a0b70c6022664465a9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "WEEK Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f5758b7519101498b28e41757fe664.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f5758b7519101498b28e41757fe664.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "WEEKDAY Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f5bb79751910148e7198206fbd199f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f5bb79751910148e7198206fbd199f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "WEIGHTED_AVG Function (Window)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d97252bcd22f4d9fa4812715cee5139b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d97252bcd22f4d9fa4812715cee5139b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "WIDTH_BUCKET Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "953bce3cc9a84ebfa77c17ab687ff0ee.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/953bce3cc9a84ebfa77c17ab687ff0ee.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "WORKDAYS_BETWEEN Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "d232c253d295101486a3dee449981b3f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d232c253d295101486a3dee449981b3f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "XMLEXTRACT Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "f1045c62108c449a835adba32c279090.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f1045c62108c449a835adba32c279090.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "XMLEXTRACTVALUE Function (Miscellaneous)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "85ee0084ac014a63aa2680b384466f39.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/85ee0084ac014a63aa2680b384466f39.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "XMLTABLE Function (String)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "2bb8ab119e384b5f94635696bb9f68b5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2bb8ab119e384b5f94635696bb9f68b5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "YEAR Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "20f5fac6751910148dabd3c6821f907d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f5fac6751910148dabd3c6821f907d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [], - "builtin_recognized": true - }, - { - "title": "YEARS_BETWEEN Function (Datetime)", - "path": [ - "SQL Reference", - "SQL Functions", - "Alphabetical List Of Functions" - ], - "file": "7c0d2c161ea34def86de3f5eadd6a0af.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/7c0d2c161ea34def86de3f5eadd6a0af.html?version=2026_2_QRC", - "status": "native_fixture_forms", - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ], - "builtin_recognized": true - }, - { - "title": "Aggregate Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "6fff7f0ae9184d1db47a25791545a1b6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6fff7f0ae9184d1db47a25791545a1b6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "AI Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "062a3e4c83d14418850aa0267db7c6dd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/062a3e4c83d14418850aa0267db7c6dd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Array Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "e32b3b4076244f63825091adeaba6299.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e32b3b4076244f63825091adeaba6299.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Data Type Conversion Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "209ddefe75191014ac249bf78ba2a1e9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209ddefe75191014ac249bf78ba2a1e9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Datetime Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "209f228975191014baed94f1b69693ae.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209f228975191014baed94f1b69693ae.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Hierarchy Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "2969da89b87f4abd85fd0b5f9f5bc395.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2969da89b87f4abd85fd0b5f9f5bc395.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "JSON Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "5848028bcd364d9aa0706ae1d7ab4184.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5848028bcd364d9aa0706ae1d7ab4184.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Miscellaneous Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "20a465cd75191014abacf163b404e930.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a465cd75191014abacf163b404e930.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Numeric Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "20a190b975191014b769eafa93453d3a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a190b975191014b769eafa93453d3a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Security Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "287e6e06fd69494488d71863c3e49285.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/287e6e06fd69494488d71863c3e49285.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Series Data Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "2dea02fb9feb451080a8c2ee573a88f9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2dea02fb9feb451080a8c2ee573a88f9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "String Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "20a24d4b75191014afc5ac3b997d3ce2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a24d4b75191014afc5ac3b997d3ce2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Vector Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "0d67bb2b7fd246b48ca4a6cf0bb9d77a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0d67bb2b7fd246b48ca4a6cf0bb9d77a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Windows Functions", - "path": [ - "SQL Reference", - "SQL Functions", - "Window Functions and the Window Specification" - ], - "file": "4958a2b74950493b900fb14ba9efdf24.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4958a2b74950493b900fb14ba9efdf24.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Window Aggregate Functions", - "path": [ - "SQL Reference", - "SQL Functions", - "Window Functions and the Window Specification" - ], - "file": "ee3c26a9f6354191800e6d0ba8485200.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ee3c26a9f6354191800e6d0ba8485200.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER AUDIT POLICY Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20cfb7b875191014866c930164aaf07c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20cfb7b875191014866c930164aaf07c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER CREDENTIAL Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20cfdad57519101482fcb19af478ec34.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20cfdad57519101482fcb19af478ec34.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER FUNCTION Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "1102d570f16a4925a706f20285870350.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1102d570f16a4925a706f20285870350.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d014b575191014b66d8ef88f6a55f6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d014b575191014b66d8ef88f6a55f6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER JWT PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "61863f687c3d40c5a7c76a4ab110ede5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/61863f687c3d40c5a7c76a4ab110ede5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER LDAP PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "ae9ba28ddefc4b29809d5b926d6ee02d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ae9ba28ddefc4b29809d5b926d6ee02d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER LIBRARY Statement (SQLScript)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "d0b979ccbbd14377983f254e85241ff4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d0b979ccbbd14377983f254e85241ff4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER PROCEDURE Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d0328875191014964a9059637c7f5f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0328875191014964a9059637c7f5f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER PSE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "9c22c6f22df64bc6881d1ed61be18b8d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9c22c6f22df64bc6881d1ed61be18b8d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER REMOTE SOURCE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "f423eb496f5b1014a1a7bb3e49bcc07b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f423eb496f5b1014a1a7bb3e49bcc07b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER REMOTE SUBSCRIPTION Statement", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "b366013688df494980a9c81f7c81f503.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b366013688df494980a9c81f7c81f503.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER ROLE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "c16ff341be00433f862b2c064431ec0c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c16ff341be00433f862b2c064431ec0c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER ROLEGROUP Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "bb0d9c0c86f6421cb3c37e48dc513d38.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bb0d9c0c86f6421cb3c37e48dc513d38.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SAML PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d04f7b751910148a98f145797d3482.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d04f7b751910148a98f145797d3482.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SCHEDULER JOB Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "701e46758a044d868365b54bac173405.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/701e46758a044d868365b54bac173405.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SEQUENCE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d06b0575191014afb2dfcb7aed7fff.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d06b0575191014afb2dfcb7aed7fff.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER STATISTICS Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "c6564762f4b846e5a76fcfb3fd7a1a88.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c6564762f4b846e5a76fcfb3fd7a1a88.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER STRUCTURED COLUMN MASK Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "58ea2c4950454b6eb9c2b29bc44e2b8f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/58ea2c4950454b6eb9c2b29bc44e2b8f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER STRUCTURED FILTER Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "07b14e01c65a4e7b89b779defb12c97c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/07b14e01c65a4e7b89b779defb12c97c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER STRUCTURED PRIVILEGE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "fd4016543766478ea6304c3909b4245c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fd4016543766478ea6304c3909b4245c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {ADD | ALTER | REMOVE} STATEMENT HINT Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "1ec23ef0839b45b7991a785eff19fd2c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1ec23ef0839b45b7991a785eff19fd2c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {ADD | REMOVE} ABSTRACT SQL PLAN FILTER (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "9c6ac161c9d8492f9d55c9cff38fb17f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9c6ac161c9d8492f9d55c9cff38fb17f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM ALTER AUDIT LOG (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "f135e4a7883746f4b4b7c06b8605a589.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f135e4a7883746f4b4b7c06b8605a589.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM ALTER CONFIGURATION Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d08a5b751910148145dbc016c826a4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d08a5b751910148145dbc016c826a4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM ALTER SESSION SET Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d0b09375191014b517e1ec387f9c26.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0b09375191014b517e1ec387f9c26.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM ALTER SESSION UNSET Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d0ce04751910149e6bf5840bb2042a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0ce04751910149e6bf5840bb2042a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM ALTER TABLE PLACEMENT Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "0715b97c91cd4c87982040cdd341d676.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0715b97c91cd4c87982040cdd341d676.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM APPLICATION ENCRYPTION Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "f42595956f5b1014bc6cb241d3d75fc2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f42595956f5b1014bc6cb241d3d75fc2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CANCEL [WORK IN] SESSION Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d0eb287519101498c4ecb8114cab17.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d0eb287519101498c4ecb8114cab17.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR AUDIT LOG Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "d2231bd2d2951014ad35d218ea6628c8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d2231bd2d2951014ad35d218ea6628c8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR CACHE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "141ad67a9cbe4c6c951b542aff239df4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/141ad67a9cbe4c6c951b542aff239df4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR COLUMN JOIN DATA STATISTICS (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "9ac0859babf549c1a05bdfd8c9c68f11.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9ac0859babf549c1a05bdfd8c9c68f11.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR CONSISTENCY CHECK HISTORY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "89ea41b59b354983bdea16daf75ac6b9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/89ea41b59b354983bdea16daf75ac6b9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR INIFILE CONTENT HISTORY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "fb097f2620c645d18064ce6b93c24a1e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fb097f2620c645d18064ce6b93c24a1e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR RESULT CACHE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "97dca93d321540faa947abe647ebdf6b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/97dca93d321540faa947abe647ebdf6b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR SQL PLAN CACHE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d107c875191014b8aecbb218720fd9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d107c875191014b8aecbb218720fd9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR TIMEZONE CACHE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "a7804953f5cb458a84f47d3045436107.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a7804953f5cb458a84f47d3045436107.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CLEAR TRACES Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d12816751910149640d1e144741069.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d12816751910149640d1e144741069.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CREATE RUNTIMEDUMP Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "6954969bba544da190ca53c1bf367086.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6954969bba544da190ca53c1bf367086.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM CREATE WAITGRAPH Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "078511c1125a4235bbd09e3ea6ff04a8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/078511c1125a4235bbd09e3ea6ff04a8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM DISCONNECT SESSION Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d1524e751910148706e0aab4063a0f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d1524e751910148706e0aab4063a0f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {ENABLE | DISABLE} ALL [ASYNCHRONOUS | SYNCHRONOUS] TABLE REPLICAS Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "f9486656d74b4b059f53c28f7d5f8be9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f9486656d74b4b059f53c28f7d5f8be9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {ENABLE | DISABLE | REMOVE} ABSTRACT SQL PLAN (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "031158f3b53342b095ab4d49ffd95a3e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/031158f3b53342b095ab4d49ffd95a3e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {ENABLE | DISABLE} STATEMENT HINT Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "8505e6f5023c4092901735116d03fdce.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8505e6f5023c4092901735116d03fdce.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM LOAD PERFTRACE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d170777519101493f4be280b8d0b45.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d170777519101493f4be280b8d0b45.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {PIN | UNPIN} SQL PLAN CACHE ENTRY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "68e2f7a8e06f41cb871276858202c605.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/68e2f7a8e06f41cb871276858202c605.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM RECLAIM DATAVOLUME Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d1e5e57519101486c7812a5a8990e8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d1e5e57519101486c7812a5a8990e8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM RECLAIM LOB SPACE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "a0b723599451418d91a5f264387a3250.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a0b723599451418d91a5f264387a3250.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM RECOMPILE SQL PLAN CACHE ENTRY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "d2264261d2951014ae11f585d3cca109.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d2264261d2951014ae11f585d3cca109.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM RECONFIGURE SERVICE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d23ead751910148f18dcd2a0862e90.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d23ead751910148f18dcd2a0862e90.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM REFRESH RESULT CACHE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "9d274fa7e20d4841a6017e020d871aa0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9d274fa7e20d4841a6017e020d871aa0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM REFRESH RESULT CACHE ENTRY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "1ab0dbbae3734a48b7a286f3df467b6b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1ab0dbbae3734a48b7a286f3df467b6b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM REMOVE CACHE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "e4a2ad5facb04ae2b76b6c885f7913ff.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e4a2ad5facb04ae2b76b6c885f7913ff.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM REMOVE RESULT CACHE ENTRY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "2124566f72194618be0d40036c1dea52.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2124566f72194618be0d40036c1dea52.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM REMOVE SQL PLAN CACHE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "dafece708a524a7b9cabc13fe95406c1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dafece708a524a7b9cabc13fe95406c1.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM REMOVE TRACES Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d25bff75191014965ad9dcc606d225.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d25bff75191014965ad9dcc606d225.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM RESET MONITORING VIEW Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d27aa375191014a9cd8ea8c334741a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d27aa375191014a9cd8ea8c334741a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM SAVE PERFTRACE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d2973275191014bafef616be15326a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d2973275191014bafef616be15326a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM SAVEPOINT Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d2b6e4751910148f429f70714d1910.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d2b6e4751910148f429f70714d1910.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {START | STOP} APPLY ABSTRACT SQL PLAN (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "935ecd1974af406a91bc1cb60a0e5ef5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/935ecd1974af406a91bc1cb60a0e5ef5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {START | STOP} CAPTURE ABSTRACT SQL PLAN (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "dc462710a89d4ebc981eda6908db28dc.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dc462710a89d4ebc981eda6908db28dc.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {START | STOP | CLEAR} SQLSCRIPT PLAN PROFILER Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "f518753a450942a48fecc02c926e3847.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f518753a450942a48fecc02c926e3847.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {START | STOP | SAVE | CLEAR} KERNEL PROFILER Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "864e9b9851bb467e9c0c4c1f285bef12.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/864e9b9851bb467e9c0c4c1f285bef12.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {START | STOP} PERFTRACE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d2d3ed75191014bb9c86ed27c378d8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d2d3ed75191014bb9c86ed27c378d8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM {START | STOP} SQLSCRIPT CODE COVERAGE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "1a40f07c15c3401083fc8fd8b9786f7b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1a40f07c15c3401083fc8fd8b9786f7b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM STOP SERVICE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER SYSTEM ... (All ALTER SYSTEM Statements)" - ], - "file": "20d30dab75191014bf7de6f8ea2b3ed6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d30dab75191014bf7de6f8ea2b3ed6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER TABLE GROUP Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "28543a11bacf412a9062f5fe54bc4f5c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/28543a11bacf412a9062f5fe54bc4f5c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Non-Heterogeneous Alter Partition Clauses", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER TABLE Statement (Data Definition)" - ], - "file": "f7ae27ca1b954471a4e1a7feab2c24d7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f7ae27ca1b954471a4e1a7feab2c24d7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Heterogeneous Alter Partition Clauses", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "ALTER TABLE Statement (Data Definition)" - ], - "file": "a4258b865710423b8712b06fb5b8e7c5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a4258b865710423b8712b06fb5b8e7c5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER TOKEN EXCHANGER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "47dbef7cc96e4cccaadcf4e027b245b3.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/47dbef7cc96e4cccaadcf4e027b245b3.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER USER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d3459f75191014a7bbeb670bad8850.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3459f75191014a7bbeb670bad8850.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER USERGROUP Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "aa94ca874c01458da5a275aac8883c23.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/aa94ca874c01458da5a275aac8883c23.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER VECTOR INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "5274113d391e40cdb31e255a1e9b3063.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5274113d391e40cdb31e255a1e9b3063.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER VIEW Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "3bc89515b93d4844bd700b3492673270.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3bc89515b93d4844bd700b3492673270.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER VIRTUAL TABLE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "51826981a2d24e7aa872f4278220b579.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/51826981a2d24e7aa872f4278220b579.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER WORKLOAD CLASS Statement (Workload Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "d4b4659f501c48fd90d52d99759a87f2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d4b4659f501c48fd90d52d99759a87f2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER WORKLOAD MAPPING Statement (Workload Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "81fc16bfa4904943b730bcd1848cd37d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/81fc16bfa4904943b730bcd1848cd37d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER X509 PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "4f7e59d60616461cbfaa00bda366b9f2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4f7e59d60616461cbfaa00bda366b9f2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ANNOTATE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "534df83ee61946b884e7594d21459e35.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/534df83ee61946b884e7594d21459e35.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CALL Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d364c175191014b592f500ccb5510c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d364c175191014b592f500ccb5510c.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "title": "CANCEL ASYNC CALL Statement", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "63ae89ee80ec4671b551d459e129d4a1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/63ae89ee80ec4671b551d459e129d4a1.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "COMMENT ON Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d3817075191014ba7bcfdbab508d0e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3817075191014ba7bcfdbab508d0e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "COMMIT Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d39db97519101480e7f9b76f48c2c4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d39db97519101480e7f9b76f48c2c4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CONNECT Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d3b9ad751910148cdccc8205563a87.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3b9ad751910148cdccc8205563a87.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE ANALYTIC MODEL (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "42da9e00b0f74e27980ccd49012ad49e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/42da9e00b0f74e27980ccd49012ad49e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE AUDIT POLICY Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d3d56075191014af43d6487fcaa603.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3d56075191014af43d6487fcaa603.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE CERTIFICATE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "ba87935fc4a84f4eb805d5eba9a7b480.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ba87935fc4a84f4eb805d5eba9a7b480.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE CREDENTIAL Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d3f464751910148968e73782586ed0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d3f464751910148968e73782586ed0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE FUNCTION Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d42e77751910149f0ff6b879b1290f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d42e77751910149f0ff6b879b1290f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE FUZZY SEARCH INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "9b79b31dde1b4f6d84144fba8d942bd3.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9b79b31dde1b4f6d84144fba8d942bd3.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d44b4175191014a940afff4b47c7ea.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d44b4175191014a940afff4b47c7ea.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE JWT PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "bfe3daf744324bc390902251817a1fcc.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bfe3daf744324bc390902251817a1fcc.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE LDAP PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "3b722036ba4941df8712508a3b231643.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3b722036ba4941df8712508a3b231643.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE LIBRARY Statement (SQLScript)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "62263ce35ac74488a397553fcb25a7d6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/62263ce35ac74488a397553fcb25a7d6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE PROCEDURE Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d467407519101484f190f545d54b24.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d467407519101484f190f545d54b24.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE PROJECTION VIEW Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "e35411b417a94f199679b9f9f45c2306.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e35411b417a94f199679b9f9f45c2306.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE PSE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "4d80bf63fc374a7f99be94d8ce70a07a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4d80bf63fc374a7f99be94d8ce70a07a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE PUBLIC KEY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "80bae7bd45b14516b334d649fdac6de2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/80bae7bd45b14516b334d649fdac6de2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE REMOTE SOURCE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d48343751910149985a2c925e12190.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d48343751910149985a2c925e12190.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE REMOTE SUBSCRIPTION Statement", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "0d7acab98a0346039221da5d5c5156ba.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/0d7acab98a0346039221da5d5c5156ba.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE ROLE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d4a23b75191014a182b123906d5b16.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d4a23b75191014a182b123906d5b16.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE ROLEGROUP Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "6cf193279bb4481faf8f2c77f137250c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6cf193279bb4481faf8f2c77f137250c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE SAML PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d4cca075191014824eeda2cbba6445.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d4cca075191014824eeda2cbba6445.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE SCHEDULER JOB Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "d7d43d818366460dae1328aab5d5df4f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d7d43d818366460dae1328aab5d5df4f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE SCHEMA Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d4ecad7519101497d192700ce5f3df.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d4ecad7519101497d192700ce5f3df.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE SCHEMA SYNONYM Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "1b54e1f64cfc401bb3adbe7c143bc323.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1b54e1f64cfc401bb3adbe7c143bc323.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE SEQUENCE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d509277519101489029c064d468c5d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d509277519101489029c064d468c5d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE STATISTICS Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d5252d7519101493f5e662a6cda4d4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5252d7519101493f5e662a6cda4d4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE STRUCTURED COLUMN MASK Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "a084e535192342dda9e8549b45d63e7f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a084e535192342dda9e8549b45d63e7f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE STRUCTURED FILTER Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "f0238ff8445342a8a9a2f9c3dd36631e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f0238ff8445342a8a9a2f9c3dd36631e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE STRUCTURED PRIVILEGE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "622b2dfdce81455a949fb2bb3be014d2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/622b2dfdce81455a949fb2bb3be014d2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE SYNONYM Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d5412b75191014bc7ec7e133ce5bf5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5412b75191014bc7ec7e133ce5bf5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE TABLE GROUP Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "a8dfce213a28413e94038f2ae5f91e6a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a8dfce213a28413e94038f2ae5f91e6a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Non-Heterogeneous Create Partition Clauses", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "CREATE TABLE Statement (Data Definition)" - ], - "file": "ca6a99bbfcd94be9ab8020a86f43caae.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ca6a99bbfcd94be9ab8020a86f43caae.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Heterogeneous Create Partition Clauses", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "CREATE TABLE Statement (Data Definition)" - ], - "file": "d496e58ce9b54bac9674beda4a636946.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d496e58ce9b54bac9674beda4a636946.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE TOKEN EXCHANGER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "fb015cd6638b46abbe3c32e66c43d576.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/fb015cd6638b46abbe3c32e66c43d576.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE TRIGGER Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d5a65575191014946db96aaedbef5b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5a65575191014946db96aaedbef5b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE TYPE Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d5c1ed75191014a80d897035629def.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5c1ed75191014a80d897035629def.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE USER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d5ddb075191014b594f7b11ff08ee2.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5ddb075191014b594f7b11ff08ee2.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE USERGROUP Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "9869125ea93548009820702f5bd897d8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9869125ea93548009820702f5bd897d8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE VECTOR INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "ab672646e17c46e8ab60463efa22558d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ab672646e17c46e8ab60463efa22558d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE VIEW Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d5fa9b75191014a33eee92692f1702.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d5fa9b75191014a33eee92692f1702.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE VIRTUAL FUNCTION Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "55d2f440e375408194be7e58266733fa.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/55d2f440e375408194be7e58266733fa.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE VIRTUAL TABLE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "d2a0406155f24a49aa6c549e0c428bd7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d2a0406155f24a49aa6c549e0c428bd7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE WORKLOAD CLASS Statement (Workload Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "dc417c30b1b3460c8860f6c7ea2a7faa.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/dc417c30b1b3460c8860f6c7ea2a7faa.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE WORKLOAD MAPPING Statement (Workload Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "996978a669b847ea89ca7f2cce41d916.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/996978a669b847ea89ca7f2cce41d916.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "CREATE X509 PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "3b3163d6ad0f4eb9bd73c7c060f49649.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3b3163d6ad0f4eb9bd73c7c060f49649.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DELETE Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d6169a75191014892db922f94abe41.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6169a75191014892db922f94abe41.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "title": "DO BEGIN...END Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "52103853351841f6a1e87f40b2686da9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/52103853351841f6a1e87f40b2686da9.html?version=2026_2_QRC", - "status": "outside_scope_sqlscript_body", - "tests": [] - }, - { - "title": "DROP ANALYTIC MODEL (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "99539ed9e50f4e9395c4d87982885ff4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/99539ed9e50f4e9395c4d87982885ff4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP AUDIT POLICY Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d6324675191014b588d13fe491415e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6324675191014b588d13fe491415e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP CERTIFICATE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "b7784cfa101942f4ae17a258d060998e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/b7784cfa101942f4ae17a258d060998e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP CREDENTIAL Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d64db0751910149535843182bf8d86.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d64db0751910149535843182bf8d86.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP FUNCTION Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d6852375191014a6e2f134db8fc8cb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6852375191014a6e2f134db8fc8cb.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d6f4e575191014b333904458242bd7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d6f4e575191014b333904458242bd7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP JWT PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "e3caf68bb0b84b4cbcc0e3a7c022e92a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/e3caf68bb0b84b4cbcc0e3a7c022e92a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP LDAP PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "340e913ae1d044d993dec2a7eff941c4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/340e913ae1d044d993dec2a7eff941c4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP LIBRARY Statement (SQLScript)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "d4160799a5564fc0b901e499c29dc5b4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d4160799a5564fc0b901e499c29dc5b4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP PROCEDURE Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d7165e75191014a7129ace03afebeb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7165e75191014a7129ace03afebeb.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP PSE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "25d67950e6614770aa98aec23ab117ee.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/25d67950e6614770aa98aec23ab117ee.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP PUBLIC KEY Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "1f935a3dff744f7bbf488271a6c869f4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/1f935a3dff744f7bbf488271a6c869f4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP REMOTE SOURCE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d7332f75191014866fc4b83cfba146.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7332f75191014866fc4b83cfba146.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP REMOTE SUBSCRIPTION Statement", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "27b652dbc0064091bcc57ebde419e2fd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/27b652dbc0064091bcc57ebde419e2fd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP ROLE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d74f7f75191014a71ee6a2ae78547f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d74f7f75191014a71ee6a2ae78547f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP ROLEGROUP Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "9506eaa644934372bf5f7d6117e68e55.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/9506eaa644934372bf5f7d6117e68e55.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP SAML PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d76c8675191014b9acc9697a367773.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d76c8675191014b9acc9697a367773.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP SCHEDULER JOB Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "5a5f9f0efe9544769977e5ef45defc1f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5a5f9f0efe9544769977e5ef45defc1f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP SCHEMA Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d7891d751910149164f0d4ca73639d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7891d751910149164f0d4ca73639d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP SCHEMA SYNONYM Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "f8ac4d9c656049c29d80a9ba3a495001.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f8ac4d9c656049c29d80a9ba3a495001.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP SEQUENCE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d7a85b751910149482f673a4789209.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7a85b751910149482f673a4789209.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP STATISTICS Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d7c595751910148307bf3bf4c745e6.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7c595751910148307bf3bf4c745e6.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP STRUCTURED COLUMN MASK Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "82d10ff0b6bd47ca9f982855015f9c36.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/82d10ff0b6bd47ca9f982855015f9c36.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP STRUCTURED FILTER Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "897bc02cfb274a54a2661ffde9f97c76.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/897bc02cfb274a54a2661ffde9f97c76.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP STRUCTURED PRIVILEGE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "4742f573d0c24e9084a699d464bf20c7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4742f573d0c24e9084a699d464bf20c7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP SYNONYM Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d7e172751910148bccb49de92d9859.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7e172751910148bccb49de92d9859.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP TABLE GROUP Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "bb62f12fef1c445189837576189c7143.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bb62f12fef1c445189837576189c7143.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP TABLE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d7fd287519101480afbce1b997e4b9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d7fd287519101480afbce1b997e4b9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP TOKEN EXCHANGER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "f5db5d688f3e4f069b67b9088f34eb3b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f5db5d688f3e4f069b67b9088f34eb3b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP TRIGGER Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d81ec9751910148fe6e1e072ac439e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d81ec9751910148fe6e1e072ac439e.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP TYPE Statement (Procedural)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d83beb751910148651cebdf3564ad3.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d83beb751910148651cebdf3564ad3.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP USER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d8d33275191014adce9c099eeed35c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d8d33275191014adce9c099eeed35c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP USERGROUP Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "6dc0adae9f4c4ebaa46cbe6b5f636ee7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6dc0adae9f4c4ebaa46cbe6b5f636ee7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP VECTOR INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "3e5e6e9b6fc14561b242fd22d97dbf91.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3e5e6e9b6fc14561b242fd22d97dbf91.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP VIEW Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d9c05f75191014b24fca55a8534531.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d9c05f75191014b24fca55a8534531.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP WORKLOAD CLASS Statement (Workload Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "22f628bdb85d4ccd885cf642d3fd31c4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/22f628bdb85d4ccd885cf642d3fd31c4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP WORKLOAD MAPPING Statement (Workload Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "8d90e94880924f7d957ba73db7e7db17.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8d90e94880924f7d957ba73db7e7db17.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "DROP X509 PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "f7a37e81a9b64a2cb6a6092a38b06c60.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f7a37e81a9b64a2cb6a6092a38b06c60.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "EXPLAIN PLAN Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d9ec5575191014a251e58ecf90997a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d9ec5575191014a251e58ecf90997a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "EXPORT Statement (Data Import Export)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20da0bec751910148e69c9668ea3ccb8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20da0bec751910148e69c9668ea3ccb8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "EXPORT INTO RDF FILE Statement (Data Import Export)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "EXPORT INTO Statement (Data Import Export)" - ], - "file": "644d06c7e0d94343b3872a88acb08c33.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/644d06c7e0d94343b3872a88acb08c33.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "GRANT Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f674e1751910148a8b990d33efbdc5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f674e1751910148a8b990d33efbdc5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "IMPORT Statement (Data Import Export)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f75ade751910148492a90e5e375b8f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f75ade751910148492a90e5e375b8f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "IMPORT FROM RDF FILE Statement (Data Import Export)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "IMPORT FROM Statement (Data Import Export)" - ], - "file": "f07faf9748d549dda8c70ca0b5d2ba20.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f07faf9748d549dda8c70ca0b5d2ba20.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "IMPORT SCAN Statement (Data Import Export)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f79b2175191014a45f9947577a2e85.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f79b2175191014a45f9947577a2e85.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "INSERT Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f7f70975191014a76da70c9181720e.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f7f70975191014a76da70c9181720e.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "title": "LOAD Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f83c8c75191014b215d6c8c427c91b.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f83c8c75191014b215d6c8c427c91b.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "LOCK TABLE Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f88d8d75191014a51abbaa4e3d36cb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f88d8d75191014a51abbaa4e3d36cb.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "MERGE DELTA Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f8d0a175191014a7c192193b8645a9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f8d0a175191014a7c192193b8645a9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "MERGE INTO Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "3226201f95764a57810dd256c9524d56.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3226201f95764a57810dd256c9524d56.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "REFRESH PSE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "c2f1007259654a8f941bab6cebd0ad31.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c2f1007259654a8f941bab6cebd0ad31.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "REFRESH STATISTICS Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fae6d975191014849d91781fd50986.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fae6d975191014849d91781fd50986.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "REFRESH VIEW Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "81e15837ac7249938e05e346c391ead5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/81e15837ac7249938e05e346c391ead5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "RELEASE SAVEPOINT Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "445eb4d2202f4f29b67e9874a3c9acfb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/445eb4d2202f4f29b67e9874a3c9acfb.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "RENAME COLUMN Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fb2b8b7519101499d2c6bd37c81b32.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fb2b8b7519101499d2c6bd37c81b32.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "RENAME INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fb6e10751910148b45cefcb6294342.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fb6e10751910148b45cefcb6294342.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "RENAME SCHEMA Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "a52198083ad642f79851b8f501aad7f5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/a52198083ad642f79851b8f501aad7f5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "RENAME TABLE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fbadb2751910148b24d8d93aff01d4.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fbadb2751910148b24d8d93aff01d4.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "RENAME VECTOR INDEX Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "8b2f122785f24dde8f2b6441b47914b0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/8b2f122785f24dde8f2b6441b47914b0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "REPLACE Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fc06a7751910149892c0d09be21a38.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fc06a7751910149892c0d09be21a38.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "REVOKE Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fc91cb75191014ac15eb4d6f2d7dde.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fc91cb75191014ac15eb4d6f2d7dde.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ROLLBACK Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fcc453751910149557fc90fe781449.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fcc453751910149557fc90fe781449.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ROLLBACK TO SAVEPOINT Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "104ae26787e24bddbda2953c0397b6e8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/104ae26787e24bddbda2953c0397b6e8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SAVEPOINT Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "cd4172aead1e47e99f6599656887f343.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/cd4172aead1e47e99f6599656887f343.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "HINT Details", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements", - "SELECT Statement (Data Manipulation)" - ], - "file": "4ba9edce1f2347a0b9fcda99879c17a1.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4ba9edce1f2347a0b9fcda99879c17a1.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET PSE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "10fe8070539649358c79955110311082.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/10fe8070539649358c79955110311082.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET [SESSION] Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fd82b675191014b22c8af08d0b319c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fd82b675191014b22c8af08d0b319c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET SESSION CREDENTIAL FOR REMOTE SOURCE (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "3480cdfb947844ab8c60dabe16a5daef.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3480cdfb947844ab8c60dabe16a5daef.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET ROLEGROUP Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "6e62e7ef3b7949eb83c47115dc47e2c8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6e62e7ef3b7949eb83c47115dc47e2c8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET SCHEMA Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fd550375191014b886a338afb4cd5f.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fd550375191014b886a338afb4cd5f.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET TRANSACTION Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fdf9cb75191014b85aaa9dec841291.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fdf9cb75191014b85aaa9dec841291.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET TRANSACTION AUTOCOMMIT DDL Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "d538d11053bd4f3f847ec5ce817a3d4c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/d538d11053bd4f3f847ec5ce817a3d4c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SET USERGROUP Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "19918539993849888af17415d43382b5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/19918539993849888af17415d43382b5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "TRUNCATE TABLE Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fe29f0751910149904f0c5c3201cfa.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fe29f0751910149904f0c5c3201cfa.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UNLOAD Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fe92a2751910148c38887562a97c5a.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fe92a2751910148c38887562a97c5a.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UNSET PSE Statement (System Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "408255391bd043209a957830f8e87b65.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/408255391bd043209a957830f8e87b65.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UNSET [SESSION] Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fec78075191014a376da819b302f43.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fec78075191014a376da819b302f43.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UNSET ROLEGROUP Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "2f2ee71a3da04b248216d7915e85cb11.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2f2ee71a3da04b248216d7915e85cb11.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UNSET SESSION CREDENTIAL FOR REMOTE SOURCE (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "348e978c588c4905957ece4126f98126.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/348e978c588c4905957ece4126f98126.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UNSET TRANSACTION Statement (Transaction Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "bc90c1228539462a99344eb3d39dae00.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/bc90c1228539462a99344eb3d39dae00.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UNSET USERGROUP Statement (Session Management)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "996f99709bfa4037a9dcce812b6d57d9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/996f99709bfa4037a9dcce812b6d57d9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "UPDATE Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20ff268675191014964add3d17700909.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20ff268675191014964add3d17700909.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "title": "UPSERT Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "ea8b6773be584203bcd99da76844c5ed.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/ea8b6773be584203bcd99da76844c5ed.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "title": "VALIDATE LDAP PROVIDER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "4181217e3e104c57a5090431c1cd70b7.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/4181217e3e104c57a5090431c1cd70b7.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "VALIDATE USER Statement (Access Control)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "5e336347cb8444279b451c172ad00c75.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5e336347cb8444279b451c172ad00c75.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Access Control Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "20a40b54751910148a82d91c57a21c1c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a40b54751910148a82d91c57a21c1c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Data Definition Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "209ce8cd75191014bcd59c2b379a17c9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209ce8cd75191014bcd59c2b379a17c9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Data Import Export Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "20a5342e75191014bb95e83cbbe772fa.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a5342e75191014bb95e83cbbe772fa.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Data Manipulation Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "209eaa85751910149a30f95c936075be.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/209eaa85751910149a30f95c936075be.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Graph Workspace Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "953a96f81f774fdeb733b83987ac6693.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/953a96f81f774fdeb733b83987ac6693.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "JSON Document Store Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "2282aef7db6846b68f09d72be04cb9c0.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/2282aef7db6846b68f09d72be04cb9c0.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Procedural Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "20a64c8c75191014af7ce80b4895b2eb.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a64c8c75191014af7ce80b4895b2eb.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Session Management Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "20a27b0a75191014a5bd9e2a08ff9354.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a27b0a75191014a5bd9e2a08ff9354.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Smart Data Integration and Smart Data Quality Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "86526627ff5e4362922c72048c9c61f5.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/86526627ff5e4362922c72048c9c61f5.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "System Management Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "20a1c3a975191014be0cf8b1b853ddf8.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a1c3a975191014be0cf8b1b853ddf8.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Transaction Management Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "20a3ae8a75191014b039b36c43e2029d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a3ae8a75191014b039b36c43e2029d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Workload Management Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "c5f48e60b55645fe91b241c4d0b89278.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/c5f48e60b55645fe91b241c4d0b89278.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "System Limitations", - "path": [ - "SQL Reference" - ], - "file": "20a760537519101497e3cfe07b348f3c.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a760537519101497e3cfe07b348f3c.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SQL Error Codes", - "path": [ - "SQL Reference" - ], - "file": "20a78d3275191014b41bae7c4a46d835.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a78d3275191014b41bae7c4a46d835.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Predicates", - "path": [ - "SQL Reference" - ], - "file": "20a2ab29751910148de0fe7189c330bc.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a2ab29751910148de0fe7189c330bc.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SQL Functions", - "path": [ - "SQL Reference" - ], - "file": "20a61f29751910149f99f0300dd95cd9.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a61f29751910149f99f0300dd95cd9.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Alphabetical List Of Functions", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "f12b86a6284c4aeeb449e57eb5dd3ebd.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/f12b86a6284c4aeeb449e57eb5dd3ebd.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Window Functions and the Window Specification", - "path": [ - "SQL Reference", - "SQL Functions" - ], - "file": "20a353327519101495dfd0a87060a0d3.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a353327519101495dfd0a87060a0d3.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SQL Statements", - "path": [ - "SQL Reference" - ], - "file": "20a6791f751910148d2bfe3814192a01.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20a6791f751910148d2bfe3814192a01.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "Alphabetical List of Statements", - "path": [ - "SQL Reference", - "SQL Statements" - ], - "file": "3bc1a0d4611d40c4a6e3fc7c8e80395d.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/3bc1a0d4611d40c4a6e3fc7c8e80395d.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER SYSTEM ... (All ALTER SYSTEM Statements)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "5f62bd7ebd0f471494faffaec4015041.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/5f62bd7ebd0f471494faffaec4015041.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "ALTER TABLE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d329a6751910149d5fdbc4800f92ff.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d329a6751910149d5fdbc4800f92ff.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "title": "CREATE TABLE Statement (Data Definition)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20d58a5f75191014b2fe92141b7df228.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20d58a5f75191014b2fe92141b7df228.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "title": "EXPORT INTO Statement (Data Import Export)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "6a6f59bbfbb64ade84d83d7f87789753.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/6a6f59bbfbb64ade84d83d7f87789753.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "IMPORT FROM Statement (Data Import Export)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20f712e175191014907393741fadcb97.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20f712e175191014907393741fadcb97.html?version=2026_2_QRC", - "status": "not_exhaustively_implemented", - "tests": [] - }, - { - "title": "SELECT Statement (Data Manipulation)", - "path": [ - "SQL Reference", - "SQL Statements", - "Alphabetical List of Statements" - ], - "file": "20fcf24075191014a89e9dc7b8408b26.html", - "source": "https://help.sap.com/docs/HANA_CLOUD_DATABASE/c1d3f60099654ecfb3fe36ac93c121bb/20fcf24075191014a89e9dc7b8408b26.html?version=2026_2_QRC", - "status": "partially_implemented", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - } -] diff --git a/docs/hana/functions.json b/docs/hana/functions.json deleted file mode 100644 index ff3b50ce..00000000 --- a/docs/hana/functions.json +++ /dev/null @@ -1,1795 +0,0 @@ -[ - { - "id": "4.9.1.1", - "name": "ABAP_ALPHANUM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=83", - "builtin_recognized": true - }, - { - "id": "4.9.1.2", - "name": "ABAP_DF16RAW_TO_SMALLDECIMAL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=85", - "builtin_recognized": true - }, - { - "id": "4.9.1.3", - "name": "ABAP_DF34RAW_TO_DECIMAL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=85", - "builtin_recognized": true - }, - { - "id": "4.9.1.4", - "name": "ABAP_NUMC", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=86", - "builtin_recognized": true - }, - { - "id": "4.9.1.5", - "name": "ABAP_LOWER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=88", - "builtin_recognized": true - }, - { - "id": "4.9.1.6", - "name": "ABAP_UPPER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=89", - "builtin_recognized": true - }, - { - "id": "4.9.1.7", - "name": "ABS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=89", - "builtin_recognized": true - }, - { - "id": "4.9.1.8", - "name": "ACOS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=90", - "builtin_recognized": true - }, - { - "id": "4.9.1.9", - "name": "ADD_DAYS", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=91", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.10", - "name": "ADD_MONTHS", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=92", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.11", - "name": "ADD_MONTHS_LAST", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=94", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.12", - "name": "ADD_NANO100", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=95", - "builtin_recognized": true - }, - { - "id": "4.9.1.13", - "name": "ADD_SECONDS", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=96", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.14", - "name": "ADD_WORKDAYS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=97", - "builtin_recognized": true - }, - { - "id": "4.9.1.15", - "name": "ADD_YEARS", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=101", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.16", - "name": "ALLOW_PRECISION_LOSS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=102", - "builtin_recognized": true - }, - { - "id": "4.9.1.17", - "name": "ASCII", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=103", - "builtin_recognized": true - }, - { - "id": "4.9.1.18", - "name": "ASIN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=104", - "builtin_recognized": true - }, - { - "id": "4.9.1.19", - "name": "ATAN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=105", - "builtin_recognized": true - }, - { - "id": "4.9.1.20", - "name": "ATAN2", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=105", - "builtin_recognized": true - }, - { - "id": "4.9.1.21", - "name": "AUTO_CORR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=106", - "builtin_recognized": true - }, - { - "id": "4.9.1.22", - "name": "AVG", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=109", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.23", - "name": "BINNING", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=110", - "builtin_recognized": true - }, - { - "id": "4.9.1.24", - "name": "BINTOHEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=112", - "builtin_recognized": true - }, - { - "id": "4.9.1.25", - "name": "BINTONHEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=113", - "builtin_recognized": true - }, - { - "id": "4.9.1.26", - "name": "BINTOSTR", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=114", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.27", - "name": "BITAND", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=115", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.28", - "name": "BITCOUNT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=116", - "builtin_recognized": true - }, - { - "id": "4.9.1.29", - "name": "BITNOT", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=117", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.30", - "name": "BITOR", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=118", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.31", - "name": "BITSET", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=119", - "builtin_recognized": true - }, - { - "id": "4.9.1.32", - "name": "BITUNSET", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=121", - "builtin_recognized": true - }, - { - "id": "4.9.1.33", - "name": "BITXOR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=122", - "builtin_recognized": true - }, - { - "id": "4.9.1.34", - "name": "CARDINALITY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=123", - "builtin_recognized": true - }, - { - "id": "4.9.1.35", - "name": "CAST", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=124", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.36", - "name": "CEIL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=125", - "builtin_recognized": true - }, - { - "id": "4.9.1.37", - "name": "CHAR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=126", - "builtin_recognized": true - }, - { - "id": "4.9.1.38", - "name": "COALESCE", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=127", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.39", - "name": "CONCAT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=128", - "builtin_recognized": true - }, - { - "id": "4.9.1.40", - "name": "CONCAT_NAZ", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=129", - "builtin_recognized": true - }, - { - "id": "4.9.1.41", - "name": "CONVERT_CURRENCY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=130", - "builtin_recognized": true - }, - { - "id": "4.9.1.42", - "name": "CONVERT_UNIT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=140", - "builtin_recognized": true - }, - { - "id": "4.9.1.43", - "name": "CORR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=144", - "builtin_recognized": true - }, - { - "id": "4.9.1.44", - "name": "CORR_SPEARMAN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=147", - "builtin_recognized": true - }, - { - "id": "4.9.1.45", - "name": "COS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=151", - "builtin_recognized": true - }, - { - "id": "4.9.1.46", - "name": "COSH", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=152", - "builtin_recognized": true - }, - { - "id": "4.9.1.47", - "name": "COT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=153", - "builtin_recognized": true - }, - { - "id": "4.9.1.48", - "name": "COUNT", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=154", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.49", - "name": "CROSS_CORR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=155", - "builtin_recognized": true - }, - { - "id": "4.9.1.50", - "name": "CUBIC_SPLINE_APPROX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=158", - "builtin_recognized": true - }, - { - "id": "4.9.1.51", - "name": "CUME_DIST", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=163", - "builtin_recognized": true - }, - { - "id": "4.9.1.52", - "name": "CURRENT_CONNECTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=165", - "builtin_recognized": true - }, - { - "id": "4.9.1.53", - "name": "CURRENT_DATABASE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=165", - "builtin_recognized": true - }, - { - "id": "4.9.1.54", - "name": "CURRENT_DATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=166", - "builtin_recognized": true - }, - { - "id": "4.9.1.55", - "name": "CURRENT_IDENTITY_VALUE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=167", - "builtin_recognized": true - }, - { - "id": "4.9.1.56", - "name": "CURRENT_MVCC_SNAPSHOT_TIMESTAMP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=168", - "builtin_recognized": true - }, - { - "id": "4.9.1.57", - "name": "CURRENT_OBJECT_SCHEMA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=168", - "builtin_recognized": true - }, - { - "id": "4.9.1.58", - "name": "CURRENT_SCHEMA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=169", - "builtin_recognized": true - }, - { - "id": "4.9.1.59", - "name": "CURRENT_SITE_ID", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=170", - "builtin_recognized": true - }, - { - "id": "4.9.1.60", - "name": "CURRENT_TIME", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=171", - "builtin_recognized": true - }, - { - "id": "4.9.1.61", - "name": "CURRENT_TIMESTAMP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=171", - "builtin_recognized": true - }, - { - "id": "4.9.1.64", - "name": "CURRENT_UPDATE_TRANSACTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=174", - "builtin_recognized": true - }, - { - "id": "4.9.1.65", - "name": "CURRENT_USER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=175", - "builtin_recognized": true - }, - { - "id": "4.9.1.66", - "name": "CURRENT_USER_ID", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=176", - "builtin_recognized": true - }, - { - "id": "4.9.1.67", - "name": "CURRENT_UTCDATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=176", - "builtin_recognized": true - }, - { - "id": "4.9.1.68", - "name": "CURRENT_UTCTIME", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=177", - "builtin_recognized": true - }, - { - "id": "4.9.1.69", - "name": "CURRENT_UTCTIMESTAMP", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=178", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.70", - "name": "DAYNAME", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=179", - "builtin_recognized": true - }, - { - "id": "4.9.1.71", - "name": "DAYOFMONTH", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=180", - "builtin_recognized": true - }, - { - "id": "4.9.1.72", - "name": "DAYOFYEAR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=181", - "builtin_recognized": true - }, - { - "id": "4.9.1.73", - "name": "DAYS_BETWEEN", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=181", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.74", - "name": "DENSE_RANK", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=183", - "builtin_recognized": true - }, - { - "id": "4.9.1.75", - "name": "DFT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=184", - "builtin_recognized": true - }, - { - "id": "4.9.1.80", - "name": "ESCAPE_DOUBLE_QUOTES", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=191", - "builtin_recognized": true - }, - { - "id": "4.9.1.81", - "name": "ESCAPE_SINGLE_QUOTES", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=192", - "builtin_recognized": true - }, - { - "id": "4.9.1.82", - "name": "EXP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=193", - "builtin_recognized": true - }, - { - "id": "4.9.1.83", - "name": "EXPRESSION_MACRO", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=193", - "builtin_recognized": true - }, - { - "id": "4.9.1.84", - "name": "EXTRACT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=194", - "builtin_recognized": true - }, - { - "id": "4.9.1.85", - "name": "FIRST_VALUE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=195", - "builtin_recognized": true - }, - { - "id": "4.9.1.86", - "name": "FLOOR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=197", - "builtin_recognized": true - }, - { - "id": "4.9.1.87", - "name": "GENERATE_PASSWORD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=198", - "builtin_recognized": true - }, - { - "id": "4.9.1.88", - "name": "GREATEST", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=199", - "builtin_recognized": true - }, - { - "id": "4.9.1.89", - "name": "GROUP_SCORE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=199", - "builtin_recognized": true - }, - { - "id": "4.9.1.90", - "name": "GROUPING", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=203", - "builtin_recognized": true - }, - { - "id": "4.9.1.91", - "name": "GROUPING_ID", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=205", - "builtin_recognized": true - }, - { - "id": "4.9.1.92", - "name": "HAMMING_DISTANCE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=207", - "builtin_recognized": true - }, - { - "id": "4.9.1.93", - "name": "HASH_MD5", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=208", - "builtin_recognized": true - }, - { - "id": "4.9.1.94", - "name": "HASH_SHA256", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=210", - "builtin_recognized": true - }, - { - "id": "4.9.1.95", - "name": "HEXTOBIN", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=211", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.96", - "name": "HEXTONUM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=212", - "builtin_recognized": true - }, - { - "id": "4.9.1.97", - "name": "HOUR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=213", - "builtin_recognized": true - }, - { - "id": "4.9.1.98", - "name": "IFNULL", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=213", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.99", - "name": "INDEXING_ERROR_CODE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=214", - "builtin_recognized": true - }, - { - "id": "4.9.1.100", - "name": "INDEXING_ERROR_MESSAGE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=215", - "builtin_recognized": true - }, - { - "id": "4.9.1.101", - "name": "INDEXING_STATUS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=216", - "builtin_recognized": true - }, - { - "id": "4.9.1.102", - "name": "INITCAP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=218", - "builtin_recognized": true - }, - { - "id": "4.9.1.103", - "name": "IS_SQL_INJECTION_SAFE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=219", - "builtin_recognized": true - }, - { - "id": "4.9.1.104", - "name": "ISOWEEK", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=220", - "builtin_recognized": true - }, - { - "id": "4.9.1.105", - "name": "JSON_QUERY", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=221", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.106", - "name": "JSON_TABLE", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=224", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.107", - "name": "JSON_VALUE", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=233", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.108", - "name": "LAG", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=236", - "builtin_recognized": true - }, - { - "id": "4.9.1.109", - "name": "LANGUAGE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=238", - "builtin_recognized": true - }, - { - "id": "4.9.1.110", - "name": "LAST_DAY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=238", - "builtin_recognized": true - }, - { - "id": "4.9.1.111", - "name": "LAST_VALUE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=239", - "builtin_recognized": true - }, - { - "id": "4.9.1.112", - "name": "LCASE", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=241", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.113", - "name": "LEAD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=242", - "builtin_recognized": true - }, - { - "id": "4.9.1.114", - "name": "LEAST", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=243", - "builtin_recognized": true - }, - { - "id": "4.9.1.115", - "name": "LEFT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=244", - "builtin_recognized": true - }, - { - "id": "4.9.1.116", - "name": "LENGTH", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=245", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.117", - "name": "LINEAR_APPROX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=246", - "builtin_recognized": true - }, - { - "id": "4.9.1.118", - "name": "LN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=250", - "builtin_recognized": true - }, - { - "id": "4.9.1.119", - "name": "LOCALTOUTC", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=251", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs" - ] - }, - { - "id": "4.9.1.120", - "name": "LOCATE", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=252", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.121", - "name": "LOCATE_REGEXPR", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=253", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.122", - "name": "LOG", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=256", - "builtin_recognized": true - }, - { - "id": "4.9.1.123", - "name": "LOWER", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=256", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.124", - "name": "LPAD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=257", - "builtin_recognized": true - }, - { - "id": "4.9.1.125", - "name": "LTRIM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=258", - "builtin_recognized": true - }, - { - "id": "4.9.1.126", - "name": "MAP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=259", - "builtin_recognized": true - }, - { - "id": "4.9.1.127", - "name": "MAX", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=261", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.128", - "name": "MEDIAN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=262", - "builtin_recognized": true - }, - { - "id": "4.9.1.129", - "name": "MEMBER_AT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=265", - "builtin_recognized": true - }, - { - "id": "4.9.1.130", - "name": "MIMETYPE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=266", - "builtin_recognized": true - }, - { - "id": "4.9.1.131", - "name": "MIN", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=267", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.132", - "name": "MINUTE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=269", - "builtin_recognized": true - }, - { - "id": "4.9.1.133", - "name": "MOD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=270", - "builtin_recognized": true - }, - { - "id": "4.9.1.134", - "name": "MONTH", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=271", - "builtin_recognized": true - }, - { - "id": "4.9.1.135", - "name": "MONTHNAME", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=271", - "builtin_recognized": true - }, - { - "id": "4.9.1.136", - "name": "MONTHS_BETWEEN", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=272", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.137", - "name": "NANO100_BETWEEN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=273", - "builtin_recognized": true - }, - { - "id": "4.9.1.138", - "name": "NCHAR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=274", - "builtin_recognized": true - }, - { - "id": "4.9.1.139", - "name": "NDIV0", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=275", - "builtin_recognized": true - }, - { - "id": "4.9.1.140", - "name": "NEXT_DAY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=276", - "builtin_recognized": true - }, - { - "id": "4.9.1.141", - "name": "NEWUID", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=276", - "builtin_recognized": true - }, - { - "id": "4.9.1.142", - "name": "NORMALIZE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=277", - "builtin_recognized": true - }, - { - "id": "4.9.1.143", - "name": "NOW", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=280", - "builtin_recognized": true - }, - { - "id": "4.9.1.144", - "name": "NTH_VALUE", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=280", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.145", - "name": "NTILE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=282", - "builtin_recognized": true - }, - { - "id": "4.9.1.146", - "name": "NULLIF", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=284", - "builtin_recognized": true - }, - { - "id": "4.9.1.147", - "name": "NUMTOHEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=285", - "builtin_recognized": true - }, - { - "id": "4.9.1.148", - "name": "OCCURRENCES_REGEXPR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=286", - "builtin_recognized": true - }, - { - "id": "4.9.1.149", - "name": "PERCENT_RANK", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=287", - "builtin_recognized": true - }, - { - "id": "4.9.1.150", - "name": "PERCENTILE_CONT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=289", - "builtin_recognized": true - }, - { - "id": "4.9.1.151", - "name": "PERCENTILE_DISC", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=291", - "builtin_recognized": true - }, - { - "id": "4.9.1.152", - "name": "PLAINTEXT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=293", - "builtin_recognized": true - }, - { - "id": "4.9.1.153", - "name": "POWER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=293", - "builtin_recognized": true - }, - { - "id": "4.9.1.154", - "name": "QUARTER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=294", - "builtin_recognized": true - }, - { - "id": "4.9.1.155", - "name": "RAND", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=295", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.156", - "name": "RANDOM_PARTITION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=296", - "builtin_recognized": true - }, - { - "id": "4.9.1.157", - "name": "RAND_SECURE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=299", - "builtin_recognized": true - }, - { - "id": "4.9.1.158", - "name": "RANK", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=300", - "builtin_recognized": true - }, - { - "id": "4.9.1.159", - "name": "RECORD_COMMIT_TIMESTAMP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=301", - "builtin_recognized": true - }, - { - "id": "4.9.1.160", - "name": "RECORD_ID", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=302", - "builtin_recognized": true - }, - { - "id": "4.9.1.161", - "name": "REPLACE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=304", - "builtin_recognized": true - }, - { - "id": "4.9.1.162", - "name": "REPLACE_REGEXPR", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=305", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.163", - "name": "RESULT_CACHE_ID", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=307", - "builtin_recognized": true - }, - { - "id": "4.9.1.164", - "name": "RESULT_CACHE_REFRESH_TIME", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=308", - "builtin_recognized": true - }, - { - "id": "4.9.1.165", - "name": "RIGHT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=308", - "builtin_recognized": true - }, - { - "id": "4.9.1.166", - "name": "ROUND", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=310", - "builtin_recognized": true - }, - { - "id": "4.9.1.167", - "name": "RPAD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=312", - "builtin_recognized": true - }, - { - "id": "4.9.1.168", - "name": "RTRIM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=313", - "builtin_recognized": true - }, - { - "id": "4.9.1.169", - "name": "ROW_NUMBER", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=314", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.170", - "name": "SCORE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=316", - "builtin_recognized": true - }, - { - "id": "4.9.1.171", - "name": "SECOND", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=321", - "builtin_recognized": true - }, - { - "id": "4.9.1.172", - "name": "SECONDS_BETWEEN", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=321", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.173", - "name": "SERIES_DISAGGREGATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=322", - "builtin_recognized": true - }, - { - "id": "4.9.1.174", - "name": "SERIES_ELEMENT_TO_PERIOD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=327", - "builtin_recognized": true - }, - { - "id": "4.9.1.175", - "name": "SERIES_FILTER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=328", - "builtin_recognized": true - }, - { - "id": "4.9.1.176", - "name": "SERIES_GENERATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=332", - "builtin_recognized": true - }, - { - "id": "4.9.1.177", - "name": "SERIES_PERIOD_TO_ELEMENT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=337", - "builtin_recognized": true - }, - { - "id": "4.9.1.178", - "name": "SERIES_ROUND", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=339", - "builtin_recognized": true - }, - { - "id": "4.9.1.179", - "name": "SESSION_CONTEXT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=342", - "builtin_recognized": true - }, - { - "id": "4.9.1.180", - "name": "SESSION_USER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=343", - "builtin_recognized": true - }, - { - "id": "4.9.1.181", - "name": "SIGN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=345", - "builtin_recognized": true - }, - { - "id": "4.9.1.182", - "name": "SIN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=346", - "builtin_recognized": true - }, - { - "id": "4.9.1.183", - "name": "SINH", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=346", - "builtin_recognized": true - }, - { - "id": "4.9.1.184", - "name": "SOUNDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=347", - "builtin_recognized": true - }, - { - "id": "4.9.1.185", - "name": "SQRT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=348", - "builtin_recognized": true - }, - { - "id": "4.9.1.186", - "name": "STDDEV", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=349", - "builtin_recognized": true - }, - { - "id": "4.9.1.187", - "name": "STDDEV_POP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=351", - "builtin_recognized": true - }, - { - "id": "4.9.1.188", - "name": "STDDEV_SAMP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=352", - "builtin_recognized": true - }, - { - "id": "4.9.1.189", - "name": "STRING_AGG", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=353", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.190", - "name": "STRTOBIN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=355", - "builtin_recognized": true - }, - { - "id": "4.9.1.191", - "name": "SUBARRAY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=356", - "builtin_recognized": true - }, - { - "id": "4.9.1.192", - "name": "SUBSTR_AFTER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=358", - "builtin_recognized": true - }, - { - "id": "4.9.1.193", - "name": "SUBSTR_BEFORE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=359", - "builtin_recognized": true - }, - { - "id": "4.9.1.194", - "name": "SUBSTRING_REGEXPR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=360", - "builtin_recognized": true - }, - { - "id": "4.9.1.195", - "name": "SUBSTRING", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=362", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.196", - "name": "SUM", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=363", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.197", - "name": "SYSUUID", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=364", - "builtin_recognized": true - }, - { - "id": "4.9.1.198", - "name": "TAN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=365", - "builtin_recognized": true - }, - { - "id": "4.9.1.199", - "name": "TANH", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=366", - "builtin_recognized": true - }, - { - "id": "4.9.1.200", - "name": "TO_ALPHANUM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=366", - "builtin_recognized": true - }, - { - "id": "4.9.1.201", - "name": "TO_BIGINT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=367", - "builtin_recognized": true - }, - { - "id": "4.9.1.202", - "name": "TO_BINARY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=368", - "builtin_recognized": true - }, - { - "id": "4.9.1.203", - "name": "TO_BLOB", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=369", - "builtin_recognized": true - }, - { - "id": "4.9.1.204", - "name": "TO_BOOLEAN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=369", - "builtin_recognized": true - }, - { - "id": "4.9.1.205", - "name": "TO_CLOB", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=370", - "builtin_recognized": true - }, - { - "id": "4.9.1.206", - "name": "TO_DATE", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=371", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.207", - "name": "TO_DATS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=372", - "builtin_recognized": true - }, - { - "id": "4.9.1.208", - "name": "TO_DECIMAL", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=373", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.209", - "name": "TO_DOUBLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=374", - "builtin_recognized": true - }, - { - "id": "4.9.1.210", - "name": "TO_FIXEDCHAR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=375", - "builtin_recognized": true - }, - { - "id": "4.9.1.211", - "name": "TO_INT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=375", - "builtin_recognized": true - }, - { - "id": "4.9.1.212", - "name": "TO_INTEGER", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=376", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.214", - "name": "TO_NCLOB", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=378", - "builtin_recognized": true - }, - { - "id": "4.9.1.215", - "name": "TO_NVARCHAR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=378", - "builtin_recognized": true - }, - { - "id": "4.9.1.216", - "name": "TO_REAL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=380", - "builtin_recognized": true - }, - { - "id": "4.9.1.217", - "name": "TO_SECONDDATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=381", - "builtin_recognized": true - }, - { - "id": "4.9.1.218", - "name": "TO_SMALLDECIMAL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=382", - "builtin_recognized": true - }, - { - "id": "4.9.1.219", - "name": "TO_SMALLINT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=382", - "builtin_recognized": true - }, - { - "id": "4.9.1.220", - "name": "TO_TIME", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=383", - "builtin_recognized": true - }, - { - "id": "4.9.1.221", - "name": "TO_TIMESTAMP", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=384", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.222", - "name": "TO_TINYINT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=385", - "builtin_recognized": true - }, - { - "id": "4.9.1.223", - "name": "TO_VARCHAR", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=386", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions" - ] - }, - { - "id": "4.9.1.224", - "name": "TRIM", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=387", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.225", - "name": "TRIM_ARRAY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=388", - "builtin_recognized": true - }, - { - "id": "4.9.1.226", - "name": "UCASE", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=389", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.227", - "name": "UMINUS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=390", - "builtin_recognized": true - }, - { - "id": "4.9.1.228", - "name": "UNICODE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=391", - "builtin_recognized": true - }, - { - "id": "4.9.1.229", - "name": "UPPER", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=392", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - }, - { - "id": "4.9.1.230", - "name": "UTCTOLOCAL", - "status": "regression_tested_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=392", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs" - ] - }, - { - "id": "4.9.1.233", - "name": "VAR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=398", - "builtin_recognized": true - }, - { - "id": "4.9.1.234", - "name": "VAR_POP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=399", - "builtin_recognized": true - }, - { - "id": "4.9.1.235", - "name": "VAR_SAMP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=401", - "builtin_recognized": true - }, - { - "id": "4.9.1.236", - "name": "WEEK", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=402", - "builtin_recognized": true - }, - { - "id": "4.9.1.237", - "name": "WEEKDAY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=403", - "builtin_recognized": true - }, - { - "id": "4.9.1.238", - "name": "WEIGHTED_AVG", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=404", - "builtin_recognized": true - }, - { - "id": "4.9.1.239", - "name": "WIDTH_BUCKET", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=406", - "builtin_recognized": true - }, - { - "id": "4.9.1.240", - "name": "WORKDAYS_BETWEEN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=407", - "builtin_recognized": true - }, - { - "id": "4.9.1.241", - "name": "XMLEXTRACT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=411", - "builtin_recognized": true - }, - { - "id": "4.9.1.242", - "name": "XMLEXTRACTVALUE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=413", - "builtin_recognized": true - }, - { - "id": "4.9.1.243", - "name": "XMLTABLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=414", - "builtin_recognized": true - }, - { - "id": "4.9.1.244", - "name": "YEAR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=420", - "builtin_recognized": true - }, - { - "id": "4.9.1.245", - "name": "YEARS_BETWEEN", - "status": "native_fixture_forms", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=421", - "builtin_recognized": true, - "tests": [ - "crates/polyglot-sql/tests/custom_fixtures/hana/functions.json" - ] - } -] diff --git a/docs/hana/statements.json b/docs/hana/statements.json deleted file mode 100644 index 506a5873..00000000 --- a/docs/hana/statements.json +++ /dev/null @@ -1,1042 +0,0 @@ -[ - { - "id": "4.10.1.1", - "name": "ALTER AUDIT POLICY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=439" - }, - { - "id": "4.10.1.2", - "name": "ALTER CLIENTSIDE ENCRYPTION COLUMN KEY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=442" - }, - { - "id": "4.10.1.3", - "name": "ALTER CLIENTSIDE ENCRYPTION KEYPAIR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=445" - }, - { - "id": "4.10.1.4", - "name": "ALTER CREDENTIAL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=446" - }, - { - "id": "4.10.1.5", - "name": "ALTER DATABASE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=448" - }, - { - "id": "4.10.1.6", - "name": "ALTER FULLTEXT INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=452" - }, - { - "id": "4.10.1.7", - "name": "ALTER FUNCTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=455" - }, - { - "id": "4.10.1.8", - "name": "ALTER INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=460" - }, - { - "id": "4.10.1.9", - "name": "ALTER JWT PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=463" - }, - { - "id": "4.10.1.10", - "name": "ALTER LDAP PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=466" - }, - { - "id": "4.10.1.11", - "name": "ALTER LIBRARY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=470" - }, - { - "id": "4.10.1.12", - "name": "ALTER PROCEDURE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=472" - }, - { - "id": "4.10.1.13", - "name": "ALTER PSE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=476" - }, - { - "id": "4.10.1.14", - "name": "ALTER REMOTE SOURCE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=480" - }, - { - "id": "4.10.1.15", - "name": "ALTER ROLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=483" - }, - { - "id": "4.10.1.16", - "name": "ALTER SAML PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=485" - }, - { - "id": "4.10.1.17", - "name": "ALTER SEQUENCE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=487" - }, - { - "id": "4.10.1.18", - "name": "ALTER SCHEDULER JOB", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=490" - }, - { - "id": "4.10.1.19", - "name": "ALTER STATISTICS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=492" - }, - { - "id": "4.10.1.20", - "name": "ALTER STRUCTURED PRIVILEGE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=499" - }, - { - "id": "4.10.1.21", - "name": "ALTER SYSTEM ...", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=501" - }, - { - "id": "4.10.1.22", - "name": "ALTER TABLE", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=603", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.23", - "name": "ALTER USER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=670" - }, - { - "id": "4.10.1.24", - "name": "ALTER USERGROUP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=680" - }, - { - "id": "4.10.1.25", - "name": "ALTER VIEW", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=685" - }, - { - "id": "4.10.1.26", - "name": "ALTER VIRTUAL TABLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=693" - }, - { - "id": "4.10.1.27", - "name": "ALTER WORKLOAD CLASS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=695" - }, - { - "id": "4.10.1.28", - "name": "ALTER WORKLOAD MAPPING", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=699" - }, - { - "id": "4.10.1.29", - "name": "ALTER X509 PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=702" - }, - { - "id": "4.10.1.30", - "name": "ANNOTATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=703" - }, - { - "id": "4.10.1.31", - "name": "BACKUP CANCEL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=705" - }, - { - "id": "4.10.1.32", - "name": "BACKUP CATALOG DELETE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=707" - }, - { - "id": "4.10.1.33", - "name": "BACKUP CATALOG RETAINED", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=710" - }, - { - "id": "4.10.1.34", - "name": "BACKUP CHECK", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=712" - }, - { - "id": "4.10.1.35", - "name": "BACKUP CHECK ACCESS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=713" - }, - { - "id": "4.10.1.36", - "name": "BACKUP DATA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=716" - }, - { - "id": "4.10.1.37", - "name": "BACKUP DATA CLOSE SNAPSHOT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=722" - }, - { - "id": "4.10.1.38", - "name": "BACKUP DATA CREATE SNAPSHOT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=724" - }, - { - "id": "4.10.1.39", - "name": "BACKUP DATA DROP SNAPSHOT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=726" - }, - { - "id": "4.10.1.40", - "name": "BACKUP ENCRYPTION ROOT KEYS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=727" - }, - { - "id": "4.10.1.41", - "name": "BACKUP LIST DATA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=730" - }, - { - "id": "4.10.1.42", - "name": "CALL", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=733", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.43", - "name": "COMMENT ON", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=736" - }, - { - "id": "4.10.1.44", - "name": "COMMIT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=738" - }, - { - "id": "4.10.1.45", - "name": "CONNECT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=739" - }, - { - "id": "4.10.1.46", - "name": "CREATE AUDIT POLICY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=740" - }, - { - "id": "4.10.1.47", - "name": "CREATE CERTIFICATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=757" - }, - { - "id": "4.10.1.48", - "name": "CREATE CLIENTSIDE ENCRYPTION COLUMN KEY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=759" - }, - { - "id": "4.10.1.49", - "name": "CREATE CLIENTSIDE ENCRYPTION KEYPAIR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=761" - }, - { - "id": "4.10.1.50", - "name": "CREATE CREDENTIAL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=763" - }, - { - "id": "4.10.1.51", - "name": "CREATE DATABASE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=764" - }, - { - "id": "4.10.1.52", - "name": "CREATE FULLTEXT INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=767" - }, - { - "id": "4.10.1.53", - "name": "CREATE FUNCTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=770" - }, - { - "id": "4.10.1.54", - "name": "CREATE FUZZY SEARCH INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=778" - }, - { - "id": "4.10.1.55", - "name": "CREATE GRAPH WORKSPACE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=779" - }, - { - "id": "4.10.1.56", - "name": "CREATE INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=781" - }, - { - "id": "4.10.1.57", - "name": "CREATE JWT PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=786" - }, - { - "id": "4.10.1.58", - "name": "CREATE LIBRARY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=789" - }, - { - "id": "4.10.1.59", - "name": "CREATE LDAP PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=791" - }, - { - "id": "4.10.1.60", - "name": "CREATE PROCEDURE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=796" - }, - { - "id": "4.10.1.61", - "name": "CREATE PROJECTION VIEW", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=813" - }, - { - "id": "4.10.1.62", - "name": "CREATE PSE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=816" - }, - { - "id": "4.10.1.63", - "name": "CREATE PUBLIC KEY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=818" - }, - { - "id": "4.10.1.64", - "name": "CREATE REMOTE SOURCE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=819" - }, - { - "id": "4.10.1.65", - "name": "CREATE ROLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=822" - }, - { - "id": "4.10.1.66", - "name": "CREATE SAML PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=823" - }, - { - "id": "4.10.1.67", - "name": "CREATE SCHEDULER JOB", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=825" - }, - { - "id": "4.10.1.68", - "name": "CREATE SCHEMA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=827" - }, - { - "id": "4.10.1.69", - "name": "CREATE SCHEMA SYNONYM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=828" - }, - { - "id": "4.10.1.70", - "name": "CREATE SEQUENCE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=831" - }, - { - "id": "4.10.1.71", - "name": "CREATE STATISTICS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=835" - }, - { - "id": "4.10.1.72", - "name": "CREATE STRUCTURED PRIVILEGE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=842" - }, - { - "id": "4.10.1.73", - "name": "CREATE SYNONYM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=844" - }, - { - "id": "4.10.1.74", - "name": "CREATE TABLE", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=845", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.75", - "name": "CREATE TRIGGER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=898" - }, - { - "id": "4.10.1.76", - "name": "CREATE TYPE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=913" - }, - { - "id": "4.10.1.77", - "name": "CREATE USER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=915" - }, - { - "id": "4.10.1.78", - "name": "CREATE USERGROUP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=923" - }, - { - "id": "4.10.1.79", - "name": "CREATE VIEW", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=927" - }, - { - "id": "4.10.1.80", - "name": "CREATE VIRTUAL FUNCTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=939" - }, - { - "id": "4.10.1.81", - "name": "CREATE VIRTUAL PROCEDURE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=945" - }, - { - "id": "4.10.1.82", - "name": "CREATE VIRTUAL TABLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=948" - }, - { - "id": "4.10.1.83", - "name": "CREATE WORKLOAD CLASS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=951" - }, - { - "id": "4.10.1.84", - "name": "CREATE WORKLOAD MAPPING", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=956" - }, - { - "id": "4.10.1.85", - "name": "CREATE X509 PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=959" - }, - { - "id": "4.10.1.86", - "name": "DELETE", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=961", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.87", - "name": "DO BEGIN...END", - "status": "outside_scope_sqlscript_body", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=965" - }, - { - "id": "4.10.1.88", - "name": "DROP AUDIT POLICY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=969" - }, - { - "id": "4.10.1.89", - "name": "DROP CERTIFICATE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=970" - }, - { - "id": "4.10.1.90", - "name": "DROP CLIENTSIDE ENCRYPTION COLUMN KEY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=971" - }, - { - "id": "4.10.1.91", - "name": "DROP CLIENTSIDE ENCRYPTION KEYPAIR", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=972" - }, - { - "id": "4.10.1.92", - "name": "DROP COLLECTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=974" - }, - { - "id": "4.10.1.93", - "name": "DROP CREDENTIAL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=975" - }, - { - "id": "4.10.1.94", - "name": "DROP DATABASE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=977" - }, - { - "id": "4.10.1.95", - "name": "DROP FULLTEXT INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=978" - }, - { - "id": "4.10.1.96", - "name": "DROP FUNCTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=979" - }, - { - "id": "4.10.1.97", - "name": "DROP GRAPH WORKSPACE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=980" - }, - { - "id": "4.10.1.98", - "name": "DROP INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=981" - }, - { - "id": "4.10.1.99", - "name": "DROP JWT PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=982" - }, - { - "id": "4.10.1.100", - "name": "DROP LIBRARY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=983" - }, - { - "id": "4.10.1.101", - "name": "DROP LDAP PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=984" - }, - { - "id": "4.10.1.102", - "name": "DROP PROCEDURE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=985" - }, - { - "id": "4.10.1.103", - "name": "DROP PSE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=987" - }, - { - "id": "4.10.1.104", - "name": "DROP PUBLIC KEY", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=988" - }, - { - "id": "4.10.1.105", - "name": "DROP REMOTE SOURCE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=989" - }, - { - "id": "4.10.1.106", - "name": "DROP ROLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=990" - }, - { - "id": "4.10.1.107", - "name": "DROP SAML PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=991" - }, - { - "id": "4.10.1.108", - "name": "DROP SCHEDULER JOB", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=992" - }, - { - "id": "4.10.1.109", - "name": "DROP SCHEMA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=993" - }, - { - "id": "4.10.1.110", - "name": "DROP SCHEMA SYNONYM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=994" - }, - { - "id": "4.10.1.111", - "name": "DROP SEQUENCE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=996" - }, - { - "id": "4.10.1.112", - "name": "DROP STATISTICS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=997" - }, - { - "id": "4.10.1.113", - "name": "DROP STRUCTURED PRIVILEGE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1000" - }, - { - "id": "4.10.1.114", - "name": "DROP SYNONYM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1001" - }, - { - "id": "4.10.1.115", - "name": "DROP TABLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1003" - }, - { - "id": "4.10.1.116", - "name": "DROP TRIGGER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1004" - }, - { - "id": "4.10.1.117", - "name": "DROP TYPE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1006" - }, - { - "id": "4.10.1.118", - "name": "DROP USER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1007" - }, - { - "id": "4.10.1.119", - "name": "DROP USERGROUP", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1009" - }, - { - "id": "4.10.1.120", - "name": "DROP VIEW", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1010" - }, - { - "id": "4.10.1.121", - "name": "DROP WORKLOAD CLASS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1012" - }, - { - "id": "4.10.1.122", - "name": "DROP WORKLOAD MAPPING", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1013" - }, - { - "id": "4.10.1.123", - "name": "DROP X509 PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1014" - }, - { - "id": "4.10.1.124", - "name": "EXPLAIN PLAN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1015" - }, - { - "id": "4.10.1.125", - "name": "EXPORT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1020" - }, - { - "id": "4.10.1.126", - "name": "EXPORT INTO", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1031" - }, - { - "id": "4.10.1.127", - "name": "GRANT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1034" - }, - { - "id": "4.10.1.128", - "name": "IMPORT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1053" - }, - { - "id": "4.10.1.129", - "name": "IMPORT FROM", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1063" - }, - { - "id": "4.10.1.130", - "name": "IMPORT SCAN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1072" - }, - { - "id": "4.10.1.131", - "name": "INSERT", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1075", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.132", - "name": "LOAD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1080" - }, - { - "id": "4.10.1.133", - "name": "LOCK TABLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1082" - }, - { - "id": "4.10.1.134", - "name": "MERGE DELTA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1084" - }, - { - "id": "4.10.1.135", - "name": "MERGE INTO", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1086" - }, - { - "id": "4.10.1.136", - "name": "RECOVER DATA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1090" - }, - { - "id": "4.10.1.137", - "name": "RECOVER DATABASE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1096" - }, - { - "id": "4.10.1.138", - "name": "RECOVER ENCRYPTION ROOT KEYS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1105" - }, - { - "id": "4.10.1.139", - "name": "REFRESH STATISTICS", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1109" - }, - { - "id": "4.10.1.140", - "name": "REFRESH VIEW", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1113" - }, - { - "id": "4.10.1.141", - "name": "RELEASE SAVEPOINT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1114" - }, - { - "id": "4.10.1.142", - "name": "RENAME COLUMN", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1115" - }, - { - "id": "4.10.1.143", - "name": "RENAME DATABASE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1116" - }, - { - "id": "4.10.1.144", - "name": "RENAME INDEX", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1117" - }, - { - "id": "4.10.1.145", - "name": "RENAME SCHEMA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1118" - }, - { - "id": "4.10.1.146", - "name": "RENAME TABLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1120" - }, - { - "id": "4.10.1.147", - "name": "REPLACE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1123" - }, - { - "id": "4.10.1.148", - "name": "REVOKE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1124" - }, - { - "id": "4.10.1.149", - "name": "ROLLBACK", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1127" - }, - { - "id": "4.10.1.150", - "name": "ROLLBACK TO SAVEPOINT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1128" - }, - { - "id": "4.10.1.151", - "name": "SAVEPOINT", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1130" - }, - { - "id": "4.10.1.152", - "name": "SELECT", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1131", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.153", - "name": "SET HISTORY SESSION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1191" - }, - { - "id": "4.10.1.154", - "name": "SET PSE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1193" - }, - { - "id": "4.10.1.155", - "name": "SET SCHEMA", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1196" - }, - { - "id": "4.10.1.156", - "name": "SET [SESSION]", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1197" - }, - { - "id": "4.10.1.157", - "name": "SET SYSTEM LICENSE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1198" - }, - { - "id": "4.10.1.158", - "name": "SET TRANSACTION", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1199" - }, - { - "id": "4.10.1.159", - "name": "SET TRANSACTION AUTOCOMMIT DDL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1202" - }, - { - "id": "4.10.1.160", - "name": "TRUNCATE TABLE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1204" - }, - { - "id": "4.10.1.161", - "name": "UNLOAD", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1206" - }, - { - "id": "4.10.1.162", - "name": "UNSET PSE", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1208" - }, - { - "id": "4.10.1.163", - "name": "UNSET [SESSION]", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1209" - }, - { - "id": "4.10.1.164", - "name": "UNSET SYSTEM LICENSE ALL", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1210" - }, - { - "id": "4.10.1.165", - "name": "UPDATE", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1211", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.166", - "name": "UPSERT", - "status": "partially_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1218", - "tests": [ - "crates/polyglot-sql/tests/dialect_matrix.rs::hana_regressions", - "crates/polyglot-sql/tests/custom_fixtures/hana/" - ] - }, - { - "id": "4.10.1.167", - "name": "VALIDATE LDAP PROVIDER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1221" - }, - { - "id": "4.10.1.168", - "name": "VALIDATE USER", - "status": "not_exhaustively_implemented", - "source": "https://help.sap.com/doc/9b40bf74f8644b898fb07dabdd2a36ad/2.0.08/en-US/SAP_HANA_SQL_Reference_Guide_en.pdf#page=1224" - } -] From 377478bafae413d2b724f6a45a3cb3289476b1c1 Mon Sep 17 00:00:00 2001 From: tobilg Date: Wed, 23 Sep 2026 13:16:02 +0200 Subject: [PATCH 5/8] Fixes --- Makefile | 1 + README.md | 2 +- crates/polyglot-sql-ast-derive/src/lib.rs | 141 +++++++------ .../benches/allocation_hotspots.rs | 25 +++ .../benches/performance_hotspots.rs | 20 +- crates/polyglot-sql/src/ast_children.rs | 25 +++ crates/polyglot-sql/src/dialects/mod.rs | 27 ++- .../src/dialects/normalization/hana.rs | 151 ++++++++++++++ .../src/dialects/normalization/mod.rs | 6 + crates/polyglot-sql/src/expressions.rs | 2 +- crates/polyglot-sql/src/generator.rs | 109 ++++++++-- crates/polyglot-sql/src/parser.rs | 24 ++- crates/polyglot-sql/src/traversal.rs | 4 +- crates/polyglot-sql/tests/dialect_matrix.rs | 187 +++++++++++++++++- packages/sdk/plugins/wasmCjsPlugin.test.ts | 57 ++++++ 15 files changed, 692 insertions(+), 89 deletions(-) create mode 100644 crates/polyglot-sql/src/dialects/normalization/hana.rs create mode 100644 packages/sdk/plugins/wasmCjsPlugin.test.ts diff --git a/Makefile b/Makefile index 4528482d..0bd5cde8 100644 --- a/Makefile +++ b/Makefile @@ -285,6 +285,7 @@ test-rust-verify-core: @echo "=== Lib unit tests ===" @cargo test --lib -p polyglot-sql @cargo test -p polyglot-sql --test deep_nesting_regression + @cargo test -p polyglot-sql --test dialect_matrix @echo "" @echo "=== Generic identity tests ===" @cargo test --test sqlglot_identity test_sqlglot_identity_all -p polyglot-sql -- --nocapture diff --git a/README.md b/README.md index 19309ae8..39aecf23 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Release notes are tracked in [`CHANGELOG.md`](CHANGELOG.md). | MySQL | Oracle | PostgreSQL | Presto | Redshift | | RisingWave | SingleStore | Snowflake | Solr | Spark | | SQLite | StarRocks | Tableau | Teradata | TiDB | -| Trino | TSQL | DataFusion | Generic SQL | SAP HANA | +| Trino | TSQL | DataFusion | Generic SQL | [SAP HANA](docs/hana.md) | ## Quick Start diff --git a/crates/polyglot-sql-ast-derive/src/lib.rs b/crates/polyglot-sql-ast-derive/src/lib.rs index 25eea077..57784687 100644 --- a/crates/polyglot-sql-ast-derive/src/lib.rs +++ b/crates/polyglot-sql-ast-derive/src/lib.rs @@ -19,32 +19,9 @@ pub fn derive_ast_node(input: TokenStream) -> TokenStream { fn expand_ast_node(input: &DeriveInput) -> proc_macro2::TokenStream { let name = &input.ident; - let immutable = match &input.data { - Data::Struct(data) => visit_fields(&data.fields, false), - Data::Enum(data) => { - let arms = data.variants.iter().map(|variant| { - let variant_name = &variant.ident; - let (pattern, body) = - visit_variant_fields(name, variant_name, &variant.fields, false); - quote!(#pattern => { #body }) - }); - quote!(match self { #(#arms),* }) - } - Data::Union(_) => quote!(), - }; - let mutable = match &input.data { - Data::Struct(data) => visit_fields(&data.fields, true), - Data::Enum(data) => { - let arms = data.variants.iter().map(|variant| { - let variant_name = &variant.ident; - let (pattern, body) = - visit_variant_fields(name, variant_name, &variant.fields, true); - quote!(#pattern => { #body }) - }); - quote!(match self { #(#arms),* }) - } - Data::Union(_) => quote!(), - }; + let immutable = node_visitor(input, false, true); + let untracked = node_visitor(input, false, false); + let mutable = node_visitor(input, true, false); let serialized_variant_names = if name == "Expression" { if let Data::Enum(data) = &input.data { let names = data.variants.iter().map(|variant| { @@ -81,6 +58,12 @@ fn expand_ast_node(input: &DeriveInput) -> proc_macro2::TokenStream { #immutable } + fn visit_expressions_untracked<'ast, F>(&'ast self, visitor: &mut F) + where F: FnMut(&'ast crate::expressions::Expression), + { + #untracked + } + fn visit_expressions_mut( &mut self, visitor: &mut F, @@ -96,6 +79,22 @@ fn expand_ast_node(input: &DeriveInput) -> proc_macro2::TokenStream { } } +fn node_visitor(input: &DeriveInput, mutable: bool, paths: bool) -> proc_macro2::TokenStream { + let name = &input.ident; + match &input.data { + Data::Struct(data) => visit_fields(&data.fields, mutable, paths), + Data::Enum(data) => { + let arms = data.variants.iter().map(|variant| { + let (pattern, body) = + visit_variant_fields(name, &variant.ident, &variant.fields, mutable, paths); + quote!(#pattern => { #body }) + }); + quote!(match self { #(#arms),* }) + } + Data::Union(_) => quote!(), + } +} + /// Match serde's `rename_all = "snake_case"` behavior for Rust enum variants. fn serde_snake_case(name: &str) -> String { let mut snake_case = String::with_capacity(name.len()); @@ -108,7 +107,7 @@ fn serde_snake_case(name: &str) -> String { snake_case } -fn visit_fields(fields: &Fields, mutable: bool) -> proc_macro2::TokenStream { +fn visit_fields(fields: &Fields, mutable: bool, paths: bool) -> proc_macro2::TokenStream { match fields { Fields::Named(fields) => { let visits = fields.named.iter().filter_map(|field| { @@ -122,11 +121,15 @@ fn visit_fields(fields: &Fields, mutable: bool) -> proc_macro2::TokenStream { Some(if mutable { mutable_visit(&field.ty, access) } else { - let visit = immutable_visit(&field.ty, immutable_access); - quote! { - path.push(crate::ast_children::ChildPathSegment::Field(#field_name)); - #visit - path.pop(); + let visit = immutable_visit(&field.ty, immutable_access, paths); + if paths { + quote! { + path.push(crate::ast_children::ChildPathSegment::Field(#field_name)); + #visit + path.pop(); + } + } else { + visit } }) }); @@ -147,11 +150,15 @@ fn visit_fields(fields: &Fields, mutable: bool) -> proc_macro2::TokenStream { Some(if mutable { mutable_visit(&field.ty, access) } else { - let visit = immutable_visit(&field.ty, immutable_access); - quote! { - path.push(crate::ast_children::ChildPathSegment::Index(#index)); - #visit - path.pop(); + let visit = immutable_visit(&field.ty, immutable_access, paths); + if paths { + quote! { + path.push(crate::ast_children::ChildPathSegment::Index(#index)); + #visit + path.pop(); + } + } else { + visit } }) }); @@ -166,6 +173,7 @@ fn visit_variant_fields( variant_name: &syn::Ident, fields: &Fields, mutable: bool, + paths: bool, ) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) { match fields { Fields::Named(fields) => { @@ -190,11 +198,15 @@ fn visit_variant_fields( Some(if mutable { mutable_visit(&field.ty, quote!(#ident)) } else { - let visit = immutable_visit(&field.ty, quote!(#ident)); - quote! { - path.push(crate::ast_children::ChildPathSegment::Field(#field_name)); - #visit - path.pop(); + let visit = immutable_visit(&field.ty, quote!(#ident), paths); + if paths { + quote! { + path.push(crate::ast_children::ChildPathSegment::Field(#field_name)); + #visit + path.pop(); + } + } else { + visit } }) }); @@ -220,8 +232,8 @@ fn visit_variant_fields( Some(if mutable { mutable_visit(&field.ty, quote!(#binding)) } else { - let visit = immutable_visit(&field.ty, quote!(#binding)); - if single_expression_payload { + let visit = immutable_visit(&field.ty, quote!(#binding), paths); + if single_expression_payload || !paths { visit } else { quote! { @@ -241,19 +253,30 @@ fn visit_variant_fields( } } -fn immutable_visit(ty: &Type, access: proc_macro2::TokenStream) -> proc_macro2::TokenStream { +fn immutable_visit( + ty: &Type, + access: proc_macro2::TokenStream, + paths: bool, +) -> proc_macro2::TokenStream { if is_expression(ty) { - return quote!(visitor(path, #access);); + return if paths { + quote!(visitor(path, #access);) + } else { + quote!(visitor(#access);) + }; } if let Some(inner) = container_inner(ty, "Option") { - let visit = immutable_visit(inner, quote!(value)); + let visit = immutable_visit(inner, quote!(value), paths); return quote!(if let Some(value) = (#access).as_ref() { #visit }); } if let Some(inner) = container_inner(ty, "Box") { - return immutable_visit(inner, quote!((#access).as_ref())); + return immutable_visit(inner, quote!((#access).as_ref()), paths); } if let Some(inner) = container_inner(ty, "Vec") { - let visit = immutable_visit(inner, quote!(value)); + let visit = immutable_visit(inner, quote!(value), paths); + if !paths { + return quote!(for value in (#access).iter() { #visit }); + } return quote! { for (index, value) in (#access).iter().enumerate() { path.push(crate::ast_children::ChildPathSegment::Index(index)); @@ -265,11 +288,15 @@ fn immutable_visit(ty: &Type, access: proc_macro2::TokenStream) -> proc_macro2:: if let Type::Tuple(tuple) = ty { let visits = tuple.elems.iter().enumerate().map(|(index, element)| { let tuple_index = syn::Index::from(index); - let visit = immutable_visit(element, quote!(&(#access).#tuple_index)); - quote! { - path.push(crate::ast_children::ChildPathSegment::Index(#index)); - #visit - path.pop(); + let visit = immutable_visit(element, quote!(&(#access).#tuple_index), paths); + if paths { + quote! { + path.push(crate::ast_children::ChildPathSegment::Index(#index)); + #visit + path.pop(); + } + } else { + visit } }); return quote!(#(#visits)*); @@ -277,7 +304,11 @@ fn immutable_visit(ty: &Type, access: proc_macro2::TokenStream) -> proc_macro2:: if is_scalar(ty) { return quote!(); } - quote!(crate::ast_children::AstNode::visit_expressions(#access, path, visitor);) + if paths { + quote!(crate::ast_children::AstNode::visit_expressions(#access, path, visitor);) + } else { + quote!(crate::ast_children::AstNode::visit_expressions_untracked(#access, visitor);) + } } fn mutable_visit(ty: &Type, access: proc_macro2::TokenStream) -> proc_macro2::TokenStream { diff --git a/crates/polyglot-sql/benches/allocation_hotspots.rs b/crates/polyglot-sql/benches/allocation_hotspots.rs index 14d7a1f9..9e3febcb 100644 --- a/crates/polyglot-sql/benches/allocation_hotspots.rs +++ b/crates/polyglot-sql/benches/allocation_hotspots.rs @@ -83,6 +83,13 @@ fn main() { let functions = nested_functions(); let strings = large_strings(); let numbers = many_numbers(); + let generic_functions = format!( + "SELECT {} FROM t", + (0..1_000) + .map(|i| format!("my_udf(c{i}) AS v{i}")) + .collect::>() + .join(", ") + ); let inputs = [ ("short_ascii", SHORT_ASCII), ("unicode", UNICODE), @@ -92,6 +99,7 @@ fn main() { ("nested_functions", functions.as_str()), ("large_strings", strings.as_str()), ("many_numbers", numbers.as_str()), + ("generic_functions", generic_functions.as_str()), ]; black_box(dialect.tokenize(SHORT_ASCII).unwrap()); @@ -119,4 +127,21 @@ fn main() { 0, measure(|| Dialect::get(DialectType::PostgreSQL)), ); + + for depth in [10, 20, 40, 80] { + let mut sql = "SELECT 1".to_owned(); + for _ in 0..depth { + sql = format!("SELECT ({sql})"); + } + for kind in [DialectType::PostgreSQL, DialectType::HANA] { + let dialect = Dialect::get(kind); + black_box(dialect.parse(&sql).unwrap()); + print_stats( + &format!("nested_{depth}_{kind}"), + "parse", + sql.len(), + measure(|| dialect.parse(&sql).unwrap()), + ); + } + } } diff --git a/crates/polyglot-sql/benches/performance_hotspots.rs b/crates/polyglot-sql/benches/performance_hotspots.rs index 48610284..edfba50f 100644 --- a/crates/polyglot-sql/benches/performance_hotspots.rs +++ b/crates/polyglot-sql/benches/performance_hotspots.rs @@ -269,11 +269,29 @@ fn bench_validation_and_analysis(c: &mut Criterion) { let _ = c; } +fn bench_hana_nested_queries(c: &mut Criterion) { + let mut group = c.benchmark_group("nested_query_dialects"); + for depth in [10, 20, 40, 80] { + let mut sql = "SELECT 1".to_owned(); + for _ in 0..depth { + sql = format!("SELECT ({sql})"); + } + for kind in [DialectType::PostgreSQL, DialectType::HANA] { + let dialect = Dialect::get(kind); + group.bench_with_input(BenchmarkId::new(kind.to_string(), depth), &sql, |b, sql| { + b.iter(|| dialect.parse(black_box(sql)).unwrap()); + }); + } + } + group.finish(); +} + criterion_group!( benches, bench_dialect_construction, bench_fresh_vs_reused_dialect, bench_tokenize_and_parse, - bench_validation_and_analysis + bench_validation_and_analysis, + bench_hana_nested_queries ); criterion_main!(benches); diff --git a/crates/polyglot-sql/src/ast_children.rs b/crates/polyglot-sql/src/ast_children.rs index ce438197..68249988 100644 --- a/crates/polyglot-sql/src/ast_children.rs +++ b/crates/polyglot-sql/src/ast_children.rs @@ -24,6 +24,11 @@ pub(crate) enum ChildPathSegment { } pub(crate) trait AstNode { + /// Visit children without constructing paths when the caller only needs nodes. + fn visit_expressions_untracked<'ast, F>(&'ast self, visitor: &mut F) + where + F: FnMut(&'ast Expression); + fn visit_expressions<'ast, F>(&'ast self, path: &mut Vec, visitor: &mut F) where F: FnMut(&[ChildPathSegment], &'ast Expression); @@ -48,6 +53,13 @@ pub(crate) fn for_each_child_mut( expression.visit_expressions_mut(&mut visitor); } +pub(crate) fn for_each_child_untracked<'ast>( + expression: &'ast Expression, + mut visitor: impl FnMut(&'ast Expression), +) { + expression.visit_expressions_untracked(&mut visitor); +} + #[cfg(test)] mod tests { use super::*; @@ -64,6 +76,19 @@ mod tests { let mut immutable_paths = Vec::new(); for_each_child(&expression, |path, _| immutable_paths.push(path.to_vec())); + let mut tracked = Vec::new(); + for_each_child(&expression, |_, child| { + tracked.push(child as *const Expression) + }); + let mut untracked = Vec::new(); + for_each_child_untracked(&expression, |child| { + untracked.push(child as *const Expression) + }); + assert_eq!( + tracked, untracked, + "path-free traversal preserves child identity and order" + ); + let mut mutable_count = 0; for_each_child_mut(&mut expression, |_| mutable_count += 1); diff --git a/crates/polyglot-sql/src/dialects/mod.rs b/crates/polyglot-sql/src/dialects/mod.rs index a08f3568..e75471b1 100644 --- a/crates/polyglot-sql/src/dialects/mod.rs +++ b/crates/polyglot-sql/src/dialects/mod.rs @@ -3523,17 +3523,26 @@ impl Dialect { expressions .into_iter() .map(|expr| { - // Validate source-bound semantics before normalization can erase them. - // Generating each outermost protected subtree checks its descendants too. - let mut pending = vec![&expr]; - while let Some(node) = pending.pop() { - if let Some(source) = node.source_dialect() { - if source != target { - target_dialect.generate_with_transpile_options(node, source, opts)?; - continue; + // This API parses SQL itself: only the HANA parser currently + // produces source-bound nodes. Standalone AST generation checks + // those nodes independently in the generator. Other SQL sources + // need not pay for a speculative full-tree validation pass. + if self.dialect_type == DialectType::HANA { + // Validate source-bound semantics before normalization can erase them. + // Generating each outermost protected subtree checks its descendants too. + let mut pending = vec![&expr]; + while let Some(node) = pending.pop() { + if let Some(source) = node.source_dialect() { + if source != target { + target_dialect + .generate_with_transpile_options(node, source, opts)?; + continue; + } } + crate::ast_children::for_each_child_untracked(node, |child| { + pending.push(child) + }); } - crate::ast_children::for_each_child(node, |_, child| pending.push(child)); } // DuckDB source: normalize VARCHAR/CHAR to TEXT (DuckDB doesn't support diff --git a/crates/polyglot-sql/src/dialects/normalization/hana.rs b/crates/polyglot-sql/src/dialects/normalization/hana.rs new file mode 100644 index 00000000..10de7048 --- /dev/null +++ b/crates/polyglot-sql/src/dialects/normalization/hana.rs @@ -0,0 +1,151 @@ +//! Lower HANA system relations while respecting lexical CTE scope. + +use crate::dialects::DialectType; +use crate::error::{Error, Result}; +use crate::expressions::*; + +fn is_name(identifier: &Identifier, name: &str) -> bool { + if identifier.quoted { + identifier.name == name + } else { + identifier.name.eq_ignore_ascii_case(name) + } +} + +fn with_clause(expression: &mut Expression) -> Option<&mut Option> { + match expression { + Expression::Select(s) => Some(&mut s.with), + Expression::Union(s) => Some(&mut s.with), + Expression::Intersect(s) => Some(&mut s.with), + Expression::Except(s) => Some(&mut s.with), + Expression::Insert(s) => Some(&mut s.with), + Expression::Update(s) => Some(&mut s.with), + Expression::Delete(s) => Some(&mut s.with), + Expression::CreateTable(s) => Some(&mut s.with_cte), + Expression::Pivot(s) => Some(&mut s.with), + _ => None, + } +} + +pub(super) fn lower_dummy(mut expression: Expression, target: DialectType) -> Result { + visit(&mut expression, false, target)?; + Ok(expression) +} + +fn visit(expression: &mut Expression, shadowed: bool, target: DialectType) -> Result<()> { + #[cfg(feature = "stacker")] + { + stacker::maybe_grow(1024 * 1024, 8 * 1024 * 1024, || { + visit_inner(expression, shadowed, target) + }) + } + #[cfg(not(feature = "stacker"))] + { + visit_inner(expression, shadowed, target) + } +} + +fn visit_inner(expression: &mut Expression, mut shadowed: bool, target: DialectType) -> Result<()> { + if let Expression::Dot(dot) = expression { + if matches!(&dot.this, Expression::Column(column) + if is_name(&column.name, "DUMMY") && column.table.as_ref().is_some_and(|name| is_name(name, "SYS"))) + { + // Replacing a schema-qualified relation with an alias can change + // binding in correlated queries. Require an explicit source alias. + return Err(Error::unsupported( + "Schema-qualified HANA DUMMY columns require an explicit table alias", + target.to_string(), + )); + } + } + // A non-recursive CTE sees preceding CTEs, but not its own alias. Temporarily + // detach WITH so the generic child walk does not visit its bodies twice. + let mut with = with_clause(expression).and_then(Option::take); + if let Some(with) = &mut with { + if with.recursive && with.ctes.iter().any(|cte| is_name(&cte.alias, "DUMMY")) { + shadowed = true; + } + for cte in &mut with.ctes { + visit(&mut cte.this, shadowed, target)?; + shadowed |= is_name(&cte.alias, "DUMMY"); + } + if let Some(search) = &mut with.search { + visit(search, shadowed, target)?; + } + } + + if let Expression::Table(table) = expression { + let system_schema = table.schema.as_ref().is_some_and(|s| is_name(s, "SYS")); + if is_name(&table.name, "DUMMY") + && table.catalog.is_none() + && (system_schema || table.schema.is_none() && !shadowed) + { + if !matches!( + target, + DialectType::DuckDB + | DialectType::PostgreSQL + | DialectType::Trino + | DialectType::Presto + | DialectType::Athena + | DialectType::Dune + | DialectType::CockroachDB + | DialectType::Materialize + | DialectType::RisingWave + ) || table.when.is_some() + || table.only + || table.final_ + || table.table_sample.is_some() + || !table.hints.is_empty() + || table.system_time.is_some() + || !table.partitions.is_empty() + || table.identifier_func.is_some() + || table.changes.is_some() + || table.version.is_some() + { + return Err(Error::unsupported( + "HANA DUMMY relation with no verified target mapping", + target.to_string(), + )); + } + // SAP's system table is one row, one column named DUMMY, value 'X'. + // Keeping that row as a derived table preserves *, aliases, joins, + // predicates and aggregate cardinality, unlike dropping FROM blindly. + let mut row = Select::new(); + row.expressions.push(Expression::Alias(Box::new(Alias::new( + Expression::string("X"), + Identifier::new("DUMMY"), + )))); + row.leading_comments = std::mem::take(&mut table.leading_comments); + row.leading_comments.append(&mut table.trailing_comments); + let subquery = Subquery { + this: Expression::Select(Box::new(row)), + alias: Some(table.alias.clone().unwrap_or_else(|| table.name.clone())), + alias_explicit_as: true, + column_aliases: table.column_aliases.clone(), + alias_keyword: None, + order_by: None, + limit: None, + offset: None, + distribute_by: None, + sort_by: None, + cluster_by: None, + lateral: false, + modifiers_inside: true, + trailing_comments: Vec::new(), + inferred_type: None, + }; + *expression = Expression::Subquery(Box::new(subquery)); + } + } + + let mut result = Ok(()); + crate::ast_children::for_each_child_mut(expression, |child| { + if result.is_ok() { + result = visit(child, shadowed, target); + } + }); + if let Some(slot) = with_clause(expression) { + *slot = with; + } + result +} diff --git a/crates/polyglot-sql/src/dialects/normalization/mod.rs b/crates/polyglot-sql/src/dialects/normalization/mod.rs index 246710d3..756b4249 100644 --- a/crates/polyglot-sql/src/dialects/normalization/mod.rs +++ b/crates/polyglot-sql/src/dialects/normalization/mod.rs @@ -8,6 +8,7 @@ use super::*; mod aggregates; mod collections; +mod hana; mod json; mod operators; mod postgres_interval; @@ -83,6 +84,11 @@ pub(super) fn normalize( Scalar(scalar::Action), } + let expr = if source == DialectType::HANA && target != DialectType::HANA { + hana::lower_dummy(expr, target)? + } else { + expr + }; let expr = statements::normalize_root(expr, &context); transform_recursive(expr, &|e| { diff --git a/crates/polyglot-sql/src/expressions.rs b/crates/polyglot-sql/src/expressions.rs index d45ddfec..b3d00a9d 100644 --- a/crates/polyglot-sql/src/expressions.rs +++ b/crates/polyglot-sql/src/expressions.rs @@ -5145,7 +5145,7 @@ pub struct Function { pub qualified_name: Vec, /// Optional DEFAULT/NULL/ERROR behavior after the arguments. #[serde(default, skip_serializing_if = "Option::is_none")] - pub on_error: Option, + pub on_error: Option>, /// Dialect whose call semantics must be retained through independent generation. #[serde(default, skip_serializing_if = "Option::is_none")] #[ast(skip)] diff --git a/crates/polyglot-sql/src/generator.rs b/crates/polyglot-sql/src/generator.rs index c68562f3..c9ae8ff8 100644 --- a/crates/polyglot-sql/src/generator.rs +++ b/crates/polyglot-sql/src/generator.rs @@ -2547,6 +2547,16 @@ impl Generator { } fn generate_expression_inner(&mut self, expr: &Expression) -> Result<()> { + if self.config.dialect == Some(DialectType::HANA) + && matches!( + expr, + Expression::StringAgg(_) | Expression::ListAgg(_) | Expression::GroupConcat(_) + ) + { + return Err(self.hana_unsupported( + "STRING_AGG/LISTAGG/GROUP_CONCAT to HANA requires a verified conversion of NULL input semantics", + )); + } if self.config.dialect == Some(DialectType::HANA) && matches!( expr, @@ -18240,8 +18250,30 @@ impl Generator { } fn generate_cast(&mut self, cast: &Cast) -> Result<()> { + if self.config.dialect == Some(DialectType::HANA) + && matches!( + cast.to, + DataType::SmallInt { .. } + | DataType::Int { .. } + | DataType::BigInt { .. } + | DataType::TinyInt { .. } + ) + && (Self::hana_integer(&cast.this).is_none() + || matches!(cast.to, DataType::TinyInt { .. }) + && !Self::hana_integer(&cast.this).is_some_and(|n| (0..=127).contains(&n))) + { + return Err(self.hana_unsupported( + "Integer CAST to HANA requires a verified source conversion; numeric rounding and character conversion rules differ", + )); + } if self.config.dialect != Some(DialectType::HANA) { if let DataType::Hana { hana_type } = &cast.to { + if matches!( + hana_type.name.as_str(), + "TINYINT" | "SMALLINT" | "INT" | "BIGINT" + ) { + return self.generate_hana_integer_cast(cast, &hana_type.name); + } if hana_type.name == "DECIMAL" { let mut args = vec![cast.this.clone()]; args.extend( @@ -18255,19 +18287,6 @@ impl Generator { } return self.generate_hana_function(&Function::new("TO_DECIMAL", args)); } - if hana_type.name == "TINYINT" - && matches!( - self.config.dialect, - Some(DialectType::Trino | DialectType::Presto | DialectType::PostgreSQL) - ) - { - if Self::hana_integer(&cast.this).is_some_and(|n| (0..=255).contains(&n)) { - self.write("CAST("); - self.generate_expression(&cast.this)?; - self.write(" AS SMALLINT)"); - return Ok(()); - } - } } } @@ -19172,6 +19191,66 @@ impl Generator { } } + fn generate_hana_integer_cast(&mut self, cast: &Cast, name: &str) -> Result<()> { + let target = self.config.dialect.unwrap_or_default(); + let supported = matches!( + target, + DialectType::DuckDB + | DialectType::PostgreSQL + | DialectType::Trino + | DialectType::Presto + | DialectType::Athena + | DialectType::Dune + | DialectType::CockroachDB + | DialectType::Materialize + | DialectType::RisingWave + ); + let integer = Self::hana_integer(&cast.this); + // TINYINT is unsigned in HANA. Wider signed targets are safe only when + // the value is proven to fit; otherwise their overflow behavior differs. + let tinyint_fits = name != "TINYINT" + || target == DialectType::DuckDB + || integer.is_some_and(|n| (0..=255).contains(&n)); + if !supported + || !tinyint_fits + || !Self::hana_exact_numeric(&cast.this) + || cast.format.is_some() + || cast.default.is_some() + { + return Err(self.hana_unsupported(format!( + "HANA {name} CAST requires verified numeric input and matching overflow semantics" + ))); + } + self.write("CAST("); + if integer.is_none() { + self.write( + if matches!( + target, + DialectType::Trino + | DialectType::Presto + | DialectType::Athena + | DialectType::Dune + ) { + "TRUNCATE(" + } else { + "TRUNC(" + }, + ); + } + self.generate_expression(&cast.this)?; + if integer.is_none() { + self.write(")"); + } + self.write(" AS "); + self.write(match name { + "TINYINT" if target == DialectType::DuckDB => "UTINYINT", + "TINYINT" => "SMALLINT", + name => name, + }); + self.write(")"); + Ok(()) + } + fn hana_exact_numeric(expr: &Expression) -> bool { match expr { Expression::Literal(l) => { @@ -19463,6 +19542,10 @@ impl Generator { if self.config.dialect != Some(DialectType::HANA) { let target = self.config.dialect.unwrap_or_default(); match (data_type.name.as_str(), data_type.parameters.as_slice()) { + ("SMALLINT" | "INT" | "BIGINT", []) => { + self.write(&data_type.name); + return Ok(()); + } ("TIMESTAMP", []) if target == DialectType::Trino => { self.write("TIMESTAMP(7)"); return Ok(()); diff --git a/crates/polyglot-sql/src/parser.rs b/crates/polyglot-sql/src/parser.rs index e4a0974f..c0baeebf 100644 --- a/crates/polyglot-sql/src/parser.rs +++ b/crates/polyglot-sql/src/parser.rs @@ -38,6 +38,7 @@ use std::sync::{Arc, LazyLock, OnceLock}; #[derive(Default)] struct ParserRecursion { depth: AtomicUsize, + statements: AtomicUsize, failure: OnceLock<(usize, usize, Span)>, } @@ -1102,9 +1103,18 @@ impl Parser { return Err(self.end_of_input_error()); } let start_pos = self.current; - match self.with_parser_depth(|parser| parser.parse_statement_inner()) { + let hana = self.config.dialect == Some(crate::dialects::DialectType::HANA); + let outer_hana_statement = + hana && self.recursion.statements.fetch_add(1, Ordering::Relaxed) == 0; + let result = self.with_parser_depth(|parser| parser.parse_statement_inner()); + if hana { + self.recursion.statements.fetch_sub(1, Ordering::Relaxed); + } + match result { Ok(expr) => { - if self.config.dialect == Some(crate::dialects::DialectType::HANA) + // Nested statements are checked by their outer statement. Walking + // every completed subtree makes a chain of subqueries quadratic. + if outer_hana_statement && expr .dfs() .any(|node| matches!(node, Expression::Raw(_) | Expression::Command(_))) @@ -10188,7 +10198,7 @@ impl Parser { } let mut function = Function::new(name, arguments); function.source_dialect = self.config.dialect; - function.on_error = on_error; + function.on_error = on_error.map(Box::new); Ok(Expression::Function(Box::new(function))) } @@ -44072,6 +44082,7 @@ impl Parser { let mut name = raw_name.to_ascii_uppercase(); if self.config.dialect == Some(crate::dialects::DialectType::HANA) { name = match name.as_str() { + "INTEGER" => "INT".to_owned(), "DEC" => "DECIMAL".to_owned(), "LONGDATE" => "TIMESTAMP".to_owned(), "DAYDATE" => "DATE".to_owned(), @@ -44116,6 +44127,9 @@ impl Parser { && matches!( name.as_str(), "TINYINT" + | "SMALLINT" + | "INT" + | "BIGINT" | "FLOAT" | "SMALLDECIMAL" | "DECIMAL" @@ -44159,8 +44173,8 @@ impl Parser { ("SHORTTEXT", [] | [1..=5000]) => true, ("REAL_VECTOR" | "HALF_VECTOR" | "ST_POINT" | "ST_GEOMETRY", [] | [_]) => true, ( - "TINYINT" | "SMALLDECIMAL" | "SECONDDATE" | "TIMESTAMP" | "TIME" | "CLOB" - | "NCLOB" | "TEXT" | "BINTEXT", + "TINYINT" | "SMALLINT" | "INT" | "BIGINT" | "SMALLDECIMAL" | "SECONDDATE" + | "TIMESTAMP" | "TIME" | "CLOB" | "NCLOB" | "TEXT" | "BINTEXT", [], ) => true, _ => false, diff --git a/crates/polyglot-sql/src/traversal.rs b/crates/polyglot-sql/src/traversal.rs index acebe63a..ccb6197d 100644 --- a/crates/polyglot-sql/src/traversal.rs +++ b/crates/polyglot-sql/src/traversal.rs @@ -211,7 +211,7 @@ impl<'a> Iterator for DfsIter<'a> { let expr = self.stack.pop()?; let child_start = self.stack.len(); - crate::ast_children::for_each_child(expr, |_, child| self.stack.push(child)); + crate::ast_children::for_each_child_untracked(expr, |child| self.stack.push(child)); self.stack[child_start..].reverse(); Some(expr) @@ -244,7 +244,7 @@ impl<'a> Iterator for BfsIter<'a> { fn next(&mut self) -> Option { let expr = self.queue.pop_front()?; - crate::ast_children::for_each_child(expr, |_, child| self.queue.push_back(child)); + crate::ast_children::for_each_child_untracked(expr, |child| self.queue.push_back(child)); Some(expr) } diff --git a/crates/polyglot-sql/tests/dialect_matrix.rs b/crates/polyglot-sql/tests/dialect_matrix.rs index 0906746e..4c028f4b 100644 --- a/crates/polyglot-sql/tests/dialect_matrix.rs +++ b/crates/polyglot-sql/tests/dialect_matrix.rs @@ -28,7 +28,7 @@ fn transpile_succeeds(sql: &str, from: DialectType, to: DialectType) -> bool { mod strict_unsupported_regressions { use super::*; - fn transpile_with_level( + pub(super) fn transpile_with_level( sql: &str, read: DialectType, write: DialectType, @@ -484,7 +484,6 @@ mod strict_unsupported_regressions { "SELECT count(t.id) FROM t", "SELECT sum(t.amount) FROM t", "SELECT t.* FROM t", - "SELECT count(x) FILTER (WHERE EXISTS (SELECT t.* FROM t)) FROM u", ]; for write in [DialectType::Fabric, DialectType::TSQL] { @@ -520,6 +519,24 @@ mod strict_unsupported_regressions { } } + #[test] + fn strict_tsql_targets_reject_filter_subqueries_lowered_into_aggregate_arguments() { + // FILTER becomes CASE inside COUNT. SQL Server/Fabric do not allow a + // subquery in that argument, even though the FILTER is valid PostgreSQL. + for target in [DialectType::TSQL, DialectType::Fabric] { + let error = transpile_with_level( + "SELECT count(x) FILTER (WHERE EXISTS (SELECT t.* FROM t)) FROM u", + DialectType::PostgreSQL, + target, + UnsupportedLevel::Raise, + ) + .unwrap_err(); + assert!(error + .to_string() + .contains("aggregate arguments containing subqueries")); + } + } + #[test] fn strict_transpile_rejects_postgres_composite_values_for_tsql_targets() { let unsupported = [ @@ -4915,10 +4932,176 @@ mod secondary_dialects { #[cfg(feature = "dialect-hana")] mod hana_regressions { + use super::strict_unsupported_regressions::transpile_with_level; use super::*; use polyglot_sql::expressions::Expression; use polyglot_sql::ExpressionWalk; + #[test] + fn integer_casts_preserve_hana_truncation_and_reject_unverified_domains() { + let sql = "SELECT CAST(10.9 AS INTEGER), CAST(-10.9 AS BIGINT), CAST(10.9 AS TINYINT), CAST(-10.9 AS SMALLINT)"; + assert_eq!(transpile(sql, DialectType::HANA, DialectType::DuckDB), + "SELECT CAST(TRUNC(10.9) AS INT), CAST(TRUNC(-10.9) AS BIGINT), CAST(TRUNC(10.9) AS UTINYINT), CAST(TRUNC(-10.9) AS SMALLINT)"); + for target in [DialectType::PostgreSQL, DialectType::Trino] { + let sql = "SELECT CAST(-10.9 AS BIGINT)"; + let output = transpile(sql, DialectType::HANA, target); + assert!(output.contains(if target == DialectType::Trino { + "TRUNCATE(-10.9)" + } else { + "TRUNC(-10.9)" + })); + } + let hana = Dialect::get(DialectType::HANA); + for sql in [ + "SELECT CAST('10.9' AS INT)", + "SELECT CAST(x AS INT) FROM t", + "SELECT CAST(256 AS TINYINT)", + ] { + let ast = hana.parse(sql).unwrap(); + let json = serde_json::to_string(&ast).unwrap(); + let decoded: Vec = serde_json::from_str(&json).unwrap(); + assert!(hana.generate(&decoded[0]).is_ok(), "native {sql}"); + for target in [DialectType::PostgreSQL, DialectType::Trino] { + assert!( + Dialect::get(target).generate(&decoded[0]).is_err(), + "{sql} -> {target:?}" + ); + for level in [UnsupportedLevel::Ignore, UnsupportedLevel::Raise] { + assert!(transpile_with_level(sql, DialectType::HANA, target, level).is_err()); + } + } + } + for sql in [ + "SELECT CAST(10.9 AS INT)", + "SELECT CAST(-10.9 AS BIGINT)", + "SELECT CAST('10.9' AS INT)", + "SELECT CAST(x AS SMALLINT) FROM t", + ] { + assert!( + transpile_with_level( + sql, + DialectType::PostgreSQL, + DialectType::HANA, + UnsupportedLevel::Raise + ) + .is_err(), + "{sql}" + ); + } + assert_eq!( + transpile( + "SELECT CAST(42 AS INT)", + DialectType::PostgreSQL, + DialectType::HANA + ), + "SELECT CAST(42 AS INT) FROM DUMMY" + ); + for sql in [ + "SELECT CAST(-32768 AS SMALLINT)", + "SELECT CAST(2147483647 AS INTEGER)", + "SELECT CAST(-9223372036854775808 AS BIGINT)", + ] { + assert!( + transpile_with_level( + sql, + DialectType::HANA, + DialectType::DuckDB, + UnsupportedLevel::Raise + ) + .is_ok(), + "{sql}" + ); + } + } + + #[test] + fn incoming_string_aggregation_requires_verified_null_semantics() { + for sql in [ + "SELECT STRING_AGG(x, ',' ORDER BY id) FROM t", + "SELECT STRING_AGG(NULL, ',') FROM t", + "SELECT STRING_AGG(x, ',') FROM t WHERE 1 = 0", + "SELECT STRING_AGG(x, ',') OVER (PARTITION BY grp) FROM t", + "SELECT STRING_AGG(x, ',') FILTER (WHERE keep), COUNT(*) FROM t", + ] { + for source in [DialectType::PostgreSQL, DialectType::DuckDB] { + let error = + transpile_with_level(sql, source, DialectType::HANA, UnsupportedLevel::Raise) + .unwrap_err(); + assert!(error.to_string().contains("STRING_AGG"), "{sql}: {error}"); + } + } + assert!(Dialect::get(DialectType::HANA) + .transpile("SELECT STRING_AGG(x, ',') FROM t", DialectType::HANA) + .is_ok()); + } + + #[test] + fn dummy_relations_preserve_rows_columns_aliases_and_cte_scope() { + assert!(Dialect::get(DialectType::HANA) + .transpile("SELECT SYS.DUMMY.DUMMY FROM SYS.DUMMY", DialectType::DuckDB,) + .unwrap_err() + .to_string() + .contains("explicit table alias")); + for target in [ + DialectType::DuckDB, + DialectType::PostgreSQL, + DialectType::Trino, + ] { + for sql in [ + "SELECT 1 FROM SYS.DUMMY", + "SELECT * FROM DUMMY", + "SELECT d.DUMMY FROM SYS.DUMMY AS d", + "SELECT COUNT(*) FROM DUMMY WHERE 1 = 0", + ] { + let output = transpile(sql, DialectType::HANA, target); + assert!(output.contains("SELECT 'X' AS DUMMY"), "{output}"); + assert!(!output.contains("FROM SYS.DUMMY"), "{output}"); + } + } + for sql in [ + "SELECT * FROM app.DUMMY", + "SELECT * FROM \"dummy\"", + "WITH DUMMY AS (SELECT 7 AS n) SELECT n FROM DUMMY", + ] { + let output = transpile(sql, DialectType::HANA, DialectType::DuckDB); + assert!(!output.contains("SELECT 'X'"), "{output}"); + } + // The alias is not visible in its own non-recursive definition. + for sql in [ + "WITH DUMMY AS (SELECT * FROM SYS.DUMMY) SELECT * FROM DUMMY", + "WITH DUMMY AS (SELECT * FROM DUMMY) SELECT * FROM DUMMY", + "WITH first_cte AS (SELECT * FROM DUMMY), DUMMY AS (SELECT 7 AS n), last_cte AS (SELECT n FROM DUMMY) SELECT * FROM first_cte", + ] { + let output = transpile(sql, DialectType::HANA, DialectType::DuckDB); + assert_eq!(output.matches("SELECT 'X'").count(), 1, "{output}"); + } + // A nested WITH does not shadow a sibling or its enclosing query. + let output = transpile( + "SELECT (WITH DUMMY AS (SELECT 7 AS n) SELECT n FROM DUMMY) FROM DUMMY", + DialectType::HANA, + DialectType::DuckDB, + ); + assert_eq!(output.matches("SELECT 'X'").count(), 1, "{output}"); + } + + #[test] + fn outer_statement_validation_still_rejects_nested_raw_fallbacks() { + let hana = Dialect::get(DialectType::HANA); + for sql in [ + "UNSUPPORTED STATEMENT", + "SELECT (UNSUPPORTED STATEMENT)", + "CREATE TABLE t AS (UNSUPPORTED STATEMENT)", + ] { + assert!(hana.parse(sql).is_err(), "{sql}"); + } + let mut sql = "SELECT 1".to_owned(); + for _ in 0..80 { + sql = format!("SELECT ({sql})"); + } + assert!(hana.parse(&sql).is_ok()); + assert!(hana.parse("SELECT 1; UNSUPPORTED STATEMENT").is_err()); + } + #[test] fn shared_function_nodes_participate_in_generic_analysis() { use polyglot_sql::optimizer::{normalize_identifiers, TypeAnnotator}; diff --git a/packages/sdk/plugins/wasmCjsPlugin.test.ts b/packages/sdk/plugins/wasmCjsPlugin.test.ts new file mode 100644 index 00000000..fbccc4d0 --- /dev/null +++ b/packages/sdk/plugins/wasmCjsPlugin.test.ts @@ -0,0 +1,57 @@ +import { join } from 'node:path'; +import { runInNewContext } from 'node:vm'; +import { describe, expect, it, vi } from 'vitest'; +import { wasmCjsPlugin } from './wasmCjsPlugin'; + +describe('CJS WASM startup', () => { + it.each([ + true, + false, + ])('defers initialization and runs optional startup once (startup=%s)', async (startup) => { + const chunk = { + type: 'chunk', + code: ` +let wasm; +function __wbg_set_wasm(value) { wasm = value; } +const __vite__wasmUrl = new URL("./polyglot_sql.wasm", import.meta.url).href; +const __vite__wasmModule = await __vite__initWasm({}, __vite__wasmUrl); +const __wbindgen_start = __vite__wasmModule.__wbindgen_start; +__wbg_set_wasm(wasm$2); +${startup ? '__wbindgen_start();' : ''} +async function init() { return Promise.resolve(); } +function isInitialized() { return true; } +export { init, isInitialized }; +`, + }; + const hook = wasmCjsPlugin().generateBundle; + if (typeof hook !== 'function') + throw new Error('Expected generateBundle hook'); + Reflect.apply(hook, {}, [{}, { 'index.cjs': chunk }, false]); + + const start = vi.fn(); + const instantiate = vi.fn(async () => ({ + instance: { exports: { __wbindgen_start: start } }, + })); + const readFileSync = vi.fn(() => new Uint8Array()); + const module = { + exports: {} as { init(): Promise; isInitialized(): boolean }, + }; + runInNewContext(chunk.code, { + module, + exports: module.exports, + __dirname: '/virtual', + require: (name: string) => + name === 'path' ? { join } : { readFileSync }, + WebAssembly: { instantiate }, + }); + + expect(module.exports.isInitialized()).toBe(false); + expect(readFileSync).not.toHaveBeenCalled(); + expect(start).not.toHaveBeenCalled(); + await Promise.all([module.exports.init(), module.exports.init()]); + await module.exports.init(); + expect(module.exports.isInitialized()).toBe(true); + expect(instantiate).toHaveBeenCalledTimes(1); + expect(start).toHaveBeenCalledTimes(startup ? 1 : 0); + }); +}); From 817f60de8c5b93df5a90f5832c7b646fbee938fe Mon Sep 17 00:00:00 2001 From: tobilg Date: Wed, 23 Sep 2026 08:56:33 +0200 Subject: [PATCH 6/8] Fixes --- .../benches/allocation_hotspots.rs | 77 +- crates/polyglot-sql/benches/common/mod.rs | 93 ++ .../benches/performance_hotspots.rs | 81 +- crates/polyglot-sql/src/dialects/mod.rs | 194 ++++- crates/polyglot-sql/src/generator.rs | 820 ++++++++++++------ crates/polyglot-sql/tests/dialect_matrix.rs | 1 + 6 files changed, 869 insertions(+), 397 deletions(-) create mode 100644 crates/polyglot-sql/benches/common/mod.rs diff --git a/crates/polyglot-sql/benches/allocation_hotspots.rs b/crates/polyglot-sql/benches/allocation_hotspots.rs index 9e3febcb..d88b0b9f 100644 --- a/crates/polyglot-sql/benches/allocation_hotspots.rs +++ b/crates/polyglot-sql/benches/allocation_hotspots.rs @@ -3,62 +3,15 @@ use stats_alloc::{Region, Stats, StatsAlloc, INSTRUMENTED_SYSTEM}; use std::alloc::System; use std::hint::black_box; -#[global_allocator] -static GLOBAL: &StatsAlloc = &INSTRUMENTED_SYSTEM; - -const SHORT_ASCII: &str = - "SELECT a, b, SUM(c) AS total FROM events WHERE created_at >= '2025-01-01' GROUP BY a, b"; -const UNICODE: &str = - "SELECT \"Kundennummer\", 'Gr\u{00fc}\u{00df}e aus Z\u{00fc}rich' AS \"Mitteilung\" FROM \"Bestellungen\" WHERE \"Stadt\" = 'M\u{00fc}nchen'"; -const COMMENT_AND_STRING_HEAVY: &str = r#" --- leading comment -SELECT 'alpha''beta' AS value, "quoted name", E'line\nvalue' -FROM events /* source comment */ -WHERE payload = '{"key":"value"}' -- trailing comment -"#; - -fn large_token_list() -> String { - let values = (0..20_000) - .map(|value| value.to_string()) - .collect::>() - .join(", "); - format!("SELECT * FROM events WHERE event_id IN ({values})") -} - -fn many_columns() -> String { - format!( - "SELECT {} FROM t", - (0..1_000) - .map(|index| format!("c{index}")) - .collect::>() - .join(", ") - ) -} +mod common; -fn nested_functions() -> String { - format!( - "SELECT {}x{} FROM t", - "COALESCE(".repeat(20), - ", NULL)".repeat(20) - ) -} +use common::{ + large_strings, large_token_list, many_columns, many_numbers, nested_functions, + COMMENT_AND_STRING_HEAVY, SHORT_ASCII, UNICODE, +}; -fn large_strings() -> String { - format!( - "SELECT {} FROM t", - vec![format!("'{}'", "x".repeat(100)); 500].join(", ") - ) -} - -fn many_numbers() -> String { - format!( - "SELECT {} FROM t", - (0..10_000) - .map(|value| value.to_string()) - .collect::>() - .join(", ") - ) -} +#[global_allocator] +static GLOBAL: &StatsAlloc = &INSTRUMENTED_SYSTEM; fn measure(operation: impl FnOnce() -> T) -> Stats { let region = Region::new(GLOBAL); @@ -144,4 +97,20 @@ fn main() { ); } } + + #[cfg(feature = "transpile")] + { + let options = polyglot_sql::TranspileOptions::strict(); + for (name, sql) in common::transpilation_queries() { + let run = + || polyglot_sql::transpile_with_by_name(&sql, "hana", "duckdb", &options).unwrap(); + black_box(run()); + print_stats( + &format!("hana_{name}"), + "transpile", + sql.len(), + measure(run), + ); + } + } } diff --git a/crates/polyglot-sql/benches/common/mod.rs b/crates/polyglot-sql/benches/common/mod.rs new file mode 100644 index 00000000..d2a5da07 --- /dev/null +++ b/crates/polyglot-sql/benches/common/mod.rs @@ -0,0 +1,93 @@ +//! SQL inputs shared by the latency and allocation hotspot benchmarks. +//! Dialect selection stays in the callers, so both suites use identical fixtures. + +pub(super) const SHORT_ASCII: &str = + "SELECT a, b, SUM(c) AS total FROM events WHERE created_at >= '2025-01-01' GROUP BY a, b"; + +pub(super) const UNICODE: &str = + "SELECT \"Kundennummer\", 'Gr\u{00fc}\u{00df}e aus Z\u{00fc}rich' AS \"Mitteilung\" FROM \"Bestellungen\" WHERE \"Stadt\" = 'M\u{00fc}nchen'"; + +pub(super) const COMMENT_AND_STRING_HEAVY: &str = r#" +-- leading comment +SELECT 'alpha''beta' AS value, "quoted name", E'line\nvalue' +FROM events /* source comment */ +WHERE payload = '{"key":"value"}' -- trailing comment +"#; + +pub(super) fn large_token_list() -> String { + let values = (0..20_000) + .map(|value| value.to_string()) + .collect::>() + .join(", "); + format!("SELECT * FROM events WHERE event_id IN ({values})") +} + +pub(super) fn many_columns() -> String { + format!( + "SELECT {} FROM t", + (0..1_000) + .map(|index| format!("c{index}")) + .collect::>() + .join(", ") + ) +} + +pub(super) fn nested_functions() -> String { + format!( + "SELECT {}x{} FROM t", + "COALESCE(".repeat(20), + ", NULL)".repeat(20) + ) +} + +pub(super) fn large_strings() -> String { + format!( + "SELECT {} FROM t", + vec![format!("'{}'", "x".repeat(100)); 500].join(", ") + ) +} + +pub(super) fn many_numbers() -> String { + format!( + "SELECT {} FROM t", + (0..10_000) + .map(|value| value.to_string()) + .collect::>() + .join(", ") + ) +} + +#[cfg(feature = "transpile")] +pub(super) fn transpilation_queries() -> Vec<(&'static str, String)> { + vec![ + ("short", "SELECT COALESCE(x, 0) FROM t".to_owned()), + ( + "wide", + format!( + "SELECT {} FROM t", + (0..100) + .map(|i| format!("COALESCE(c{i}, 0) AS v{i}")) + .collect::>() + .join(", ") + ), + ), + ( + "nested", + format!( + "SELECT {}x{} FROM t", + "COALESCE(".repeat(20), + ", 0)".repeat(20) + ), + ), + ( + "casts", + format!( + "SELECT {}", + (0..100) + .map(|i| format!("CAST({i}.123 AS DECIMAL(10, 2)) AS v{i}")) + .collect::>() + .join(", ") + ), + ), + ] +} diff --git a/crates/polyglot-sql/benches/performance_hotspots.rs b/crates/polyglot-sql/benches/performance_hotspots.rs index edfba50f..64122b5c 100644 --- a/crates/polyglot-sql/benches/performance_hotspots.rs +++ b/crates/polyglot-sql/benches/performance_hotspots.rs @@ -4,18 +4,12 @@ use polyglot_sql::parser::{Parser, ParserConfig}; use polyglot_sql::ComplexityGuardOptions; use std::time::Duration; -const SHORT_ASCII: &str = - "SELECT a, b, SUM(c) AS total FROM events WHERE created_at >= '2025-01-01' GROUP BY a, b"; +mod common; -const UNICODE: &str = - "SELECT \"Kundennummer\", 'Gr\u{00fc}\u{00df}e aus Z\u{00fc}rich' AS \"Mitteilung\" FROM \"Bestellungen\" WHERE \"Stadt\" = 'M\u{00fc}nchen'"; - -const COMMENT_AND_STRING_HEAVY: &str = r#" --- leading comment -SELECT 'alpha''beta' AS value, "quoted name", E'line\nvalue' -FROM events /* source comment */ -WHERE payload = '{"key":"value"}' -- trailing comment -"#; +use common::{ + large_strings, large_token_list, many_columns, many_numbers, nested_functions, + COMMENT_AND_STRING_HEAVY, SHORT_ASCII, UNICODE, +}; const TPCH_STYLE: &str = r#" WITH regional_sales AS ( @@ -36,49 +30,6 @@ WHERE ranked.position <= 10 ORDER BY ranked.revenue DESC "#; -fn large_token_list() -> String { - let values = (0..20_000) - .map(|value| value.to_string()) - .collect::>() - .join(", "); - format!("SELECT * FROM events WHERE event_id IN ({values})") -} - -fn many_columns() -> String { - format!( - "SELECT {} FROM t", - (0..1_000) - .map(|index| format!("c{index}")) - .collect::>() - .join(", ") - ) -} - -fn nested_functions() -> String { - format!( - "SELECT {}x{} FROM t", - "COALESCE(".repeat(20), - ", NULL)".repeat(20) - ) -} - -fn large_strings() -> String { - format!( - "SELECT {} FROM t", - vec![format!("'{}'", "x".repeat(100)); 500].join(", ") - ) -} - -fn many_numbers() -> String { - format!( - "SELECT {} FROM t", - (0..10_000) - .map(|value| value.to_string()) - .collect::>() - .join(", ") - ) -} - fn disabled_guards() -> ComplexityGuardOptions { ComplexityGuardOptions { max_parser_depth: None, @@ -286,12 +237,32 @@ fn bench_hana_nested_queries(c: &mut Criterion) { group.finish(); } +fn bench_hana_source_validation(c: &mut Criterion) { + #[cfg(feature = "transpile")] + { + let options = polyglot_sql::TranspileOptions::strict(); + let mut group = c.benchmark_group("hana_source_validation"); + for (name, sql) in common::transpilation_queries() { + group.bench_with_input(BenchmarkId::from_parameter(name), &sql, |b, sql| { + b.iter(|| { + polyglot_sql::transpile_with_by_name(black_box(sql), "hana", "duckdb", &options) + .unwrap() + }); + }); + } + group.finish(); + } + #[cfg(not(feature = "transpile"))] + let _ = c; +} + criterion_group!( benches, bench_dialect_construction, bench_fresh_vs_reused_dialect, bench_tokenize_and_parse, bench_validation_and_analysis, - bench_hana_nested_queries + bench_hana_nested_queries, + bench_hana_source_validation ); criterion_main!(benches); diff --git a/crates/polyglot-sql/src/dialects/mod.rs b/crates/polyglot-sql/src/dialects/mod.rs index e75471b1..a642243f 100644 --- a/crates/polyglot-sql/src/dialects/mod.rs +++ b/crates/polyglot-sql/src/dialects/mod.rs @@ -3523,27 +3523,14 @@ impl Dialect { expressions .into_iter() .map(|expr| { - // This API parses SQL itself: only the HANA parser currently - // produces source-bound nodes. Standalone AST generation checks - // those nodes independently in the generator. Other SQL sources - // need not pay for a speculative full-tree validation pass. - if self.dialect_type == DialectType::HANA { - // Validate source-bound semantics before normalization can erase them. - // Generating each outermost protected subtree checks its descendants too. - let mut pending = vec![&expr]; - while let Some(node) = pending.pop() { - if let Some(source) = node.source_dialect() { - if source != target { - target_dialect - .generate_with_transpile_options(node, source, opts)?; - continue; - } - } - crate::ast_children::for_each_child_untracked(node, |child| { - pending.push(child) - }); - } - } + // Reject unsupported source semantics before normalization can + // erase them. This AST-only pass shares conversion decisions with + // the generator and never renders throwaway SQL. + Self::reject_hana_source_semantics( + &expr, + self.dialect_type, + target_dialect.generator_config.dialect.unwrap_or_default(), + )?; // DuckDB source: normalize VARCHAR/CHAR to TEXT (DuckDB doesn't support // VARCHAR length constraints). This emulates Python sqlglot's DuckDB parser @@ -4367,6 +4354,25 @@ impl Dialect { && select.for_json.is_empty() } + fn reject_hana_source_semantics( + expression: &Expression, + source: DialectType, + target: DialectType, + ) -> Result<()> { + if source != DialectType::HANA || target == DialectType::HANA { + return Ok(()); + } + let mut pending = vec![expression]; + while let Some(node) = pending.pop() { + if node.source_dialect() == Some(DialectType::HANA) { + Generator::validate_hana_source_node(node, target)?; + } + // A supported outer call does not establish support for its arguments. + crate::ast_children::for_each_child_untracked(node, |child| pending.push(child)); + } + Ok(()) + } + fn reject_clickhouse_session_semantics( expr: &Expression, source: DialectType, @@ -10150,6 +10156,152 @@ impl Dialect { mod tests { use super::*; + #[cfg(all( + feature = "transpile", + feature = "dialect-hana", + feature = "dialect-duckdb", + feature = "dialect-trino" + ))] + #[test] + fn hana_validation_and_generation_agree_after_ast_serialization() { + let hana = Dialect::get(DialectType::HANA); + for (sql, duckdb, trino) in [ + ("SELECT COALESCE(IFNULL(x, 0), 1) FROM t", true, true), + ("SELECT LOCATE('abcabc', 'bc', 2)", true, true), + ("SELECT LOCATE('abcabc', 'bc', 1, 2)", false, true), + ("SELECT SUBSTRING('abc', -1, -2)", true, true), + ("SELECT TO_DECIMAL(12.345, 5, 2)", true, true), + ( + "SELECT CAST(12.345 AS DECIMAL(5)), CAST(-12.9 AS INT)", + true, + true, + ), + ("SELECT TO_DATE('2024-01-15', 'YYYY-MM-DD')", true, true), + ( + "SELECT TO_TIMESTAMP('2024-01-15', 'YYYY-MM-DD')", + false, + true, + ), + ( + "SELECT TO_VARCHAR(DATE '2024-01-15', 'YYYY-MM-DD')", + true, + true, + ), + ("SELECT CURRENT_UTCDATE", true, true), + ( + "SELECT CURRENT_UTCTIMESTAMP(7), CURRENT_UTCTIME", + false, + true, + ), + ("CREATE TABLE t (n INT, xs INT ARRAY)", true, true), + ("CREATE TABLE t (n SMALLDECIMAL ARRAY)", false, false), + ("SELECT COALESCE(ADD_DAYS(d, 1), d) FROM t", false, false), + ("SELECT COALESCE(CAST(x AS INT), 0) FROM t", false, false), + ( + "SELECT COALESCE(JSON_VALUE(j, '$.a'), 'x') FROM t", + false, + false, + ), + ( + "SELECT COALESCE(SUBSTR_REGEXPR('a' IN s), 'x') FROM t", + false, + false, + ), + ( + "SELECT COALESCE(STRING_AGG(x, ','), '') FROM t", + false, + false, + ), + ( + "CREATE TABLE t (n INT DEFAULT ADD_DAYS(d, 1))", + false, + false, + ), + ("SELECT * FROM t FOR JSON", false, false), + ("CREATE COLUMN TABLE t (n INT)", false, false), + ("SELECT * FROM t WITH HINT (NO_INLINE)", false, false), + ] { + let ast = hana.parse(sql).unwrap().remove(0); + let json = serde_json::to_string(&ast).unwrap(); + let ast: Expression = serde_json::from_str(&json).unwrap(); + for (target, supported) in [(DialectType::DuckDB, duckdb), (DialectType::Trino, trino)] + { + assert_eq!( + Dialect::reject_hana_source_semantics(&ast, DialectType::HANA, target).is_ok(), + supported, + "validation: {sql} -> {target}" + ); + assert_eq!( + Dialect::get(target).generate(&ast).is_ok(), + supported, + "generation: {sql} -> {target}" + ); + } + assert!(Dialect::reject_hana_source_semantics( + &ast, + DialectType::HANA, + DialectType::HANA + ) + .is_ok()); + } + } + + #[cfg(all( + feature = "transpile", + feature = "dialect-hana", + feature = "dialect-duckdb" + ))] + #[test] + fn hana_rejects_source_semantics_before_preprocessing_can_erase_them() { + use std::sync::atomic::{AtomicBool, Ordering}; + let called = Arc::new(AtomicBool::new(false)); + let seen = Arc::clone(&called); + let mut hana = Dialect::get(DialectType::HANA); + hana.custom_preprocess = Some(Box::new(move |_| { + seen.store(true, Ordering::Relaxed); + Ok(Expression::number(1)) + })); + for level in [ + UnsupportedLevel::Ignore, + UnsupportedLevel::Warn, + UnsupportedLevel::Raise, + UnsupportedLevel::Immediate, + ] { + for sql in [ + "SELECT COALESCE(ADD_DAYS(d, 1), d) FROM t", + "SELECT COALESCE(CAST(x AS INT), 0) FROM t", + "SELECT COALESCE(JSON_VALUE(j, '$.a'), 'x') FROM t", + "CREATE TABLE t (x SMALLDECIMAL ARRAY)", + "SELECT * FROM t FOR JSON", + "SELECT * FROM t WITH HINT (NO_INLINE)", + ] { + assert!( + hana.transpile_with( + sql, + DialectType::DuckDB, + TranspileOptions::default().with_unsupported_level(level) + ) + .is_err(), + "{sql}" + ); + assert!( + !called.load(Ordering::Relaxed), + "preprocessing must not erase unsupported input: {sql}" + ); + } + } + let mut target = Dialect::get(DialectType::DuckDB); + Arc::make_mut(&mut target.generator_config).dialect = Some(DialectType::Generic); + assert!(hana + .transpile("SELECT LOCATE('abc', 'b')", &target) + .is_err()); + assert!(!called.load(Ordering::Relaxed)); + assert!(hana + .transpile("SELECT COALESCE(x, 0) FROM t", DialectType::DuckDB) + .is_ok()); + assert!(called.load(Ordering::Relaxed)); + } + #[test] fn built_in_dialect_instances_share_tokenizer_config() { let first = Dialect::get(DialectType::PostgreSQL); diff --git a/crates/polyglot-sql/src/generator.rs b/crates/polyglot-sql/src/generator.rs index c9ae8ff8..77f0805f 100644 --- a/crates/polyglot-sql/src/generator.rs +++ b/crates/polyglot-sql/src/generator.rs @@ -184,6 +184,39 @@ enum TsqlDatePart { Unsupported(String), } +// Validated conversion decisions shared by rendering and source checks. +enum HanaFunctionMapping { + Quoted, + Coalesce, + Locate { + start: i64, + occurrence: i64, + }, + Substring { + start: i64, + length: Option, + }, + Decimal { + precision: i64, + scale: i64, + }, + Datetime { + mask: String, + formatting: bool, + date: bool, + }, + Utc { + precision: i64, + date: bool, + time: bool, + }, +} + +enum HanaTypeMapping<'a> { + Name(&'a str), + Standard(DataType), +} + /// Identifier quote style (start/end characters) #[derive(Debug, Clone, Copy, PartialEq)] pub struct IdentifierQuoteStyle { @@ -2528,6 +2561,84 @@ impl Generator { Ok(sql) } + /// Check a source node using the same decisions as rendering, without emitting SQL. + /// Descendants are checked by the transpilation pipeline. + #[cfg(feature = "transpile")] + pub(crate) fn validate_hana_source_node(node: &Expression, target: DialectType) -> Result<()> { + let unsupported_feature = match node { + Expression::Function(f) => { + Self::hana_function_mapping(f, target)?; + return Ok(()); + } + Expression::Cast(c) => { + if let DataType::Hana { hana_type } = &c.to { + match hana_type.name.as_str() { + "TINYINT" | "SMALLINT" | "INT" | "BIGINT" => { + Self::hana_integer_cast(c, &hana_type.name, target)?; + } + "DECIMAL" => { + Self::hana_decimal_cast(c, hana_type, target)?; + } + _ => { + Self::hana_type_mapping(hana_type, target)?; + } + } + } + return Ok(()); + } + Expression::DataType(DataType::Hana { hana_type }) => { + Self::hana_type_mapping(hana_type, target)?; + return Ok(()); + } + Expression::Select(s) => return Self::validate_hana_select(s, target), + Expression::CreateTable(t) => return Self::validate_hana_create_table(t, target), + Expression::AggregateFunction(f) => { + return Err(Self::hana_unsupported_for_target( + target, + format!("HANA aggregate {} has no verified target mapping", f.name), + )) + } + Expression::Upsert(_) => { + "HANA UPSERT requires target-specific key and update semantics" + } + Expression::Call(_) => "HANA CALL requires a verified target procedure signature", + Expression::Hierarchy(_) => "HANA hierarchy has no verified target mapping", + Expression::ViewParameter(_) => { + "HANA calculation-view PLACEHOLDER has no verified target mapping" + } + Expression::StorageProperty(_) => { + "HANA storage property has no verified target mapping" + } + Expression::Hint(_) => "Optimizer hint has no verified target mapping", + Expression::JSONValue(_) + | Expression::JSONTable(_) + | Expression::JSONColumnDef(_) + | Expression::JsonQuery(_) + | Expression::JsonExtract(_) + | Expression::JsonExtractScalar(_) => { + "SQL/JSON path and error semantics have no verified target mapping" + } + Expression::RegexpLike(_) + | Expression::RegexpReplace(_) + | Expression::RegexpExtract(_) + | Expression::RegexpInstr(_) + | Expression::RegexpCount(_) => { + "Regular-expression source semantics have no verified target mapping" + } + Expression::Cube(_) | Expression::Rollup(_) | Expression::GroupingSets(_) => { + "HANA grouping-set selection and result delivery options" + } + Expression::PartitionByProperty(_) => { + "HANA partitioning has no verified target mapping" + } + _ => "HANA source semantics have no verified target mapping", + }; + Err(Self::hana_unsupported_for_target( + target, + unsupported_feature, + )) + } + fn generate_expression(&mut self, expr: &Expression) -> Result<()> { #[cfg(feature = "stacker")] { @@ -4742,19 +4853,24 @@ impl Generator { Some(outer) } - fn generate_select(&mut self, select: &Select) -> Result<()> { - if (select.result_serialization.is_some() - || select.query_collation.is_some() - || !select.query_hints.is_empty() - || select.total_rowcount - || select.locks.iter().any(|lock| lock.ignore_locked)) - && self.config.dialect != Some(DialectType::HANA) + fn validate_hana_select(select: &Select, target: DialectType) -> Result<()> { + if target != DialectType::HANA + && (select.result_serialization.is_some() + || select.query_collation.is_some() + || !select.query_hints.is_empty() + || select.total_rowcount + || select.locks.iter().any(|lock| lock.ignore_locked)) { - return Err(crate::error::Error::unsupported( + return Err(Self::hana_unsupported_for_target( + target, "HANA SELECT serialization or hints have no verified target mapping", - self.config.dialect.unwrap_or_default().to_string(), )); } + Ok(()) + } + + fn generate_select(&mut self, select: &Select) -> Result<()> { + Self::validate_hana_select(select, self.config.dialect.unwrap_or_default())?; use crate::dialects::DialectType; @@ -8614,18 +8730,27 @@ impl Generator { // ==================== DDL Generation ==================== - fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> { - if ct.source_dialect == Some(DialectType::HANA) - && self.config.dialect != Some(DialectType::HANA) - && ct.table_modifier.as_ref().is_some_and(|m| { - m.split_whitespace() - .any(|part| matches!(part, "COLUMN" | "ROW" | "LOCAL" | "GLOBAL")) - }) - { - return Err( - self.hana_unsupported("HANA table storage/scope has no verified target mapping") - ); + fn validate_hana_create_table(table: &CreateTable, target: DialectType) -> Result<()> { + if table.source_dialect != Some(DialectType::HANA) || target == DialectType::HANA { + return Ok(()); + } + if table.table_modifier.as_ref().is_some_and(|m| { + m.split_whitespace() + .any(|p| matches!(p, "COLUMN" | "ROW" | "LOCAL" | "GLOBAL")) + }) { + return Err(Self::hana_unsupported_for_target( + target, + "HANA table storage/scope has no verified target mapping", + )); + } + for column in table.columns.iter().chain(&table.with_partition_columns) { + Self::validate_hana_data_type(&column.data_type, target)?; } + Ok(()) + } + + fn generate_create_table(&mut self, ct: &CreateTable) -> Result<()> { + Self::validate_hana_create_table(ct, self.config.dialect.unwrap_or_default())?; // Athena: Determine if this is Hive-style DDL or Trino-style DML // CREATE TABLE AS SELECT uses Trino (double quotes) @@ -18275,17 +18400,12 @@ impl Generator { return self.generate_hana_integer_cast(cast, &hana_type.name); } if hana_type.name == "DECIMAL" { - let mut args = vec![cast.this.clone()]; - args.extend( - hana_type - .parameters - .iter() - .map(|n| Expression::number(i64::from(*n))), - ); - if hana_type.parameters.len() == 1 { - args.push(Expression::number(0)); - } - return self.generate_hana_function(&Function::new("TO_DECIMAL", args)); + let (precision, scale) = Self::hana_decimal_cast( + cast, + hana_type, + self.config.dialect.unwrap_or_default(), + )?; + return self.generate_hana_decimal(&cast.this, precision, scale); } } } @@ -19191,38 +19311,77 @@ impl Generator { } } - fn generate_hana_integer_cast(&mut self, cast: &Cast, name: &str) -> Result<()> { - let target = self.config.dialect.unwrap_or_default(); - let supported = matches!( + fn hana_exact_numeric(expr: &Expression) -> bool { + match expr { + Expression::Literal(l) => { + matches!(l.as_ref(), Literal::Number(n) if !n.contains(['e', 'E'])) + } + Expression::Neg(n) => Self::hana_exact_numeric(&n.this), + Expression::Cast(c) => { + matches!( + &c.to, + DataType::Decimal { + precision: Some(_), + .. + } + ) || matches!(&c.to, DataType::Hana { hana_type } if hana_type.name == "DECIMAL" && !hana_type.parameters.is_empty()) + } + _ => false, + } + } + + fn hana_portable_string(expr: &Expression) -> bool { + // HANA indexes CESU-8/UTF-16 units; these targets index Unicode code + // points. Unknown/binary/supplementary-character inputs need another mapping. + matches!(expr, Expression::Literal(l) if matches!(l.as_ref(), Literal::String(s) | Literal::NationalString(s) if s.chars().all(|c| (c as u32) <= 0xffff))) + } + + fn hana_trino_target(target: DialectType) -> bool { + matches!( target, - DialectType::DuckDB - | DialectType::PostgreSQL - | DialectType::Trino - | DialectType::Presto - | DialectType::Athena - | DialectType::Dune - | DialectType::CockroachDB - | DialectType::Materialize - | DialectType::RisingWave - ); + DialectType::Trino | DialectType::Presto | DialectType::Athena | DialectType::Dune + ) + } + + fn hana_numeric_target(target: DialectType) -> bool { + Self::hana_trino_target(target) + || matches!( + target, + DialectType::DuckDB + | DialectType::PostgreSQL + | DialectType::CockroachDB + | DialectType::Materialize + | DialectType::RisingWave + ) + } + + /// Return whether truncation is needed before an integer conversion. + fn hana_integer_cast(cast: &Cast, name: &str, target: DialectType) -> Result { let integer = Self::hana_integer(&cast.this); - // TINYINT is unsigned in HANA. Wider signed targets are safe only when - // the value is proven to fit; otherwise their overflow behavior differs. let tinyint_fits = name != "TINYINT" || target == DialectType::DuckDB || integer.is_some_and(|n| (0..=255).contains(&n)); - if !supported + if !Self::hana_numeric_target(target) || !tinyint_fits || !Self::hana_exact_numeric(&cast.this) || cast.format.is_some() || cast.default.is_some() { - return Err(self.hana_unsupported(format!( - "HANA {name} CAST requires verified numeric input and matching overflow semantics" - ))); + return Err(Self::hana_unsupported_for_target( + target, + format!( + "HANA {name} CAST requires verified numeric input and matching overflow semantics" + ), + )); } + Ok(integer.is_none()) + } + + fn generate_hana_integer_cast(&mut self, cast: &Cast, name: &str) -> Result<()> { + let target = self.config.dialect.unwrap_or_default(); + let truncate = Self::hana_integer_cast(cast, name, target)?; self.write("CAST("); - if integer.is_none() { + if truncate { self.write( if matches!( target, @@ -19238,7 +19397,7 @@ impl Generator { ); } self.generate_expression(&cast.this)?; - if integer.is_none() { + if truncate { self.write(")"); } self.write(" AS "); @@ -19251,36 +19410,15 @@ impl Generator { Ok(()) } - fn hana_exact_numeric(expr: &Expression) -> bool { - match expr { - Expression::Literal(l) => { - matches!(l.as_ref(), Literal::Number(n) if !n.contains(['e', 'E'])) - } - Expression::Neg(n) => Self::hana_exact_numeric(&n.this), - Expression::Cast(c) => { - matches!( - &c.to, - DataType::Decimal { - precision: Some(_), - .. - } - ) || matches!(&c.to, DataType::Hana { hana_type } if hana_type.name == "DECIMAL" && !hana_type.parameters.is_empty()) - } - _ => false, - } - } - - fn hana_portable_string(expr: &Expression) -> bool { - // HANA indexes CESU-8/UTF-16 units; these targets index Unicode code - // points. Unknown/binary/supplementary-character inputs need another mapping. - matches!(expr, Expression::Literal(l) if matches!(l.as_ref(), Literal::String(s) | Literal::NationalString(s) if s.chars().all(|c| (c as u32) <= 0xffff))) + fn hana_unsupported_for_target( + target: DialectType, + feature: impl Into, + ) -> crate::error::Error { + crate::error::Error::unsupported(feature, target.to_string()) } fn hana_unsupported(&self, feature: impl Into) -> crate::error::Error { - crate::error::Error::unsupported( - feature, - self.config.dialect.unwrap_or_default().to_string(), - ) + Self::hana_unsupported_for_target(self.config.dialect.unwrap_or_default(), feature) } fn generate_grouping_options( @@ -19343,256 +19481,385 @@ impl Generator { Ok(()) } - fn generate_hana_function(&mut self, function: &Function) -> Result<()> { + fn hana_function_mapping( + function: &Function, + target: DialectType, + ) -> Result { if function.quoted { - let mut identifier = Identifier::new(&function.name); - identifier.quoted = true; - self.generate_identifier(&identifier)?; - self.write("("); - for (i, arg) in function.args.iter().enumerate() { - if i > 0 { - self.write(", "); - } - self.generate_expression(arg)?; - } - self.write(")"); - return Ok(()); - } - if self.config.dialect == Some(DialectType::HANA) { - return self.generate_function(function); + return Ok(HanaFunctionMapping::Quoted); } - let name = function.name.to_ascii_uppercase(); + let name = if function.name.bytes().any(|c| c.is_ascii_lowercase()) { + Cow::Owned(function.name.to_ascii_uppercase()) + } else { + Cow::Borrowed(function.name.as_str()) + }; let args = &function.args; - let target = self.config.dialect.unwrap_or_default(); - let trino = matches!( - target, - DialectType::Trino | DialectType::Presto | DialectType::Athena | DialectType::Dune - ); - let postgres = matches!( - target, - DialectType::PostgreSQL - | DialectType::CockroachDB - | DialectType::Materialize - | DialectType::RisingWave - ); - let duckdb = target == DialectType::DuckDB; - - // These calls are retained as source nodes until generation so parsing, - // JSON serialization, and native transpilation cannot lose HANA semantics. - if matches!(name.as_str(), "COALESCE" | "IFNULL") && args.len() >= 2 { - return self.generate_vararg_func("COALESCE", args); + if matches!(name.as_ref(), "COALESCE" | "IFNULL") && args.len() >= 2 { + return Ok(HanaFunctionMapping::Coalesce); } - if name == "LOCATE" && (2..=4).contains(&args.len()) && (trino || postgres || duckdb) { - let start = if args.len() >= 3 { - Self::hana_integer(&args[2]) - } else { - Some(1) - }; - let occurrence = if args.len() == 4 { - Self::hana_integer(&args[3]) - } else { - Some(1) - }; + if name == "LOCATE" && (2..=4).contains(&args.len()) && Self::hana_numeric_target(target) { + let start = args.get(2).map_or(Some(1), Self::hana_integer); + let occurrence = args.get(3).map_or(Some(1), Self::hana_integer); if let (Some(start), Some(occurrence)) = (start, occurrence) { if start >= 0 && occurrence > 0 - && (trino || occurrence == 1) + && (Self::hana_trino_target(target) || occurrence == 1) && args[..2].iter().all(Self::hana_portable_string) && (!matches!(&args[1], Expression::Literal(l) if matches!(l.as_ref(), Literal::String(s) | Literal::NationalString(s) if s.is_empty())) || (start <= 1 && occurrence == 1)) { - let haystack = self.generate_to_string(&args[0])?; - let needle = self.generate_to_string(&args[1])?; - let start = start.max(1); - let searched = if start == 1 { - haystack - } else { - format!("SUBSTR({haystack}, {start})") - }; - let found = if trino && occurrence != 1 { - format!("STRPOS({searched}, {needle}, {occurrence})") - } else { - format!("STRPOS({searched}, {needle})") - }; - if start == 1 { - self.write(&found); - } else { - self.write(&format!( - "CASE WHEN {found} = 0 THEN 0 ELSE {found} + {} END", - start - 1 - )); - } - return Ok(()); + return Ok(HanaFunctionMapping::Locate { + start: start.max(1), + occurrence, + }); } } } - if matches!(name.as_str(), "SUBSTRING" | "SUBSTR") + if matches!(name.as_ref(), "SUBSTRING" | "SUBSTR") && (2..=3).contains(&args.len()) - && (trino || postgres || duckdb) + && Self::hana_numeric_target(target) && Self::hana_portable_string(&args[0]) { - // Constant bounds avoid changing NULL propagation or evaluating a - // volatile bound more than once. Dynamic/binary cases need a typed mapping. if let Some(start) = Self::hana_integer(&args[1]) { let length = args.get(2).map(Self::hana_integer); if !matches!(length, Some(None)) { - let mut lowered = vec![args[0].clone(), Expression::number(start.max(1))]; - if let Some(Some(length)) = length { - lowered.push(Expression::number(length.max(0))); - } - return self.generate_vararg_func("SUBSTRING", &lowered); + return Ok(HanaFunctionMapping::Substring { + start: start.max(1), + length: length.flatten().map(|n| n.max(0)), + }); } } } - if name == "TO_DECIMAL" && args.len() == 3 && (trino || postgres || duckdb) { - if let (Some(precision), Some(scale)) = - (Self::hana_integer(&args[1]), Self::hana_integer(&args[2])) - { - if (1..=38).contains(&precision) && (0..=precision).contains(&scale) { - // Require numeric input evidence. Casting an unknown string - // before truncation can round away digits or change format rules. - let numeric = Self::hana_exact_numeric(&args[0]); - if numeric { - let value = self.generate_to_string(&args[0])?; - let truncate = if trino { "TRUNCATE" } else { "TRUNC" }; - self.write(&format!( - "CAST({truncate}({value}, {scale}) AS DECIMAL({precision}, {scale}))" - )); - return Ok(()); - } - } - } + if name == "TO_DECIMAL" && args.len() == 3 { + let (precision, scale) = Self::hana_decimal_mapping( + &args[0], + Self::hana_integer(&args[1]), + Self::hana_integer(&args[2]), + target, + )?; + return Ok(HanaFunctionMapping::Decimal { precision, scale }); } if matches!( - name.as_str(), + name.as_ref(), "TO_DATE" | "TO_TIMESTAMP" | "TO_VARCHAR" | "TO_NVARCHAR" ) && args.len() == 2 - && (trino || duckdb) + && (Self::hana_trino_target(target) || target == DialectType::DuckDB) && (name != "TO_TIMESTAMP" || target == DialectType::Trino) { if let Expression::Literal(literal) = &args[1] { if let Literal::String(mask) = literal.as_ref() { - if let Some(mask) = crate::format_tokens::hana_datetime_format(mask, trino) { - let formatting = matches!(name.as_str(), "TO_VARCHAR" | "TO_NVARCHAR"); + if let Some(mask) = crate::format_tokens::hana_datetime_format( + mask, + Self::hana_trino_target(target), + ) { + let formatting = matches!(name.as_ref(), "TO_VARCHAR" | "TO_NVARCHAR"); let known_datetime = matches!(&args[0], Expression::Cast(c) if matches!(c.to, DataType::Date | DataType::Timestamp { .. } | DataType::Time { .. })) || matches!(&args[0], Expression::Cast(c) if matches!(&c.to, DataType::Hana { hana_type } if matches!(hana_type.name.as_str(), "TIMESTAMP" | "TIME" | "SECONDDATE"))) || matches!(&args[0], Expression::Literal(l) if matches!(l.as_ref(), Literal::Date(_) | Literal::Timestamp(_))); if !formatting || known_datetime { - let value = self.generate_to_string(&args[0])?; - let mask = self.generate_to_string(&Expression::string(mask))?; - if formatting { - let function = if trino { "DATE_FORMAT" } else { "STRFTIME" }; - self.write(&format!("{function}({value}, {mask})")); - } else { - let function = if trino { "DATE_PARSE" } else { "STRPTIME" }; - let result_type = if name == "TO_DATE" { - "DATE" - } else if trino { - "TIMESTAMP(7)" - } else { - "TIMESTAMP" - }; - self.write(&format!( - "CAST({function}({value}, {mask}) AS {result_type})" - )); - } - return Ok(()); + return Ok(HanaFunctionMapping::Datetime { + mask, + formatting, + date: name == "TO_DATE", + }); } } } } } if matches!( - name.as_str(), + name.as_ref(), "CURRENT_UTCDATE" | "CURRENT_UTCTIME" | "CURRENT_UTCTIMESTAMP" - ) && (trino || postgres || duckdb) + ) && Self::hana_numeric_target(target) { - let precision = if args.is_empty() { - Some(3) - } else if args.len() == 1 { - Self::hana_integer(&args[0]) - } else { - None + let precision = match args.as_slice() { + [] => Some(3), + [arg] => Self::hana_integer(arg), + _ => None, }; if let Some(precision) = precision { if (0..=7).contains(&precision) && (target == DialectType::Trino || name == "CURRENT_UTCDATE") { - let utc = if trino && name == "CURRENT_UTCTIMESTAMP" { - format!("CURRENT_TIMESTAMP({precision}) AT TIME ZONE 'UTC'") - } else { - "CURRENT_TIMESTAMP AT TIME ZONE 'UTC'".to_owned() - }; - let data_type = match name.as_str() { - "CURRENT_UTCDATE" => "DATE".to_owned(), - "CURRENT_UTCTIME" => "TIME(0)".to_owned(), - _ => format!("TIMESTAMP({precision})"), - }; - self.write(&format!("CAST({utc} AS {data_type})")); - return Ok(()); + return Ok(HanaFunctionMapping::Utc { + precision, + date: name == "CURRENT_UTCDATE", + time: name == "CURRENT_UTCTIME", + }); } } } - Err(self.hana_unsupported(format!( - "HANA {name}: no verified mapping for these arguments" - ))) + Err(Self::hana_unsupported_for_target( + target, + format!("HANA {name}: no verified mapping for these arguments"), + )) } - fn generate_hana_data_type(&mut self, data_type: &HanaDataType) -> Result<()> { - if self.config.dialect != Some(DialectType::HANA) { - let target = self.config.dialect.unwrap_or_default(); - match (data_type.name.as_str(), data_type.parameters.as_slice()) { - ("SMALLINT" | "INT" | "BIGINT", []) => { - self.write(&data_type.name); - return Ok(()); + fn generate_hana_function(&mut self, function: &Function) -> Result<()> { + if self.config.dialect == Some(DialectType::HANA) { + return self.generate_function(function); + } + let target = self.config.dialect.unwrap_or_default(); + let args = &function.args; + let trino = matches!( + target, + DialectType::Trino | DialectType::Presto | DialectType::Athena | DialectType::Dune + ); + match Self::hana_function_mapping(function, target)? { + HanaFunctionMapping::Quoted => { + let mut identifier = Identifier::new(&function.name); + identifier.quoted = true; + self.generate_identifier(&identifier)?; + self.write("("); + for (i, arg) in args.iter().enumerate() { + if i > 0 { + self.write(", "); + } + self.generate_expression(arg)?; } - ("TIMESTAMP", []) if target == DialectType::Trino => { - self.write("TIMESTAMP(7)"); - return Ok(()); + self.write(")"); + } + HanaFunctionMapping::Coalesce => return self.generate_vararg_func("COALESCE", args), + HanaFunctionMapping::Locate { start, occurrence } => { + let haystack = self.generate_to_string(&args[0])?; + let needle = self.generate_to_string(&args[1])?; + let searched = if start == 1 { + haystack + } else { + format!("SUBSTR({haystack}, {start})") + }; + let found = if trino && occurrence != 1 { + format!("STRPOS({searched}, {needle}, {occurrence})") + } else { + format!("STRPOS({searched}, {needle})") + }; + if start == 1 { + self.write(&found); + } else { + self.write(&format!( + "CASE WHEN {found} = 0 THEN 0 ELSE {found} + {} END", + start - 1 + )); } - ("TIME", []) if target == DialectType::Trino => { - self.write("TIME(0)"); - return Ok(()); + } + HanaFunctionMapping::Substring { start, length } => { + self.write_func_name("SUBSTRING"); + self.write("("); + self.generate_expression(&args[0])?; + self.write(&format!(", {start}")); + if let Some(length) = length { + self.write(&format!(", {length}")); } - ("FLOAT", [] | [1..=53]) - if matches!( - target, - DialectType::Trino - | DialectType::Presto - | DialectType::DuckDB - | DialectType::PostgreSQL - ) => - { - let real = data_type.parameters.first().is_some_and(|p| *p <= 24); - self.write(if real { - "REAL" - } else if target == DialectType::PostgreSQL { - "DOUBLE PRECISION" + self.write(")"); + } + HanaFunctionMapping::Decimal { precision, scale } => { + return self.generate_hana_decimal(&args[0], precision, scale) + } + HanaFunctionMapping::Datetime { + mask, + formatting, + date, + } => { + let value = self.generate_to_string(&args[0])?; + let mask = self.generate_to_string(&Expression::string(mask))?; + if formatting { + let function = if trino { "DATE_FORMAT" } else { "STRFTIME" }; + self.write(&format!("{function}({value}, {mask})")); + } else { + let function = if trino { "DATE_PARSE" } else { "STRPTIME" }; + let result_type = if date { + "DATE" + } else if trino { + "TIMESTAMP(7)" } else { - "DOUBLE" - }); - return Ok(()); + "TIMESTAMP" + }; + self.write(&format!( + "CAST({function}({value}, {mask}) AS {result_type})" + )); } - ("TINYINT", []) - if matches!(target, DialectType::DuckDB | DialectType::ClickHouse) => - { - return self.generate_data_type(&DataType::UInt8); + } + HanaFunctionMapping::Utc { + precision, + date, + time, + } => { + let utc = if trino && !date && !time { + format!("CURRENT_TIMESTAMP({precision}) AT TIME ZONE 'UTC'") + } else { + "CURRENT_TIMESTAMP AT TIME ZONE 'UTC'".to_owned() + }; + let data_type = if date { + "DATE".to_owned() + } else if time { + "TIME(0)".to_owned() + } else { + format!("TIMESTAMP({precision})") + }; + self.write(&format!("CAST({utc} AS {data_type})")); + } + } + Ok(()) + } + + fn hana_decimal_mapping( + input: &Expression, + precision: Option, + scale: Option, + target: DialectType, + ) -> Result<(i64, i64)> { + if let (Some(precision), Some(scale)) = (precision, scale) { + if Self::hana_numeric_target(target) + && (1..=38).contains(&precision) + && (0..=precision).contains(&scale) + && Self::hana_exact_numeric(input) + { + return Ok((precision, scale)); + } + } + Err(Self::hana_unsupported_for_target( + target, + "HANA TO_DECIMAL: no verified mapping for these arguments", + )) + } + + fn hana_decimal_cast( + cast: &Cast, + data_type: &HanaDataType, + target: DialectType, + ) -> Result<(i64, i64)> { + let (precision, scale) = match data_type.parameters.as_slice() { + [p] => (Some(i64::from(*p)), Some(0)), + [p, s] => (Some(i64::from(*p)), Some(i64::from(*s))), + _ => (None, None), + }; + Self::hana_decimal_mapping(&cast.this, precision, scale, target) + } + + fn generate_hana_decimal( + &mut self, + value: &Expression, + precision: i64, + scale: i64, + ) -> Result<()> { + let truncate = if matches!( + self.config.dialect, + Some( + DialectType::Trino | DialectType::Presto | DialectType::Athena | DialectType::Dune + ) + ) { + "TRUNCATE" + } else { + "TRUNC" + }; + self.write("CAST("); + self.write(truncate); + self.write("("); + self.generate_expression(value)?; + self.write(&format!(", {scale}) AS DECIMAL({precision}, {scale}))")); + Ok(()) + } + + fn hana_type_mapping( + data_type: &HanaDataType, + target: DialectType, + ) -> Result> { + let mapping = match (data_type.name.as_str(), data_type.parameters.as_slice()) { + ("SMALLINT" | "INT" | "BIGINT", []) => HanaTypeMapping::Name(&data_type.name), + ("TIMESTAMP", []) if target == DialectType::Trino => { + HanaTypeMapping::Name("TIMESTAMP(7)") + } + ("TIME", []) if target == DialectType::Trino => HanaTypeMapping::Name("TIME(0)"), + ("FLOAT", [] | [1..=53]) + if matches!( + target, + DialectType::Trino + | DialectType::Presto + | DialectType::DuckDB + | DialectType::PostgreSQL + ) => + { + HanaTypeMapping::Name(if data_type.parameters.first().is_some_and(|p| *p <= 24) { + "REAL" + } else if target == DialectType::PostgreSQL { + "DOUBLE PRECISION" + } else { + "DOUBLE" + }) + } + ("TINYINT", []) if matches!(target, DialectType::DuckDB | DialectType::ClickHouse) => { + HanaTypeMapping::Standard(DataType::UInt8) + } + ("DECIMAL", [p, s]) if (1..=38).contains(p) && s <= p => { + HanaTypeMapping::Standard(DataType::Decimal { + precision: Some(*p), + scale: Some(*s), + }) + } + _ => { + return Err(Self::hana_unsupported_for_target( + target, + format!( + "HANA {} has no lossless type mapping for this target", + data_type.name + ), + )) + } + }; + Ok(mapping) + } + + fn validate_hana_data_type(data_type: &DataType, target: DialectType) -> Result<()> { + // Column types are embedded structs, not Expression children. In particular, + // the generic expression walk cannot see HANA types nested inside an ARRAY. + let mut pending = Vec::new(); + let mut current = data_type; + loop { + match current { + DataType::Hana { hana_type } => { + Self::hana_type_mapping(hana_type, target)?; + } + DataType::Array { element_type, .. } + | DataType::List { element_type } + | DataType::Nullable { + inner: element_type, + } + | DataType::Vector { + element_type: Some(element_type), + .. + } => { + current = element_type; + continue; } - ("DECIMAL", [p, s]) if (1..=38).contains(p) && s <= p => { - return self.generate_data_type(&DataType::Decimal { - precision: Some(*p), - scale: Some(*s), - }); + DataType::Map { + key_type, + value_type, + } => { + pending.push(value_type.as_ref()); + current = key_type; + continue; + } + DataType::Struct { fields, .. } => { + pending.extend(fields.iter().map(|f| &f.data_type)) } + DataType::Union { fields } => pending.extend(fields.iter().map(|(_, t)| t)), + DataType::Object { fields, .. } => pending.extend(fields.iter().map(|(_, t, _)| t)), _ => {} } - return Err(crate::error::Error::unsupported( - format!( - "HANA {} has no lossless type mapping for this target", - data_type.name - ), - self.config.dialect.unwrap_or_default().to_string(), - )); + match pending.pop() { + Some(next) => current = next, + None => return Ok(()), + } + } + } + + fn generate_hana_data_type(&mut self, data_type: &HanaDataType) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + match Self::hana_type_mapping(data_type, self.config.dialect.unwrap_or_default())? { + HanaTypeMapping::Name(name) => self.write(name), + HanaTypeMapping::Standard(data_type) => return self.generate_data_type(&data_type), + } + return Ok(()); } self.write(&data_type.name); if !data_type.parameters.is_empty() { @@ -43028,6 +43295,25 @@ mod tests { use super::*; use crate::parser::Parser; + #[cfg(all( + feature = "transpile", + feature = "dialect-hana", + feature = "dialect-duckdb" + ))] + #[test] + fn hana_substring_mapping_preserves_function_name_configuration() { + let ast = crate::Dialect::get(DialectType::HANA) + .parse("SELECT SUBSTRING('abc', -1, 2)") + .unwrap() + .remove(0); + let sql = crate::Dialect::get(DialectType::DuckDB) + .generate_with_overrides(&ast, |config| { + config.normalize_functions = crate::generator::NormalizeFunctions::Lower; + }) + .unwrap(); + assert_eq!(sql, "SELECT substring('abc', 1, 2)"); + } + fn roundtrip(sql: &str) -> String { let ast = Parser::parse_sql(sql).unwrap(); Generator::sql(&ast[0]).unwrap() diff --git a/crates/polyglot-sql/tests/dialect_matrix.rs b/crates/polyglot-sql/tests/dialect_matrix.rs index 4c028f4b..18d920fd 100644 --- a/crates/polyglot-sql/tests/dialect_matrix.rs +++ b/crates/polyglot-sql/tests/dialect_matrix.rs @@ -5567,6 +5567,7 @@ mod hana_regressions { "SELECT TO_VARCHAR(d, fmt) FROM t", "SELECT TO_TIMESTAMP(s, 'YYYY-MM-DD HH24:MI:SS.FF7') FROM t", "SELECT CAST(x AS SMALLDECIMAL) FROM t", + "CREATE TABLE t (x SMALLDECIMAL ARRAY)", "SELECT ADD_MONTHS_LAST(d, 1) FROM t", "SELECT * FROM t WITH HINT (NO_INLINE)", "SELECT * FROM t FOR UPDATE IGNORE LOCKED", From 3f58bcb8406be64ff88ffecebc995698151865ee Mon Sep 17 00:00:00 2001 From: tobilg Date: Wed, 23 Sep 2026 08:58:54 +0200 Subject: [PATCH 7/8] Fixes --- crates/polyglot-sql-ast-derive/src/lib.rs | 17 ++- crates/polyglot-sql/src/ast_children.rs | 70 ++++++++++- crates/polyglot-sql/src/dialects/mod.rs | 24 +++- crates/polyglot-sql/src/generator.rs | 128 +++++++++++++------- crates/polyglot-sql/src/validation.rs | 2 +- crates/polyglot-sql/src/validation/tests.rs | 45 +++++++ crates/polyglot-sql/tests/dialect_matrix.rs | 92 +++++++++++++- 7 files changed, 320 insertions(+), 58 deletions(-) diff --git a/crates/polyglot-sql-ast-derive/src/lib.rs b/crates/polyglot-sql-ast-derive/src/lib.rs index 57784687..ebde3e0d 100644 --- a/crates/polyglot-sql-ast-derive/src/lib.rs +++ b/crates/polyglot-sql-ast-derive/src/lib.rs @@ -58,8 +58,10 @@ fn expand_ast_node(input: &DeriveInput) -> proc_macro2::TokenStream { #immutable } - fn visit_expressions_untracked<'ast, F>(&'ast self, visitor: &mut F) - where F: FnMut(&'ast crate::expressions::Expression), + fn visit_syntax_untracked<'ast, F, T>(&'ast self, visitor: &mut F, type_visitor: &mut T) + where + F: FnMut(&'ast crate::expressions::Expression), + T: FnMut(&'ast crate::expressions::DataType), { #untracked } @@ -307,7 +309,16 @@ fn immutable_visit( if paths { quote!(crate::ast_children::AstNode::visit_expressions(#access, path, visitor);) } else { - quote!(crate::ast_children::AstNode::visit_expressions_untracked(#access, visitor);) + let visit_type = if matches!(ty, Type::Path(path) if path.path.segments.last().is_some_and(|segment| segment.ident == "DataType")) + { + quote!(type_visitor(#access);) + } else { + quote!() + }; + quote! { + #visit_type + crate::ast_children::AstNode::visit_syntax_untracked(#access, visitor, type_visitor); + } } } diff --git a/crates/polyglot-sql/src/ast_children.rs b/crates/polyglot-sql/src/ast_children.rs index 68249988..43142a83 100644 --- a/crates/polyglot-sql/src/ast_children.rs +++ b/crates/polyglot-sql/src/ast_children.rs @@ -15,7 +15,7 @@ allow(dead_code) )] -use crate::expressions::Expression; +use crate::expressions::{DataType, Expression}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub(crate) enum ChildPathSegment { @@ -24,10 +24,12 @@ pub(crate) enum ChildPathSegment { } pub(crate) trait AstNode { - /// Visit children without constructing paths when the caller only needs nodes. - fn visit_expressions_untracked<'ast, F>(&'ast self, visitor: &mut F) + /// Visit expression children and embedded syntax types without constructing paths. + /// Expression descendants are left to the caller; nested type fields are visited here. + fn visit_syntax_untracked<'ast, F, T>(&'ast self, visitor: &mut F, type_visitor: &mut T) where - F: FnMut(&'ast Expression); + F: FnMut(&'ast Expression), + T: FnMut(&'ast DataType); fn visit_expressions<'ast, F>(&'ast self, path: &mut Vec, visitor: &mut F) where @@ -57,7 +59,16 @@ pub(crate) fn for_each_child_untracked<'ast>( expression: &'ast Expression, mut visitor: impl FnMut(&'ast Expression), ) { - expression.visit_expressions_untracked(&mut visitor); + expression.visit_syntax_untracked(&mut visitor, &mut |_| {}); +} + +#[cfg(feature = "transpile")] +pub(crate) fn for_each_child_and_type_untracked<'ast>( + expression: &'ast Expression, + mut visitor: impl FnMut(&'ast Expression), + mut type_visitor: impl FnMut(&'ast DataType), +) { + expression.visit_syntax_untracked(&mut visitor, &mut type_visitor); } #[cfg(test)] @@ -65,6 +76,55 @@ mod tests { use super::*; use crate::Parser; + #[cfg(all(feature = "transpile", feature = "dialect-hana"))] + #[test] + fn syntax_visitor_covers_embedded_types_once_and_skips_inferred_metadata() { + use crate::expressions::HanaDataType; + use crate::{Dialect, DialectType}; + let hana = Dialect::get(DialectType::HANA); + for sql in [ + "ALTER TABLE t ADD (x SMALLDECIMAL ARRAY)", + "CREATE TABLE t (x SMALLDECIMAL ARRAY)", + "SELECT CAST(xs AS SMALLDECIMAL ARRAY) FROM t", + ] { + let ast = hana.parse(sql).unwrap(); + let mut pending = vec![&ast[0]]; + let mut names = Vec::new(); + let mut arrays = 0; + while let Some(node) = pending.pop() { + for_each_child_and_type_untracked( + node, + |child| pending.push(child), + |dt| match dt { + DataType::Hana { hana_type } => names.push(hana_type.name.as_str()), + DataType::Array { .. } => arrays += 1, + _ => {} + }, + ); + } + assert_eq!(names, ["SMALLDECIMAL"], "{sql}"); + assert_eq!(arrays, 1, "{sql}"); + } + let mut node = hana.parse("CAST(1 AS INT)").unwrap().remove(0); + node.set_inferred_type(DataType::Hana { + hana_type: HanaDataType { + name: "SMALLDECIMAL".into(), + parameters: vec![], + }, + }); + let mut names = Vec::new(); + for_each_child_and_type_untracked( + &node, + |_| {}, + |dt| { + if let DataType::Hana { hana_type } = dt { + names.push(hana_type.name.as_str()); + } + }, + ); + assert_eq!(names, ["INT"]); + } + #[test] fn immutable_and_mutable_visitors_cover_the_same_slots() { let mut expression = Parser::parse_sql( diff --git a/crates/polyglot-sql/src/dialects/mod.rs b/crates/polyglot-sql/src/dialects/mod.rs index a642243f..4f89a2c6 100644 --- a/crates/polyglot-sql/src/dialects/mod.rs +++ b/crates/polyglot-sql/src/dialects/mod.rs @@ -4368,7 +4368,24 @@ impl Dialect { Generator::validate_hana_source_node(node, target)?; } // A supported outer call does not establish support for its arguments. - crate::ast_children::for_each_child_untracked(node, |child| pending.push(child)); + // Types in column definitions, casts, routine signatures, etc. are + // embedded syntax, not Expression children. Validate each type once, + // before normalization can replace its enclosing ARRAY/STRUCT type. + // A scalar native CAST already uses a value-aware conversion check + // (e.g. a HANA TINYINT literal can fit a target signed integer). + let cast_type_validated = matches!(node, Expression::Cast(c) + if matches!(c.to, crate::expressions::DataType::Hana { .. })); + let mut type_result = Ok(()); + crate::ast_children::for_each_child_and_type_untracked( + node, + |child| pending.push(child), + |data_type| { + if !cast_type_validated && type_result.is_ok() { + type_result = Generator::validate_hana_source_type(data_type, target); + } + }, + ); + type_result?; } Ok(()) } @@ -10195,6 +10212,8 @@ mod tests { ), ("CREATE TABLE t (n INT, xs INT ARRAY)", true, true), ("CREATE TABLE t (n SMALLDECIMAL ARRAY)", false, false), + ("ALTER TABLE t ADD (n SMALLDECIMAL ARRAY)", false, false), + ("ALTER TABLE t ADD (n INT ARRAY)", true, true), ("SELECT COALESCE(ADD_DAYS(d, 1), d) FROM t", false, false), ("SELECT COALESCE(CAST(x AS INT), 0) FROM t", false, false), ( @@ -10272,6 +10291,9 @@ mod tests { "SELECT COALESCE(CAST(x AS INT), 0) FROM t", "SELECT COALESCE(JSON_VALUE(j, '$.a'), 'x') FROM t", "CREATE TABLE t (x SMALLDECIMAL ARRAY)", + "ALTER TABLE t ADD (x SMALLDECIMAL ARRAY)", + "SELECT CAST(xs AS SMALLDECIMAL ARRAY) FROM t", + "CREATE FUNCTION f(x SMALLDECIMAL ARRAY) RETURNS INT AS 1", "SELECT * FROM t FOR JSON", "SELECT * FROM t WITH HINT (NO_INLINE)", ] { diff --git a/crates/polyglot-sql/src/generator.rs b/crates/polyglot-sql/src/generator.rs index 77f0805f..f16c5d85 100644 --- a/crates/polyglot-sql/src/generator.rs +++ b/crates/polyglot-sql/src/generator.rs @@ -5251,7 +5251,8 @@ impl Generator { } } } else if self.config.dialect == Some(DialectType::HANA) { - self.write(" FROM DUMMY"); + // A user CTE named DUMMY must not capture the synthetic one-row source. + self.write(" FROM SYS.DUMMY"); } // JOINs - handle nested join structure for pretty printing @@ -8743,9 +8744,6 @@ impl Generator { "HANA table storage/scope has no verified target mapping", )); } - for column in table.columns.iter().chain(&table.with_partition_columns) { - Self::validate_hana_data_type(&column.data_type, target)?; - } Ok(()) } @@ -18374,23 +18372,36 @@ impl Generator { Ok(()) } - fn generate_cast(&mut self, cast: &Cast) -> Result<()> { - if self.config.dialect == Some(DialectType::HANA) - && matches!( - cast.to, - DataType::SmallInt { .. } - | DataType::Int { .. } - | DataType::BigInt { .. } - | DataType::TinyInt { .. } - ) - && (Self::hana_integer(&cast.this).is_none() - || matches!(cast.to, DataType::TinyInt { .. }) - && !Self::hana_integer(&cast.this).is_some_and(|n| (0..=127).contains(&n))) + fn validate_cast_to_hana(&self, cast: &Cast) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + return Ok(()); + } + // Native HANA casts retain DataType::Hana. A generic DECIMAL does not + // establish source rounding/overflow semantics, including for TRY/SAFE_CAST. + if matches!(cast.to, DataType::Decimal { .. }) { + return Err(self.hana_unsupported( + "Decimal CAST to HANA requires a verified source conversion; numeric rounding and overflow rules differ", + )); + } + if matches!( + cast.to, + DataType::SmallInt { .. } + | DataType::Int { .. } + | DataType::BigInt { .. } + | DataType::TinyInt { .. } + ) && (Self::hana_integer(&cast.this).is_none() + || matches!(cast.to, DataType::TinyInt { .. }) + && !Self::hana_integer(&cast.this).is_some_and(|n| (0..=127).contains(&n))) { return Err(self.hana_unsupported( "Integer CAST to HANA requires a verified source conversion; numeric rounding and character conversion rules differ", )); } + Ok(()) + } + + fn generate_cast(&mut self, cast: &Cast) -> Result<()> { + self.validate_cast_to_hana(cast)?; if self.config.dialect != Some(DialectType::HANA) { if let DataType::Hana { hana_type } = &cast.to { if matches!( @@ -18410,6 +18421,12 @@ impl Generator { } } + if self.config.dialect != Some(DialectType::HANA) { + // Some target CAST mappings replace an entire container type with + // CHAR/JSON; validate its leaves before those shortcuts can discard them. + Self::validate_hana_data_type(&cast.to, self.config.dialect.unwrap_or_default())?; + } + use crate::dialects::DialectType; // SingleStore uses :> syntax @@ -19809,9 +19826,20 @@ impl Generator { Ok(mapping) } + #[cfg(feature = "transpile")] + pub(crate) fn validate_hana_source_type( + data_type: &DataType, + target: DialectType, + ) -> Result<()> { + if let DataType::Hana { hana_type } = data_type { + Self::hana_type_mapping(hana_type, target)?; + } + Ok(()) + } + fn validate_hana_data_type(data_type: &DataType, target: DialectType) -> Result<()> { - // Column types are embedded structs, not Expression children. In particular, - // the generic expression walk cannot see HANA types nested inside an ARRAY. + // Validate one complete type before rendering can collapse a container + // to a target fallback such as JSON or NVARCHAR(MAX). let mut pending = Vec::new(); let mut current = data_type; loop { @@ -25064,6 +25092,7 @@ impl Generator { // Type conversion generators fn generate_try_cast(&mut self, cast: &Cast) -> Result<()> { + self.validate_cast_to_hana(cast)?; use crate::dialects::DialectType; // SingleStore uses !:> syntax for try cast @@ -25126,6 +25155,7 @@ impl Generator { } fn generate_safe_cast(&mut self, cast: &Cast) -> Result<()> { + self.validate_cast_to_hana(cast)?; self.write_keyword("SAFE_CAST"); self.write("("); self.generate_expression(&cast.this)?; @@ -27314,6 +27344,14 @@ impl Generator { } fn generate_data_type(&mut self, dt: &DataType) -> Result<()> { + if self.config.dialect != Some(DialectType::HANA) { + Self::validate_hana_data_type(dt, self.config.dialect.unwrap_or_default())?; + } + self.generate_data_type_inner(dt) + } + + // Recursive rendering uses this method so each type is validated only once. + fn generate_data_type_inner(&mut self, dt: &DataType) -> Result<()> { use crate::dialects::DialectType; match dt { @@ -28176,14 +28214,14 @@ impl Generator { // Dialect-specific array syntax match self.config.dialect { Some(DialectType::HANA) => { - self.generate_data_type(element_type)?; + self.generate_data_type_inner(element_type)?; self.write(" ARRAY"); } Some(DialectType::PostgreSQL) | Some(DialectType::Redshift) | Some(DialectType::DuckDB) => { // PostgreSQL uses TYPE[] or TYPE[N] syntax - self.generate_data_type(element_type)?; + self.generate_data_type_inner(element_type)?; if let Some(dim) = dimension { self.write(&format!("[{}]", dim)); } else { @@ -28192,7 +28230,7 @@ impl Generator { } Some(DialectType::BigQuery) => { self.write_keyword("ARRAY<"); - self.generate_data_type(element_type)?; + self.generate_data_type_inner(element_type)?; self.write(">"); } Some(DialectType::Snowflake) @@ -28205,7 +28243,7 @@ impl Generator { } else { self.write_keyword("ARRAY("); } - self.generate_data_type(element_type)?; + self.generate_data_type_inner(element_type)?; self.write(")"); } Some(DialectType::TSQL) @@ -28222,14 +28260,14 @@ impl Generator { _ => { // Default: use angle bracket syntax (ARRAY) self.write_keyword("ARRAY<"); - self.generate_data_type(element_type)?; + self.generate_data_type_inner(element_type)?; self.write(">"); } } } DataType::List { element_type } => { // Materialize: element_type LIST (postfix syntax) - self.generate_data_type(element_type)?; + self.generate_data_type_inner(element_type)?; self.write_keyword(" LIST"); } DataType::Map { @@ -28241,9 +28279,9 @@ impl Generator { Some(DialectType::Materialize) => { // Materialize: MAP[key_type => value_type] self.write_keyword("MAP["); - self.generate_data_type(key_type)?; + self.generate_data_type_inner(key_type)?; self.write(" => "); - self.generate_data_type(value_type)?; + self.generate_data_type_inner(value_type)?; self.write("]"); } Some(DialectType::Snowflake) @@ -28253,9 +28291,9 @@ impl Generator { | Some(DialectType::Trino) | Some(DialectType::Athena) => { self.write_keyword("MAP("); - self.generate_data_type(key_type)?; + self.generate_data_type_inner(key_type)?; self.write(", "); - self.generate_data_type(value_type)?; + self.generate_data_type_inner(value_type)?; self.write(")"); } Some(DialectType::ClickHouse) => { @@ -28264,17 +28302,17 @@ impl Generator { self.write("Map("); let saved_depth = self.clickhouse_nullable_depth; self.clickhouse_nullable_depth = -1; // suppress Nullable for key - self.generate_data_type(key_type)?; + self.generate_data_type_inner(key_type)?; self.clickhouse_nullable_depth = saved_depth; self.write(", "); - self.generate_data_type(value_type)?; + self.generate_data_type_inner(value_type)?; self.write(")"); } _ => { self.write_keyword("MAP<"); - self.generate_data_type(key_type)?; + self.generate_data_type_inner(key_type)?; self.write(", "); - self.generate_data_type(value_type)?; + self.generate_data_type_inner(value_type)?; self.write(">"); } } @@ -28310,7 +28348,7 @@ impl Generator { // Snowflake format: VECTOR(type, dimension) self.write_keyword("VECTOR("); if let Some(ref et) = element_type { - self.generate_data_type(et)?; + self.generate_data_type_inner(et)?; if dimension.is_some() { self.write(", "); } @@ -28329,7 +28367,7 @@ impl Generator { } self.generate_type_field_name(name); self.write(" "); - self.generate_data_type(dt)?; + self.generate_data_type_inner(dt)?; if *not_null { self.write_keyword(" NOT NULL"); } @@ -28354,7 +28392,7 @@ impl Generator { self.generate_type_field_name(&field.name); self.write(" "); } - self.generate_data_type(&field.data_type)?; + self.generate_data_type_inner(&field.data_type)?; } self.write(")"); } @@ -28369,7 +28407,7 @@ impl Generator { self.generate_type_field_name(&field.name); self.write(" "); } - self.generate_data_type(&field.data_type)?; + self.generate_data_type_inner(&field.data_type)?; } self.write(")"); } @@ -28384,7 +28422,7 @@ impl Generator { self.generate_type_field_name(&field.name); self.write(" "); } - self.generate_data_type(&field.data_type)?; + self.generate_data_type_inner(&field.data_type)?; } self.write(")"); } @@ -28399,7 +28437,7 @@ impl Generator { self.generate_type_field_name(&field.name); self.write(" "); } - self.generate_data_type(&field.data_type)?; + self.generate_data_type_inner(&field.data_type)?; } self.write(")"); } @@ -28414,7 +28452,7 @@ impl Generator { self.generate_type_field_name(&field.name); self.write(" "); } - self.generate_data_type(&field.data_type)?; + self.generate_data_type_inner(&field.data_type)?; } self.write(")"); } @@ -28438,7 +28476,7 @@ impl Generator { self.generate_type_field_name(&field.name); self.write(" "); } - self.generate_data_type(&field.data_type)?; + self.generate_data_type_inner(&field.data_type)?; } self.write(")"); } else { @@ -28453,7 +28491,7 @@ impl Generator { self.write(self.config.struct_field_sep); } // For anonymous fields, just output the type - self.generate_data_type(&field.data_type)?; + self.generate_data_type_inner(&field.data_type)?; // Spark/Databricks: Output COMMENT clause if present if let Some(comment) = &field.comment { self.write(" COMMENT '"); @@ -28520,7 +28558,7 @@ impl Generator { self.generate_type_field_name(name); self.write(" "); } - self.generate_data_type(dt)?; + self.generate_data_type_inner(dt)?; } self.write(")"); } @@ -28531,20 +28569,20 @@ impl Generator { // Suppress inner Nullable wrapping to prevent Nullable(Nullable(...)) let saved_depth = self.clickhouse_nullable_depth; self.clickhouse_nullable_depth = -1; - self.generate_data_type(inner)?; + self.generate_data_type_inner(inner)?; self.clickhouse_nullable_depth = saved_depth; self.write(")"); } else { // Map ClickHouse-specific custom type names to standard types match inner.as_ref() { DataType::Custom { name } if name.eq_ignore_ascii_case("DATETIME") => { - self.generate_data_type(&DataType::Timestamp { + self.generate_data_type_inner(&DataType::Timestamp { precision: None, timezone: false, })?; } _ => { - self.generate_data_type(inner)?; + self.generate_data_type_inner(inner)?; } } } diff --git a/crates/polyglot-sql/src/validation.rs b/crates/polyglot-sql/src/validation.rs index 38f17220..051b7f21 100644 --- a/crates/polyglot-sql/src/validation.rs +++ b/crates/polyglot-sql/src/validation.rs @@ -767,7 +767,7 @@ fn data_type_family(data_type: &DataType) -> TypeFamily { TypeFamily::Numeric } DataType::Hana { hana_type } => match hana_type.name.as_str() { - "TINYINT" => TypeFamily::Integer, + "TINYINT" | "SMALLINT" | "INT" | "BIGINT" => TypeFamily::Integer, "TIMESTAMP" | "SECONDDATE" => TypeFamily::Timestamp, "TIME" => TypeFamily::Time, "FLOAT" | "DECIMAL" | "SMALLDECIMAL" => TypeFamily::Numeric, diff --git a/crates/polyglot-sql/src/validation/tests.rs b/crates/polyglot-sql/src/validation/tests.rs index 3952ac70..5061c3ff 100644 --- a/crates/polyglot-sql/src/validation/tests.rs +++ b/crates/polyglot-sql/src/validation/tests.rs @@ -2109,6 +2109,51 @@ fn test_validate_with_schema_type_check_comparison_mismatch() { .any(|e| e.code == validation_codes::E_INCOMPATIBLE_COMPARISON_TYPES)); } +#[cfg(feature = "dialect-hana")] +#[test] +fn hana_integer_casts_participate_in_type_validation() { + let schema = ValidationSchema { + tables: vec![], + strict: Some(true), + }; + let opts = SchemaValidationOptions { + check_types: true, + strict: Some(true), + ..Default::default() + }; + for data_type in ["TINYINT", "SMALLINT", "INT", "INTEGER", "BIGINT"] { + for (sql, code) in [ + ( + format!("SELECT CAST(1 AS {data_type}) + 'x'"), + validation_codes::E_INVALID_ARITHMETIC_TYPE, + ), + ( + format!("SELECT CAST(1 AS {data_type}) = DATE '2024-01-01'"), + validation_codes::E_INCOMPATIBLE_COMPARISON_TYPES, + ), + ( + format!("SELECT LENGTH(CAST(1 AS {data_type}))"), + validation_codes::E_INVALID_FUNCTION_ARGUMENT_TYPE, + ), + ] { + let result = validate_with_schema(&sql, DialectType::HANA, &schema, &opts); + assert!(!result.valid, "{sql}"); + assert!( + result.errors.iter().any(|e| e.code == code), + "{sql}: {result:?}" + ); + } + for sql in [ + format!("SELECT CAST(1 AS {data_type}) + 2"), + format!("SELECT CAST(1 AS {data_type}) = 2"), + format!("SELECT ABS(CAST(1 AS {data_type}))"), + ] { + let result = validate_with_schema(&sql, DialectType::HANA, &schema, &opts); + assert!(result.valid, "{sql}: {result:?}"); + } + } +} + #[test] fn test_validate_with_schema_type_check_arithmetic_mismatch() { let schema = base_schema(); diff --git a/crates/polyglot-sql/tests/dialect_matrix.rs b/crates/polyglot-sql/tests/dialect_matrix.rs index 18d920fd..a6959026 100644 --- a/crates/polyglot-sql/tests/dialect_matrix.rs +++ b/crates/polyglot-sql/tests/dialect_matrix.rs @@ -4994,7 +4994,7 @@ mod hana_regressions { DialectType::PostgreSQL, DialectType::HANA ), - "SELECT CAST(42 AS INT) FROM DUMMY" + "SELECT CAST(42 AS INT) FROM SYS.DUMMY" ); for sql in [ "SELECT CAST(-32768 AS SMALLINT)", @@ -5014,6 +5014,87 @@ mod hana_regressions { } } + #[test] + fn incoming_decimal_casts_require_verified_rounding_and_overflow_semantics() { + for source in [DialectType::PostgreSQL, DialectType::DuckDB] { + for sql in [ + "SELECT CAST(12.349 AS DECIMAL(5, 2))", + "SELECT CAST(-12.349 AS DECIMAL(5, 2))", + "SELECT CAST(999.999 AS DECIMAL(5, 2))", + "SELECT CAST('12.349' AS DECIMAL(5, 2))", + "SELECT CAST(x AS DECIMAL(5, 2)) FROM t", + "SELECT CAST(12.349 AS DECIMAL)", + "SELECT TRY_CAST(12.349 AS DECIMAL(5, 2))", + "SELECT SAFE_CAST(12.349 AS DECIMAL(5, 2))", + ] { + let ast = Dialect::get(source).parse(sql).unwrap(); + let error = Dialect::get(DialectType::HANA) + .generate(&ast[0]) + .unwrap_err(); + assert!( + error.to_string().contains("Decimal CAST to HANA"), + "{sql}: {error}" + ); + for level in [ + UnsupportedLevel::Ignore, + UnsupportedLevel::Warn, + UnsupportedLevel::Raise, + UnsupportedLevel::Immediate, + ] { + let error = + transpile_with_level(sql, source, DialectType::HANA, level).unwrap_err(); + assert!( + error.to_string().contains("Decimal CAST to HANA"), + "{sql}: {error}" + ); + } + } + } + for sql in [ + "SELECT CAST(12.349 AS DECIMAL(5, 2)) FROM t", + "SELECT CAST(-12.349 AS DECIMAL(5, 2)) FROM t", + "SELECT CAST(x AS DECIMAL) FROM t", + ] { + assert_eq!(transpile(sql, DialectType::HANA, DialectType::HANA), sql); + } + assert_eq!( + transpile( + "CREATE TABLE t (x DECIMAL(5, 2))", + DialectType::PostgreSQL, + DialectType::HANA + ), + "CREATE TABLE t (x DECIMAL(5, 2))" + ); + } + + #[test] + fn synthetic_dummy_is_not_captured_by_ctes() { + for (sql, expected) in [ + ( + "WITH DUMMY AS (SELECT x FROM t) SELECT 42", + "WITH DUMMY AS (SELECT x FROM t) SELECT 42 FROM SYS.DUMMY", + ), + ( + r#"WITH "DUMMY" AS (SELECT x FROM t) SELECT 42"#, + r#"WITH "DUMMY" AS (SELECT x FROM t) SELECT 42 FROM SYS.DUMMY"#, + ), + ( + "WITH DUMMY AS (SELECT 7 AS x) SELECT (SELECT 42) FROM DUMMY", + "WITH DUMMY AS (SELECT 7 AS x FROM SYS.DUMMY) SELECT (SELECT 42 FROM SYS.DUMMY) FROM DUMMY", + ), + ( + "WITH DUMMY AS (SELECT x FROM t) SELECT x FROM DUMMY", + "WITH DUMMY AS (SELECT x FROM t) SELECT x FROM DUMMY", + ), + ] { + assert_eq!(transpile(sql, DialectType::PostgreSQL, DialectType::HANA), expected); + let ast = Dialect::get(DialectType::PostgreSQL).parse(sql).unwrap(); + assert_eq!(Dialect::get(DialectType::HANA).generate(&ast[0]).unwrap(), expected); + // Explicit relations, including the injected system relation, survive native generation. + assert_eq!(transpile(expected, DialectType::HANA, DialectType::HANA), expected); + } + } + #[test] fn incoming_string_aggregation_requires_verified_null_semantics() { for sql in [ @@ -5379,7 +5460,7 @@ mod hana_regressions { fn incoming_queries_generate_native_syntax_or_report_unsupported() { assert_eq!( transpile("SELECT 1", DialectType::Generic, DialectType::HANA), - "SELECT 1 FROM DUMMY" + "SELECT 1 FROM SYS.DUMMY" ); for (sql, source) in [ ("SELECT SUBSTRING('abcdef', -2, 2)", DialectType::DuckDB), @@ -5399,7 +5480,7 @@ mod hana_regressions { fn source_casts_retain_conversion_semantics() { assert_eq!( transpile("SELECT UNKNOWN", DialectType::HANA, DialectType::HANA), - "SELECT NULL FROM DUMMY" + "SELECT NULL FROM SYS.DUMMY" ); assert_eq!( transpile("SELECT UNKNOWN", DialectType::HANA, DialectType::DuckDB), @@ -5568,6 +5649,11 @@ mod hana_regressions { "SELECT TO_TIMESTAMP(s, 'YYYY-MM-DD HH24:MI:SS.FF7') FROM t", "SELECT CAST(x AS SMALLDECIMAL) FROM t", "CREATE TABLE t (x SMALLDECIMAL ARRAY)", + "ALTER TABLE t ADD (x SMALLDECIMAL ARRAY)", + "ALTER TABLE t ADD x SMALLDECIMAL ARRAY", + "ALTER TABLE t ALTER COLUMN x TYPE SMALLDECIMAL ARRAY", + "SELECT CAST(xs AS SMALLDECIMAL ARRAY) FROM t", + "CREATE FUNCTION f(x SMALLDECIMAL ARRAY) RETURNS INT AS 1", "SELECT ADD_MONTHS_LAST(d, 1) FROM t", "SELECT * FROM t WITH HINT (NO_INLINE)", "SELECT * FROM t FOR UPDATE IGNORE LOCKED", From 8e4d7ec9d3063b0e400ba9d49f77e3a1c25608e0 Mon Sep 17 00:00:00 2001 From: tobilg Date: Wed, 23 Sep 2026 17:35:26 +0200 Subject: [PATCH 8/8] Fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39aecf23..647bbf29 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Release notes are tracked in [`CHANGELOG.md`](CHANGELOG.md). | MySQL | Oracle | PostgreSQL | Presto | Redshift | | RisingWave | SingleStore | Snowflake | Solr | Spark | | SQLite | StarRocks | Tableau | Teradata | TiDB | -| Trino | TSQL | DataFusion | Generic SQL | [SAP HANA](docs/hana.md) | +| Trino | TSQL | DataFusion | SAP HANA | Generic SQL | ## Quick Start