sqlglotc 30.3.0__tar.gz → 30.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/PKG-INFO +1 -1
  2. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generator.py +11 -0
  3. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/duckdb.py +49 -0
  4. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/snowflake.py +1 -0
  5. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parser.py +5 -1
  6. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/PKG-INFO +1 -1
  7. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/MANIFEST.in +0 -0
  8. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/pyproject.toml +0 -0
  9. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/setup.cfg +0 -0
  10. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/setup.py +0 -0
  11. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/errors.py +0 -0
  12. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/executor/table.py +0 -0
  13. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/aggregate.py +0 -0
  14. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/array.py +0 -0
  15. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/builders.py +0 -0
  16. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/constraints.py +0 -0
  17. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/core.py +0 -0
  18. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/datatypes.py +0 -0
  19. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/ddl.py +0 -0
  20. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/dml.py +0 -0
  21. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/functions.py +0 -0
  22. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/json.py +0 -0
  23. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/math.py +0 -0
  24. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/properties.py +0 -0
  25. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/query.py +0 -0
  26. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/string.py +0 -0
  27. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/expressions/temporal.py +0 -0
  28. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/athena.py +0 -0
  29. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/bigquery.py +0 -0
  30. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/clickhouse.py +0 -0
  31. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/databricks.py +0 -0
  32. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/doris.py +0 -0
  33. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/dremio.py +0 -0
  34. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/drill.py +0 -0
  35. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/druid.py +0 -0
  36. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/dune.py +0 -0
  37. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/exasol.py +0 -0
  38. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/fabric.py +0 -0
  39. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/hive.py +0 -0
  40. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/materialize.py +0 -0
  41. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/mysql.py +0 -0
  42. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/oracle.py +0 -0
  43. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/postgres.py +0 -0
  44. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/presto.py +0 -0
  45. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/prql.py +0 -0
  46. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/redshift.py +0 -0
  47. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/risingwave.py +0 -0
  48. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/singlestore.py +0 -0
  49. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/solr.py +0 -0
  50. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/spark.py +0 -0
  51. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/spark2.py +0 -0
  52. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/sqlite.py +0 -0
  53. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/starrocks.py +0 -0
  54. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/tableau.py +0 -0
  55. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/teradata.py +0 -0
  56. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/trino.py +0 -0
  57. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/generators/tsql.py +0 -0
  58. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/helper.py +0 -0
  59. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/annotate_types.py +0 -0
  60. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/isolate_table_selects.py +0 -0
  61. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/normalize_identifiers.py +0 -0
  62. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/qualify.py +0 -0
  63. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/qualify_columns.py +0 -0
  64. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/qualify_tables.py +0 -0
  65. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/resolver.py +0 -0
  66. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/scope.py +0 -0
  67. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/optimizer/simplify.py +0 -0
  68. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/athena.py +0 -0
  69. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/base.py +0 -0
  70. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/bigquery.py +0 -0
  71. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/clickhouse.py +0 -0
  72. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/databricks.py +0 -0
  73. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/doris.py +0 -0
  74. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/dremio.py +0 -0
  75. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/drill.py +0 -0
  76. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/druid.py +0 -0
  77. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/duckdb.py +0 -0
  78. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/dune.py +0 -0
  79. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/exasol.py +0 -0
  80. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/fabric.py +0 -0
  81. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/hive.py +0 -0
  82. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/materialize.py +0 -0
  83. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/mysql.py +0 -0
  84. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/oracle.py +0 -0
  85. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/postgres.py +0 -0
  86. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/presto.py +0 -0
  87. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/prql.py +0 -0
  88. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/redshift.py +0 -0
  89. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/risingwave.py +0 -0
  90. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/singlestore.py +0 -0
  91. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/snowflake.py +0 -0
  92. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/solr.py +0 -0
  93. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/spark.py +0 -0
  94. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/spark2.py +0 -0
  95. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/sqlite.py +0 -0
  96. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/starrocks.py +0 -0
  97. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/tableau.py +0 -0
  98. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/teradata.py +0 -0
  99. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/trino.py +0 -0
  100. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/parsers/tsql.py +0 -0
  101. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/schema.py +0 -0
  102. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/serde.py +0 -0
  103. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/time.py +0 -0
  104. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/tokenizer_core.py +0 -0
  105. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglot/trie.py +0 -0
  106. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/SOURCES.txt +0 -0
  107. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/dependency_links.txt +0 -0
  108. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/requires.txt +0 -0
  109. {sqlglotc-30.3.0 → sqlglotc-30.4.0}/sqlglotc.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglotc
3
- Version: 30.3.0
3
+ Version: 30.4.0
4
4
  Summary: mypyc-compiled extensions for sqlglot
5
5
  Author-email: Toby Mao <toby.mao@gmail.com>
6
6
  License-Expression: MIT
@@ -3416,6 +3416,17 @@ class Generator:
3416
3416
  return self.func("CONCAT", *expressions)
3417
3417
 
3418
3418
  def concatws_sql(self, expression: exp.ConcatWs) -> str:
3419
+ if self.dialect.CONCAT_COALESCE and not expression.args.get("coalesce"):
3420
+ # Dialect's CONCAT_WS function coalesces NULLs to empty strings, but the expression does not.
3421
+ # Wrap the entire call in a CASE expression that returns NULL if any input IS NULL.
3422
+ all_args = expression.expressions
3423
+ expression.set("coalesce", True)
3424
+ return self.sql(
3425
+ exp.case()
3426
+ .when(exp.or_(*(arg.is_(exp.null()) for arg in all_args)), exp.null())
3427
+ .else_(expression)
3428
+ )
3429
+
3419
3430
  return self.func(
3420
3431
  "CONCAT_WS", seq_get(expression.expressions, 0), *self.convert_concat_args(expression)
3421
3432
  )
