diff --git a/sidemantic-rs/src/core/mod.rs b/sidemantic-rs/src/core/mod.rs index b06202f11..187c12a5c 100644 --- a/sidemantic-rs/src/core/mod.rs +++ b/sidemantic-rs/src/core/mod.rs @@ -34,6 +34,7 @@ pub(crate) use preaggregation::{ materialization_sql as preaggregation_materialization_sql, replace_model_placeholder, source_expression as preaggregation_source_expression, }; +pub(crate) use relative_date::bigquery_trunc_part; pub use relative_date::RelativeDate; pub use segment::Segment; pub use symmetric_agg::{ diff --git a/sidemantic-rs/src/core/relative_date.rs b/sidemantic-rs/src/core/relative_date.rs index 2638deb03..50d030b8a 100644 --- a/sidemantic-rs/src/core/relative_date.rs +++ b/sidemantic-rs/src/core/relative_date.rs @@ -5,6 +5,17 @@ use lazy_static::lazy_static; use regex::Regex; +/// BigQuery date part for a grain; weeks start Monday as in the other dialects. +pub(crate) fn bigquery_trunc_part(granularity: &str) -> String { + let part = granularity.to_ascii_uppercase(); + // BigQuery's bare WEEK starts on Sunday. + if part == "WEEK" { + "WEEK(MONDAY)".to_string() + } else { + part + } +} + /// Relative date expression parser pub struct RelativeDate; diff --git a/sidemantic-rs/src/runtime.rs b/sidemantic-rs/src/runtime.rs index 08bc44444..c623f1e07 100644 --- a/sidemantic-rs/src/runtime.rs +++ b/sidemantic-rs/src/runtime.rs @@ -4611,7 +4611,10 @@ pub fn validate_table_formula_expression(expression: &str) -> Result { fn relative_date_trunc(granularity: &str, dialect: &str) -> String { if dialect.eq_ignore_ascii_case("bigquery") { - format!("DATE_TRUNC(CURRENT_DATE, {})", granularity.to_uppercase()) + format!( + "DATE_TRUNC(CURRENT_DATE, {})", + crate::core::bigquery_trunc_part(granularity) + ) } else { format!("DATE_TRUNC('{granularity}', CURRENT_DATE)") } @@ -6704,6 +6707,10 @@ type: percent_of_total parse_relative_date("this month", "bigquery"), Some("DATE_TRUNC(CURRENT_DATE, MONTH)".to_string()) ); + assert_eq!( + parse_relative_date("this week", "bigquery"), + Some("DATE_TRUNC(CURRENT_DATE, WEEK(MONDAY))".to_string()) + ); let range = relative_date_to_range("this month", "order_date", "duckdb").unwrap(); assert!(range.contains("order_date >= DATE_TRUNC('month', CURRENT_DATE)")); diff --git a/sidemantic-rs/src/sql/generator.rs b/sidemantic-rs/src/sql/generator.rs index 3333bfcd4..ea17468a8 100644 --- a/sidemantic-rs/src/sql/generator.rs +++ b/sidemantic-rs/src/sql/generator.rs @@ -4178,7 +4178,7 @@ impl<'a> SqlGenerator<'a> { Ok(format!( "DATE_TRUNC({}, {})", column_expr, - granularity.to_ascii_uppercase() + crate::core::bigquery_trunc_part(granularity) )) } else if matches!(self.dialect, DialectType::Spark | DialectType::Databricks) { let grain = granularity.to_ascii_uppercase(); diff --git a/sidemantic/core/relative_date.py b/sidemantic/core/relative_date.py index cd10071e5..b9cea6578 100644 --- a/sidemantic/core/relative_date.py +++ b/sidemantic/core/relative_date.py @@ -3,10 +3,17 @@ import re +def bigquery_trunc_part(granularity: str) -> str: + """BigQuery date part for a grain; weeks start Monday as in the other dialects.""" + part = granularity.upper() + # BigQuery's bare WEEK starts on Sunday. + return "WEEK(MONDAY)" if part == "WEEK" else part + + def _date_trunc(granularity: str, column_expr: str, dialect: str) -> str: """Generate dialect-specific DATE_TRUNC expression.""" if dialect == "bigquery": - return f"DATE_TRUNC({column_expr}, {granularity.upper()})" + return f"DATE_TRUNC({column_expr}, {bigquery_trunc_part(granularity)})" else: return f"DATE_TRUNC('{granularity}', {column_expr})" diff --git a/sidemantic/sql/generator.py b/sidemantic/sql/generator.py index d815ff0a8..ed2fcf842 100644 --- a/sidemantic/sql/generator.py +++ b/sidemantic/sql/generator.py @@ -12,6 +12,7 @@ from sqlglot.errors import SqlglotError from sidemantic.core.preagg_matcher import PreAggregationMatcher +from sidemantic.core.relative_date import bigquery_trunc_part from sidemantic.core.semantic_graph import SemanticGraph, _relationship_local_key_columns from sidemantic.core.symmetric_aggregate import build_symmetric_aggregate_sql from sidemantic.sql.aggregation_detection import sql_has_aggregate @@ -737,7 +738,7 @@ def _date_trunc(self, granularity: str, column_expr: str) -> str: column_expr = self._localize_to_timezone(column_expr) if self.dialect == "bigquery": - return f"DATE_TRUNC({column_expr}, {granularity.upper()})" + return f"DATE_TRUNC({column_expr}, {bigquery_trunc_part(granularity)})" if self.dialect in {"spark", "databricks"}: spark_granularity = granularity.upper() diff --git a/tests/dates/test_relative_dates.py b/tests/dates/test_relative_dates.py index bac430963..b4cb5b85e 100644 --- a/tests/dates/test_relative_dates.py +++ b/tests/dates/test_relative_dates.py @@ -105,7 +105,7 @@ def test_bigquery_dialect(): """Test BigQuery dialect generates correct DATE_TRUNC syntax.""" # BigQuery uses DATE_TRUNC(column, MONTH) not DATE_TRUNC('month', column) assert RelativeDateRange.parse("this month", dialect="bigquery") == "DATE_TRUNC(CURRENT_DATE, MONTH)" - assert RelativeDateRange.parse("this week", dialect="bigquery") == "DATE_TRUNC(CURRENT_DATE, WEEK)" + assert RelativeDateRange.parse("this week", dialect="bigquery") == "DATE_TRUNC(CURRENT_DATE, WEEK(MONDAY))" assert RelativeDateRange.parse("this year", dialect="bigquery") == "DATE_TRUNC(CURRENT_DATE, YEAR)" assert ( RelativeDateRange.parse("last month", dialect="bigquery") diff --git a/tests/queries/test_basic.py b/tests/queries/test_basic.py index 8fe736e6d..fb62d7909 100644 --- a/tests/queries/test_basic.py +++ b/tests/queries/test_basic.py @@ -116,6 +116,27 @@ def test_time_dimension_bigquery_dialect(layer): assert "DATE_TRUNC('month'" not in sql, f"Should not have PostgreSQL syntax. Got: {sql}" +def test_time_dimension_bigquery_week_starts_monday(layer): + """BigQuery's bare WEEK starts Sunday; week buckets must match the Monday weeks of other dialects.""" + orders = Model( + name="orders", + table="orders_table", + primary_key="order_id", + dimensions=[Dimension(name="created_at", type="time", sql="created_at", granularity="day")], + metrics=[Metric(name="revenue", agg="sum", sql="amount")], + ) + layer.add_model(orders) + + sql = layer.compile(metrics=["orders.revenue"], dimensions=["orders.created_at__week"], dialect="bigquery") + + assert "DATE_TRUNC(created_at, WEEK(MONDAY))" in sql, f"Expected Monday-start BigQuery weeks. Got: {sql}" + # Sunday 2023-12-31 belongs to the week starting Monday 2023-12-25, as in DuckDB. + bucket = sqlglot.parse_one("SELECT CAST(DATE_TRUNC(DATE '2023-12-31', WEEK(MONDAY)) AS DATE)", read="bigquery").sql( + dialect="duckdb" + ) + assert duckdb.sql(bucket).fetchone()[0] == date(2023, 12, 25) + + def test_time_dimension_duckdb_dialect(layer): """Test that time dimensions generate correct DuckDB DATE_TRUNC syntax.""" orders = Model( diff --git a/tests/queries/yardstick_replay_runtime.py b/tests/queries/yardstick_replay_runtime.py index e1c7b530c..d9e1c481d 100644 --- a/tests/queries/yardstick_replay_runtime.py +++ b/tests/queries/yardstick_replay_runtime.py @@ -30,6 +30,11 @@ class ReplayStatement: has_aggregate: bool +def _drop_target(drop: exp.Drop) -> exp.Table: + # sqlglot >= 30.23 parses DROP targets into `tables`; earlier versions use `this`. + return drop.this or drop.args["tables"][0] + + def split_replay_sql(sql: str, dialect: str) -> list[str]: """Split SQLLogicTest batches without splitting comments or quoted literals.""" tokens = sqlglot.tokenize(sql, read=dialect) @@ -187,12 +192,12 @@ def execute(self, sql: str) -> list[tuple]: self._install_models() continue if isinstance(parsed, exp.Drop) and str(parsed.args.get("kind", "")).upper() == "VIEW": - table = parsed.this + table = _drop_target(parsed) name = table.name.lower() if table.db.lower() == "main" and not table.catalog: drop = parsed.copy() catalog = self.layer.adapter.execute("SELECT current_database()").fetchone()[0] - drop.this.set("catalog", exp.to_identifier(catalog, quoted=True)) + _drop_target(drop).set("catalog", exp.to_identifier(catalog, quoted=True)) self._execute(drop.sql(dialect=self.adapter.dialect)) else: self._execute(statement.sql) @@ -237,8 +242,8 @@ def execute(self, sql: str) -> list[tuple]: remaining_uses = used_temporary.copy() for remaining in statements[statement_index:]: remaining_uses.update(self._temporary_reads(remaining, pending_temporary)) - if isinstance(remaining.parsed, exp.Drop) and not remaining.parsed.this.db: - remaining_uses.add(remaining.parsed.this.name.lower()) + if isinstance(remaining.parsed, exp.Drop) and not _drop_target(remaining.parsed).db: + remaining_uses.add(_drop_target(remaining.parsed).name.lower()) if pending_temporary - remaining_uses: raise RuntimeError( "TEMPORARY AS MEASURE views must be used in the same statement batch as AGGREGATE()" diff --git a/uv.lock b/uv.lock index 57102bcb4..fd5cf4c1f 100644 --- a/uv.lock +++ b/uv.lock @@ -3914,11 +3914,11 @@ wheels = [ [[package]] name = "sqlglot" -version = "30.1.0" +version = "30.23.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/ae/afee950eff42a9c8ceab4a2e25abfeaa8278c578f967201824287cf530ce/sqlglot-30.1.0.tar.gz", hash = "sha256:7593aea85349c577b269d540ba245024f91464afdcf61c6ef7765f4691c46ef8", size = 5812093, upload-time = "2026-03-26T19:25:45.065Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/40/4afe7d21cdf3dbb5a7529ea33a0e07055081fb3d37bc0550e7c2278d6ec0/sqlglot-30.23.0.tar.gz", hash = "sha256:34b5b62fa4cbf042ee6b9e829236577b2f8db4538dd20007de2aa5383c92e845", size = 6108071, upload-time = "2026-10-14T21:48:38.209Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/31/f1cad1972a8eb4b1a9bc904e4a8d440af1eef064160fe10ba0ae81f4693f/sqlglot-30.1.0-py3-none-any.whl", hash = "sha256:6c2d58d0cc68b5f96900058e8866ef4959f89f9e66e4096e0ba746830dda4f40", size = 665823, upload-time = "2026-03-26T19:25:42.794Z" }, + { url = "https://files.pythonhosted.org/packages/2d/73/9e749f3e57ca471bf663eb6d51fbe79b9921c5b7376706cd1cac999c8e2e/sqlglot-30.23.0-py3-none-any.whl", hash = "sha256:b5a645722cb4c6b649e9131b94830d9df9a557e87be63713179d848320f2baa1", size = 783709, upload-time = "2026-10-14T21:48:36.327Z" }, ] [package.optional-dependencies] @@ -3928,26 +3928,33 @@ c = [ [[package]] name = "sqlglotc" -version = "30.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b4/53/abd9c353be84baca2272027e274c916786dc99abec3a5cefcd7295670f49/sqlglotc-30.1.0.tar.gz", hash = "sha256:c1e3ca25b0f9f81977862956fbb38dcf7e9f7bf00082ae123ff8d5c93ddec520", size = 433098, upload-time = "2026-03-26T19:24:43.676Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/47/f4bc1d4a854521b6942e15c7418f087a6c2ddd02ca8f7a663ecbda281193/sqlglotc-30.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aed0e1e5cf1c0cd09bb4d2c89738e2e5da76a07b46e62695e9b4c97843c21044", size = 17666122, upload-time = "2026-03-26T19:24:05.868Z" }, - { url = "https://files.pythonhosted.org/packages/87/28/f1d637e2a02887f0f1e8a5cbaf46e17b096109bbc53598fd44cb69511ad5/sqlglotc-30.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:787bc5860424955aa2c7ff3d1a041faacc85e3b048ede83fb5c470b0fefa68b3", size = 11761274, upload-time = "2026-03-26T19:24:07.881Z" }, - { url = "https://files.pythonhosted.org/packages/d8/d0/3ca532e921f4b0bb45e159fcff0c99ac8a60b2e1440db9dad2afb24c4c78/sqlglotc-30.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b0b0ddfe2033af693ddf2e2f979e37fa7949a2f282b06ade985328470c899fd", size = 12338512, upload-time = "2026-03-26T19:24:09.905Z" }, - { url = "https://files.pythonhosted.org/packages/46/12/5faae564487186af2e0f76d5f07b1d779a23c0236349708a1054031c03ad/sqlglotc-30.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a25690f97103687b1ac36576ba677e6ea169c1092bb23670a411d789acecd6a", size = 7720318, upload-time = "2026-03-26T19:24:11.903Z" }, - { url = "https://files.pythonhosted.org/packages/8f/7a/0250322354b18c2e5fba84017d4c3f0c97d27d216786742379775aa9a5d7/sqlglotc-30.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:07fe6a1ae40c42d9b3f00531f93798c2bb3168c01a32d6ed61952207f24b53de", size = 17735285, upload-time = "2026-03-26T19:24:13.573Z" }, - { url = "https://files.pythonhosted.org/packages/1c/1c/271ec81c35a0a966508e8d2c1d81396e8f41eb4c5746905421cfde5fd83a/sqlglotc-30.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dac443012ae7866505d40752005a11a861ad1ef942fdc093abad51d45b86f48b", size = 12407907, upload-time = "2026-03-26T19:24:15.647Z" }, - { url = "https://files.pythonhosted.org/packages/27/6d/6bdb1982b6c8cb35095b39e39320bdedc3888d4df2da18b5b244d86a7ab6/sqlglotc-30.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c6919cae44dd21f476444ec851e3bf9579801740401b394e77a1d0e6fc6e22cb", size = 12954625, upload-time = "2026-03-26T19:24:17.452Z" }, - { url = "https://files.pythonhosted.org/packages/4d/0d/036be5ca7c613864241bbe375f0cd6fdb4d58ef2c16343fb14de7a85b518/sqlglotc-30.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:471550fe9725af978129bb37161e48f16bac7659afe2df65b153cd84376d422c", size = 7930443, upload-time = "2026-03-26T19:24:19.074Z" }, - { url = "https://files.pythonhosted.org/packages/7d/be/6befe0a641bfd2698e2552723a4b502b5bad67a80ba87dfa1da4cf968fc9/sqlglotc-30.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:91deaabad97680ab69d02e9878bd82bc3cabbc1709ab2f5fa5fb19a7b29e8521", size = 17671102, upload-time = "2026-03-26T19:24:20.586Z" }, - { url = "https://files.pythonhosted.org/packages/f9/fa/74d938a0f3a3975ab8e2934ea0a958f16c4444bf65f2ac268c74b34b533b/sqlglotc-30.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75db34b844abdc308015893950828a3c38362009ca6d0dd4a7ab41bc7ab83570", size = 12306463, upload-time = "2026-03-26T19:24:22.739Z" }, - { url = "https://files.pythonhosted.org/packages/7d/59/0fe37835dba5a6eac6193e886c73bfbe20e78a71bae933c7ccf39ffd5c1d/sqlglotc-30.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:040a8540be799688837a8912b05557531952a27747c7bd612e341dff01979118", size = 12871619, upload-time = "2026-03-26T19:24:24.94Z" }, - { url = "https://files.pythonhosted.org/packages/b1/0e/0abdcb2f90bf670431454d041a5ba0d8e656a71be261d1e2fb959c35b96e/sqlglotc-30.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:ca8444caea04c6b817cf8ce039f1c9f429fe358ea81c50e6dd710cf2a9167648", size = 7938367, upload-time = "2026-03-26T19:24:27.421Z" }, - { url = "https://files.pythonhosted.org/packages/c4/52/a7885f87212444372ea0fa4e7db4170169237f0b801df411b41e4d10d563/sqlglotc-30.1.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:83dd3106320f1ce2b94866be0ea32c4bde2528f391ef0247ee80cb5fd7e30cb8", size = 17600245, upload-time = "2026-03-26T19:24:28.879Z" }, - { url = "https://files.pythonhosted.org/packages/25/08/253a66baf42563eb72de33a8d32f08ac41404fda5d3c51eb9d355bf55d23/sqlglotc-30.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:159d1dff253606af9bb15d198cd7f65b7d77924785f0b53c16239a8c261cc318", size = 12297805, upload-time = "2026-03-26T19:24:30.688Z" }, - { url = "https://files.pythonhosted.org/packages/5a/22/e491682a25fb389e528754c0cc1fe09bf94ea4d78538ac49c52de3e266aa/sqlglotc-30.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3182a183fbf3e205cd50d0ed038302e2cd2abd60e6ba0eaf9c909c455e495146", size = 12829341, upload-time = "2026-03-26T19:24:33.264Z" }, - { url = "https://files.pythonhosted.org/packages/48/c9/e25794baa777575f130b35486e814884996e6889581c7e9fd4264f2b6e05/sqlglotc-30.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:1e7a6cbf0b15d8859e9865cf97f2bf9f9a09e53d03f2e0718df560d132f7eacb", size = 8102173, upload-time = "2026-03-26T19:24:34.945Z" }, +version = "30.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sqlglot" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/80/0666464e3b84df07790fb01841f21b1cdebefddcb6cae0b584ec69afb3f6/sqlglotc-30.23.0.tar.gz", hash = "sha256:637db97dae72631f1658a74d94aa244c7dafe3853d4d58ca8769935d1b10b28a", size = 536542, upload-time = "2026-10-14T21:47:43.187Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/fc/429c5d33b8f1b7a3c7b31fb3d1a23cd16c38fb080f833266811f0d5a6e51/sqlglotc-30.23.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:67aba90ed41d3d74c6cc5260e473b0c3aab6b868f9aa78f3f77fcdabb433a082", size = 33753766, upload-time = "2026-10-14T20:39:19.368Z" }, + { url = "https://files.pythonhosted.org/packages/cc/86/75213a0a2a7f7e07dd2fd85e3e9bb83a68e69bacfb107491cdc12e83b437/sqlglotc-30.23.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36da6056e27034ec82bf929264386949d5eb51ddb6e5f828d7161a9f1f64eeaf", size = 26278472, upload-time = "2026-10-14T20:39:23.643Z" }, + { url = "https://files.pythonhosted.org/packages/06/64/03632ca8c702af6073d95c4728d7b87878a90dfc2bdc79f768ce4e4587d8/sqlglotc-30.23.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:650d644f63812fe91d1071ec9815148df2bb52ef4d9d47d0e70a468d00de8e5d", size = 27519427, upload-time = "2026-10-14T20:39:26.937Z" }, + { url = "https://files.pythonhosted.org/packages/f0/9f/b5352fb02d0ac90e8b4387115e0d60844754f08f8b4c95cac9eead814fd8/sqlglotc-30.23.0-cp311-cp311-win_amd64.whl", hash = "sha256:2b404ec21908832183c279b933c2979c7ad3ebcad552409aa5f6f79a18fbad33", size = 11320941, upload-time = "2026-10-14T20:39:29.474Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b7/e9c6c5c152245587eef3b5750f1f6b32099c6bf63fc0687524dfef08230f/sqlglotc-30.23.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7967559bf24dc0ba60540daa58061785836ff94e289d0e8ec24f1fa72b2ea019", size = 34039791, upload-time = "2026-10-14T20:39:32.598Z" }, + { url = "https://files.pythonhosted.org/packages/00/0b/6ca23751e02f5d99dcb8a4091fc3635fa6f5ea192fb447c4cd08cf0a13a4/sqlglotc-30.23.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48c7e8624a0d11ac2ca8bbae11af591464eb636d643ed770811fbb1e5ab98b1b", size = 27221048, upload-time = "2026-10-14T21:46:57.36Z" }, + { url = "https://files.pythonhosted.org/packages/6f/23/2928c7a4cb0fa2196e426dd1ca7d1c8776d0d405f1e78ebc8f7330dcb385/sqlglotc-30.23.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:65dd497c42eeb97a91a429109a302f51c0ceedf57aeeb59e4b368465cf65dd56", size = 28626089, upload-time = "2026-10-14T21:47:00.571Z" }, + { url = "https://files.pythonhosted.org/packages/27/8e/353484c53c19651b2d54e391edf2de4e29b836a0a536319ab3d040c07f14/sqlglotc-30.23.0-cp312-cp312-win_amd64.whl", hash = "sha256:b795d34e066f22eb4c6a1e9740b80ed3b508bd0a0ca53511bc37de6a33fcd4f1", size = 11544291, upload-time = "2026-10-14T21:47:03.31Z" }, + { url = "https://files.pythonhosted.org/packages/e3/13/7578c015f235808227b1cfed69f484be592c6f76e85ee145d062bfbb614d/sqlglotc-30.23.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:eeb558ec3d8eacc4091d6d95a07352826da01d864fde909b27ddadcc4b9a8de2", size = 33473107, upload-time = "2026-10-14T21:47:06.266Z" }, + { url = "https://files.pythonhosted.org/packages/d9/26/fb755af670d8c421b5638e8d8dac044a57f708dd05813876cfc41f5c4c34/sqlglotc-30.23.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7604bd79957f3f2d0633ed7181145ced13ff1b629461bfd5b630de93c5248b9a", size = 26856960, upload-time = "2026-10-14T21:47:09.313Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ed/fb356fb38a364653488e7c41620e141f92f0d9a659b71e3145a280340474/sqlglotc-30.23.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b0ffb3c8e40a664b8365eff57abaf117638eddf642e0de1040320c236081308e", size = 28249955, upload-time = "2026-10-14T21:47:12.768Z" }, + { url = "https://files.pythonhosted.org/packages/2a/27/18733930bbc4ff0ef154257e9b47e282d9a0b63ad4aeb8176eabbaeb0bcb/sqlglotc-30.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:2a4d05ba5341baf6b6bef8975270404fb34b64af7e63a7f138be8c99c17dfc33", size = 11555612, upload-time = "2026-10-14T21:47:15.54Z" }, + { url = "https://files.pythonhosted.org/packages/0a/28/2a72a2099b98a5bb83b9ce3a4cc15f312ffdf553ce69400bc4820e5c5dc5/sqlglotc-30.23.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:bf81fa991f4b0306309a8bd768a3e685883e0329f9308489dff6bbf71d3adf0c", size = 33377654, upload-time = "2026-10-14T21:47:18.707Z" }, + { url = "https://files.pythonhosted.org/packages/5a/b0/c48bd48737b33e954c764c6350de8e257bb2027395aa904fd66f08cefea0/sqlglotc-30.23.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1435425c4d1b936e1912db7f86874bb16421d90ae6211148df851242c924dd3e", size = 26839514, upload-time = "2026-10-14T21:47:22.314Z" }, + { url = "https://files.pythonhosted.org/packages/0a/94/f98665c30949076673ea5e8c2cb881ef5cb4acafa1bfe37716724ce56b90/sqlglotc-30.23.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cfb91a2598bd803eecf2ac69014cfdbee605b86a957ee5bc7e92e391a403eba2", size = 28131052, upload-time = "2026-10-14T21:47:25.775Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b9/925681b4cc836844f11b48424a74f36e8e8792703269d18034514034bef2/sqlglotc-30.23.0-cp314-cp314-win_amd64.whl", hash = "sha256:351678192d57ae292a57ebc63a7b22329ab16c3647a104539377f493445f7817", size = 11706547, upload-time = "2026-10-14T21:47:28.438Z" }, + { url = "https://files.pythonhosted.org/packages/47/d7/349518428af9aeda0c4b93a6d8bd8e30f2ff576ce1230f1886073120f86d/sqlglotc-30.23.0-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:d10f9610ad420630d7053905f5a30cfc8ac0325cafc793b328e33563510dabee", size = 33347187, upload-time = "2026-10-14T21:47:31.873Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0a/a43fa5f13ac6634eb89d28871a3d5a01875bfba34a5659d046e892d7e8aa/sqlglotc-30.23.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba1309527bd4e3248b45daa3d82aff568f360f3c88fe72143c116520433d206d", size = 26916973, upload-time = "2026-10-14T21:47:34.937Z" }, + { url = "https://files.pythonhosted.org/packages/b2/88/f71361dc504c473776d28a121f68b83de80ebbd786eaa1af25c3f4655820/sqlglotc-30.23.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:842a76c63f26c2d730fe9a1d28cf0a477aefa29c37390788216966f1f844aef1", size = 28110377, upload-time = "2026-10-14T21:47:38.15Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f4/3209bd71d16479db525c7d672301d2a048e5617e370055b4837901696e02/sqlglotc-30.23.0-cp315-cp315-win_amd64.whl", hash = "sha256:80c48bc9d79ee12b9999ff30723b1ff5bf829c514e8b67a4c80d961912bfe90a", size = 11706505, upload-time = "2026-10-14T21:47:41.026Z" }, ] [[package]]