sql-blocks 1.20250711__py3-none-any.whl → 1.20250712__py3-none-any.whl

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.
sql_blocks/sql_blocks.py CHANGED
@@ -336,6 +336,10 @@ class Round(Function):
336
336
  inputs = [FLOAT]
337
337
  output = FLOAT
338
338
 
339
+ class Trunc(Function):
340
+ inputs = [FLOAT]
341
+ output = FLOAT
342
+
339
343
  # --- Date Functions: ------------------------------------
340
344
  class DateDiff(Function):
341
345
  inputs = [DATE]
@@ -1681,8 +1685,11 @@ class CypherParser(Parser):
1681
1685
  if token in self.TOKEN_METHODS:
1682
1686
  return
1683
1687
  if '*' in token:
1684
- token = token.replace('*', '')
1685
- self.queries[-1].key_field = token
1688
+ pk_field = token.replace('*', '')
1689
+ if not pk_field.isidentifier():
1690
+ pos = int(pk_field or '1')-1
1691
+ pk_field = self.queries[-1].values[SELECT][pos]
1692
+ self.queries[-1].key_field = pk_field.split('.')[-1]
1686
1693
  return
1687
1694
  # -------------------------------------------------------
1688
1695
  def field_params() -> dict:
@@ -1706,6 +1713,8 @@ class CypherParser(Parser):
1706
1713
  if group:
1707
1714
  if not field:
1708
1715
  field = group
1716
+ elif not alias:
1717
+ alias = group
1709
1718
  extra_classes += [GroupBy]
1710
1719
  if function:
1711
1720
  if is_count and not field:
@@ -1713,7 +1722,9 @@ class CypherParser(Parser):
1713
1722
  class_type = FUNCTION_CLASS.get(function)
1714
1723
  if not class_type:
1715
1724
  raise ValueError(f'Unknown function `{function}`.')
1716
- class_list = [ class_type().As(alias or group, extra_classes) ]
1725
+ class_list = [ class_type().As(alias, extra_classes) ]
1726
+ elif alias:
1727
+ class_list = [NamedField(alias)] + extra_classes
1717
1728
  else:
1718
1729
  class_list = [Field] + extra_classes
1719
1730
  FieldList(field, class_list).add('', self.queries[-1])
@@ -2181,17 +2192,28 @@ MAIN_TAG = '__main__'
2181
2192
  class CTEFactory:
2182
2193
  def __init__(self, txt: str):
2183
2194
  """
2184
- Syntax:
2195
+ SQL syntax:
2185
2196
  ---
2186
- **SELECT ...
2197
+ **SELECT field, field
2187
2198
  FROM** ( `sub_query1` ) **AS** `alias_1`
2188
2199
  JOIN ( `sub_query2` ) **AS** `alias_2` **ON** `__join__`
2200
+
2201
+ Cypher syntax:
2202
+ ---
2203
+ Table1(field, `function$`field`:alias`, `group@`) <- Table2(field)
2204
+ `...`MainTable(field)
2189
2205
  """
2206
+ self.main = None
2190
2207
  if parser_class(txt) == CypherParser:
2208
+ if '...' in txt:
2209
+ txt, other = txt.split('...')
2210
+ self.main = detect(other)
2211
+ alias = self.main.table_name
2191
2212
  query_list = Select.parse(txt, CypherParser)
2192
- alias = '_'.join(query.table_name for query in query_list)
2193
- self.main = Select(alias)
2194
- self.main.break_lines = False
2213
+ if not self.main:
2214
+ alias = '_'.join(query.table_name for query in query_list)
2215
+ self.main = Select(alias)
2216
+ self.main.break_lines = False
2195
2217
  query = join_queries(query_list)
2196
2218
  self.cte_list = [CTE(alias, [query])]
2197
2219
  return
@@ -2405,17 +2427,18 @@ def detect(text: str, join_method = join_queries, format: str='') -> Select | li
2405
2427
 
2406
2428
  if __name__ == "__main__":
2407
2429
  cte = CTEFactory(
2408
- "Sales(year$ref_date:ref_year@, sum$quantity:qty_sold, vendor) <- Vendor(id, name@)"
2430
+ "Sales(year$ref_date:ref_year@, sum$quantity:qty_sold, vendor) <- Vendor(id, name:vendors_name@)"
2409
2431
  # ^^^ ^^^ ^^^
2410
2432
  # | | | ^^^ ^^^
2411
2433
  # | | | | |
2412
- # | | | Relaciona Sales com Vendor ----+ |
2434
+ # | | | Relate Sales to Vendor --------+ |
2413
2435
  # | | | |
2414
- # | | +---- Chama de `ref_year` e agrupa |
2436
+ # | | +---- Call it `ref_year` and group it |
2415
2437
  # | | |
2416
- # | +-- Extrai o ano do campo `ref_date` |
2438
+ # | +-- Extracts the year from the `ref_date` field |
2417
2439
  # | |
2418
- # +--- Tabela de vendas |
2419
- # Agrupa também pelo nome do vendedor -------------+
2440
+ # +--- The Sales table |
2441
+ # Also groups by vendor´s name ------------------+
2442
+ "...Annual_Sales_per_Vendor(ref_year, qty_sold, vendors_name, *) -> Goal(year, target)"
2420
2443
  )
2421
2444
  print(cte)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sql_blocks
3
- Version: 1.20250711
3
+ Version: 1.20250712
4
4
  Summary: Allows you to create objects for parts of SQL query commands. Also to combine these objects by joining them, adding or removing parts...
5
5
  Home-page: https://github.com/julio-cascalles/sql_blocks
6
6
  Author: Júlio Cascalles
@@ -948,7 +948,7 @@ R2 = Recursive.create(
948
948
  >> Note: Comments added later.
949
949
  ---
950
950
 
951
- ### CTEFactory class
951
+ ### 17.3 - CTEFactory class
952
952
  CTEFactory exchanges subqueries for CTEs, simply by passing the text of the "dirty" query:
953
953
 
954
954
  *Example*:
@@ -992,4 +992,27 @@ results...
992
992
  ORDER BY
993
993
  u001.name
994
994
  ```
995
+
996
+ #### 17.3.1 - You can also pass a Cypher script like in the example below:
997
+
998
+ ![image](assets/CTEFactory.png)
999
+
1000
+ results...
1001
+ ```
1002
+ WITH Annual_Sales_per_Vendor AS (
1003
+ SELECT ven.name as vendors_name, Year(sal.ref_date) as ref_year
1004
+ , Sum(sal.quantity) as qty_sold FROM Vendor ven LEFT JOIN Sales sal ON (ven.id = sal.vendor)
1005
+ GROUP BY ven.name, ref_year
1006
+ )
1007
+ SELECT
1008
+ aspv.ref_year,
1009
+ aspv.qty_sold,
1010
+ aspv.vendors_name,
1011
+ goa.target
1012
+ FROM
1013
+ Annual_Sales_per_Vendor aspv
1014
+ RIGHT JOIN Goal goa ON (aspv.ref_year = goa.year)
1015
+ ```
1016
+
1017
+
995
1018
  ---
@@ -0,0 +1,7 @@
1
+ sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
+ sql_blocks/sql_blocks.py,sha256=A-i1B6jUA6_SYRfZAA65mhqHMkSQApXO7NcmIt3O5O8,83911
3
+ sql_blocks-1.20250712.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
+ sql_blocks-1.20250712.dist-info/METADATA,sha256=Kj2I_aL5fxL2bxn3hoj8hb54kKDt3M510VDn8mGmA7o,25079
5
+ sql_blocks-1.20250712.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
+ sql_blocks-1.20250712.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
+ sql_blocks-1.20250712.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- sql_blocks/__init__.py,sha256=5ItzGCyqqa6kwY8wvF9kapyHsAiWJ7KEXCcC-OtdXKg,37
2
- sql_blocks/sql_blocks.py,sha256=JHQ0CzciUEodZoA0WjUYKDpC2VZWcFlDB9C2wrNc4rA,83004
3
- sql_blocks-1.20250711.dist-info/LICENSE,sha256=6kbiFSfobTZ7beWiKnHpN902HgBx-Jzgcme0SvKqhKY,1091
4
- sql_blocks-1.20250711.dist-info/METADATA,sha256=fci6o5QrXStVrXylRQ7QaCpO9jid0P6eON6xMK4Rob0,24486
5
- sql_blocks-1.20250711.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
6
- sql_blocks-1.20250711.dist-info/top_level.txt,sha256=57AbUvUjYNy4m1EqDaU3WHeP-uyIAfV0n8GAUp1a1YQ,11
7
- sql_blocks-1.20250711.dist-info/RECORD,,