@@ -82,6 +82,13 @@ WEEK_START_DAY_TO_DOW = {
82
82
 
83
83
  MAX_BIT_POSITION = exp.Literal.number(32768)
84
84
 
85
+ # cs/as/ps are Snowflake defaults; DuckDB already behaves the same way, so they are safe to drop.
86
+ # Note: "as" is also a reserved keyword in DuckDB, making it impossible to pass through.
87
+ _SNOWFLAKE_COLLATION_DEFAULTS = frozenset({"cs", "as", "ps"})
88
+ _SNOWFLAKE_COLLATION_UNSUPPORTED = frozenset(
89
+ {"ci", "ai", "upper", "lower", "utf8", "bin", "pi", "fl", "fu", "trim", "ltrim", "rtrim"}
90
+ )
91
+
85
92
  # Window functions that support IGNORE/RESPECT NULLS in DuckDB
86
93
  _IGNORE_RESPECT_NULLS_WINDOW_FUNCTIONS = (
87
94
  exp.FirstValue,
@@ -2997,6 +3004,30 @@ class DuckDBGenerator(generator.Generator):
2997
3004
  self.unsupported("COLLATION function is not supported by DuckDB")
2998
3005
  return self.function_fallback_sql(expression)
2999
3006
 
3007
+ def collate_sql(self, expression: exp.Collate) -> str:
3008
+ if not expression.expression.is_string:
3009
+ return super().collate_sql(expression)
3010
+
3011
+ raw = expression.expression.name
3012
+ if not raw:
3013
+ return self.sql(expression.this)
3014
+
3015
+ parts = []
3016
+ for part in raw.split("-"):
3017
+ lower = part.lower()
3018
+ if lower not in _SNOWFLAKE_COLLATION_DEFAULTS:
3019
+ if lower in _SNOWFLAKE_COLLATION_UNSUPPORTED:
3020
+ self.unsupported(
3021
+ f"Snowflake collation specifier '{part}' has no DuckDB equivalent"
3022
+ )
3023
+ parts.append(lower)
3024
+
3025
+ if not parts:
3026
+ return self.sql(expression.this)
3027
+ return super().collate_sql(
3028
+ exp.Collate(this=expression.this, expression=exp.var(".".join(parts)))
3029
+ )
3030
+
3000
3031
  def _validate_regexp_flags(self, flags: exp.Expr | None, supported_flags: str) -> str | None:
3001
3032
  """
3002
3033
  Validate and filter regexp flags for DuckDB compatibility.
@@ -3362,6 +3393,9 @@ class DuckDBGenerator(generator.Generator):
3362
3393
  def right_sql(self, expression: exp.Right) -> str:
3363
3394
  return self._left_right_sql(expression, "RIGHT")
3364
3395
 
3396
+ def rtrimmedlength_sql(self, expression: exp.RtrimmedLength) -> str:
3397
+ return self.func("LENGTH", exp.Trim(this=expression.this, position="TRAILING"))
3398
+
3365
3399
  def rand_sql(self, expression: exp.Rand) -> str:
3366
3400
  seed = expression.this
3367
3401
  if seed is not None:
@@ -3733,6 +3767,21 @@ class DuckDBGenerator(generator.Generator):
3733
3767
 
3734
3768
  return self.func("ARRAY_TO_STRING", expression.this, expression.expression)
3735
3769
 
3770
+ def concatws_sql(self, expression: exp.ConcatWs) -> str:
3771
+ # DuckDB-specific: handle binary types using DPipe (||) operator
3772
+ separator = seq_get(expression.expressions, 0)
3773
+ args = expression.expressions[1:]
3774
+
3775
+ if any(_is_binary(arg) for arg in [separator, *args]):
3776
+ result = args[0]
3777
+ for arg in args[1:]:
3778
+ result = exp.DPipe(
3779
+ this=exp.DPipe(this=result, expression=separator), expression=arg
3780
+ )
3781
+ return self.sql(result)
3782
+
3783
+ return super().concatws_sql(expression)
3784
+
3736
3785
  def _regexp_extract_sql(self, expression: exp.RegexpExtract | exp.RegexpExtractAll) -> str:
3737
3786
  this = expression.this
3738
3787
  group = expression.args.get("group")
@@ -481,6 +481,7 @@ class SnowflakeGenerator(generator.Generator):
481
481
  ),
482
482
  exp.CosineDistance: rename_func("VECTOR_COSINE_SIMILARITY"),
483
483
  exp.EuclideanDistance: rename_func("VECTOR_L2_DISTANCE"),
484
+ exp.HandlerProperty: lambda self, e: f"HANDLER = {self.sql(e, 'this')}",
484
485
  exp.FileFormatProperty: lambda self, e: (
485
486
  f"FILE_FORMAT=({self.expressions(e, 'expressions', sep=' ')})"
486
487
  ),
@@ -5399,7 +5399,11 @@ class Parser:
5399
5399
  comments = self._prev_comments
5400
5400
  if top:
5401
5401
  limit_paren = self._match(TokenType.L_PAREN)
5402
- expression = self._parse_term() if limit_paren else self._parse_number()
5402
+ expression = (
5403
+ self._parse_term() or self._parse_select()
5404
+ if limit_paren
5405
+ else self._parse_number()
5406
+ )
5403
5407
 
5404
5408
  if limit_paren:
5405
5409
  self._match_r_paren()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlglotc
3
- Version: 30.3.0
3
+ Version: 30.4.0
4
4
  Summary: mypyc-compiled extensions for sqlglot
5
5
  Author-email: Toby Mao <toby.mao@gmail.com>
6
6
  License-Expression: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes