Skip to content

Commit

Permalink
0.12.0-a6
Browse files Browse the repository at this point in the history
  • Loading branch information
joocer committed Sep 24, 2023
1 parent ab06668 commit f3dfb2a
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/regression_suite_arm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
python setup.py build_ext --inplace
- name: "Authenticate to Google Cloud"
uses: google-github-actions/auth@v0.4.0
uses: google-github-actions/auth@v1
with:
credentials_json: '${{ secrets.GCP_KEY }}'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/regression_suite_mac_x86.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
python setup.py build_ext --inplace
- name: "Authenticate to Google Cloud"
uses: google-github-actions/auth@v0.4.0
uses: google-github-actions/auth@v1
with:
credentials_json: '${{ secrets.GCP_KEY }}'

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/regression_suite_windows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
python setup.py build_ext --inplace
- name: "Authenticate to Google Cloud"
uses: google-github-actions/auth@v0.4.0
uses: google-github-actions/auth@v1
with:
credentials_json: '${{ secrets.GCP_KEY }}'

Expand Down
2 changes: 1 addition & 1 deletion opteryx/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
"""

# __version__ = "0.4.0-alpha.6"
__version__ = "0.12.0-alpha.3"
__version__ = "0.12.0-alpha.6"
24 changes: 19 additions & 5 deletions opteryx/components/binder/binder_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,11 +395,6 @@ def visit_join(self, node: Node, context: BindingContext) -> Tuple[Node, Binding
if node.column:
if not node.alias:
node.alias = f"UNNEST({node.column.query_column})"
# Find which relation on the left side of the plan the field is in
for left_relation_name in node.left_relation_names:
if context.schemas[left_relation_name].find_column(node.column.value):
node.source = left_relation_name
break
# this is the column which is being unnested
node.column, context = inner_binder(node.column, context, node.identity)
# this is the column that is being created - find it from it's name
Expand All @@ -418,6 +413,25 @@ def visit_join(self, node: Node, context: BindingContext) -> Tuple[Node, Binding
return node, context

def visit_project(self, node: Node, context: BindingContext) -> Tuple[Node, BindingContext]:
columns = []
for column in node.columns:
if not column.node_type == NodeType.WILDCARD:
columns.append(column)
else:
schema = context.schemas[column.value[0]]

for schema_column in schema.columns:
column_reference = Node(
node_type=NodeType.IDENTIFIER,
name=schema_column.name,
schema_column=schema_column,
type=schema_column.type,
query_column=f"{column.value[0]}.{schema_column.name}",
)
columns.append(column_reference)

node.columns = columns

node.columns, group_contexts = zip(
*(inner_binder(col, context, node.identity) for col in node.columns)
)
Expand Down
10 changes: 8 additions & 2 deletions opteryx/components/logical_planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,11 @@ def inner_query_planner(ast_branch):
inner_plan.add_edge(previous_step_id, step_id)

# projection
if not (len(_projection) == 1 and _projection[0].node_type == NodeType.WILDCARD):
if not (
len(_projection) == 1
and _projection[0].node_type == NodeType.WILDCARD
and _projection[0].value is None
):
project_step = LogicalPlanNode(node_type=LogicalPlanStepType.Project)
project_step.columns = _projection
previous_step_id, step_id = step_id, random_string()
Expand Down Expand Up @@ -443,7 +447,9 @@ def create_node_relation(relation):
if function["alias"] is None:
from opteryx.exceptions import UnnamedColumnError

raise UnnamedColumnError(f"Column created by {function_name} has no name.")
raise UnnamedColumnError(
f"Column created by {function_name} has no name, use AS to name the column."
)

function = relation["relation"]["Table"]
function_name = function["name"][0]["value"].upper()
Expand Down
2 changes: 2 additions & 0 deletions opteryx/managers/expression/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def format_expression(root):
return f"{root.value.upper()}({distinct}{format_expression(root.expression)}{order}{limit})"
return f"{root.value.upper()}({distinct}{','.join([format_expression(e) for e in root.parameters])}{order})"
if node_type == NodeType.WILDCARD:
if root.value:
return f"{root.value[0]}.*"
return "*"
if node_type == NodeType.BINARY_OPERATOR:
_map = {
Expand Down
19 changes: 1 addition & 18 deletions opteryx/models/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
from typing import Any
from typing import Dict

from orso.tools import random_string


class Node:
def __init__(self, node_type: str = None, **kwargs: Any):
Expand All @@ -44,9 +42,6 @@ def __init__(self, node_type: str = None, **kwargs: Any):
Dynamic attributes for the node.
"""
object.__setattr__(self, "_internal", {}) # Directly set _internal using the base method
object.__setattr__(
self, "_identity", random_string()
) # Generate and set immutable identifier
if node_type:
self._internal["node_type"] = node_type
for k, v in kwargs.items():
Expand Down Expand Up @@ -74,16 +69,6 @@ def properties(self) -> Dict[str, Any]:
"""
return self._internal

@property
def identity(self) -> str:
"""
Get the immutable unique identity for the Node.
Returns:
str: The immutable identity.
"""
return self._identity

def __getattr__(self, name: str) -> Any:
"""
Retrieve attribute from the internal dictionary or the _identity.
Expand All @@ -107,9 +92,7 @@ def __setattr__(self, name: str, value: Any) -> None:
value: Any
The value to set.
"""
if name == "identity":
raise AttributeError("The 'identity' attribute is immutable.")
elif name == "_internal":
if name == "_internal":
self._internal = value
else:
self._is_valid_key(name)
Expand Down
52 changes: 0 additions & 52 deletions tests/misc/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,58 +119,6 @@ def __str__(self):
assert '"custom":"CustomObject"' in str(n)


import pytest


def test_node_identifier_uniqueness():
"""
Test that each Node instance gets a unique identifier.
"""
node1 = Node()
node2 = Node()
node3 = Node(node_type="test")

assert node1.identifier is not None
assert node2.identifier is not None
assert node3.identifier is not None

# Test that identifiers are unique
assert node1.identifier != node2.identifier
assert node1.identifier != node3.identifier
assert node2.identifier != node3.identifier


def test_node_identifier_immutable():
"""
Test that the identifier attribute cannot be changed.
"""
node = Node()

# Attempt to change the identifier, should raise an error
with pytest.raises(AttributeError):
node.identifier = "new_id"

# Attempt to delete the identifier, should raise an error
with pytest.raises(AttributeError):
del node.identifier


def test_node_identifier_consistency():
"""
Test that the identifier remains the same across the lifetime of the Node object.
"""
node = Node()
initial_identifier = node.identifier

# Perform some operations on the Node object
node._internal["new_key"] = "new_value"
node_copy = node.copy()

# Check that the identifier remains unchanged
assert node.identifier == initial_identifier
assert node_copy.identifier != initial_identifier # Copy should have its own unique identifier


if __name__ == "__main__": # pragma: no cover
from tests.tools import run_tests

Expand Down
2 changes: 1 addition & 1 deletion tests/sql_battery/test_shapes_and_errors_battery.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@
("SELECT * FROM $satellites INNER JOIN $planets WITH (NO_CACHE) USING (id)", 9, 27, None),
("SELECT * FROM $satellites JOIN $planets USING (id)", 9, 27, None),
("SELECT * FROM $astronauts CROSS JOIN UNNEST(missions) AS mission WHERE mission = 'Apollo 11'", 3, 20, None),
("SELECT * FROM $astronauts CROSS JOIN UNNEST(missions)", 869, 20, None),
("SELECT * FROM $astronauts CROSS JOIN UNNEST(missions) AS m", 869, 20, None),
("SELECT * FROM $planets INNER JOIN $satellites ON $planets.id = $satellites.planetId", 177, 28, None),
("SELECT DISTINCT planetId FROM $satellites LEFT OUTER JOIN $planets ON $satellites.planetId = $planets.id", 7, 1, None),
("SELECT DISTINCT planetId FROM $satellites LEFT JOIN $planets ON $satellites.planetId = $planets.id", 7, 1, None),
Expand Down
2 changes: 1 addition & 1 deletion tests/storage/test_sql_biq_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


# skip to reduce billing
# @skip_if(is_arm() or is_windows() or is_mac())
@skip_if(is_arm() or is_windows() or is_mac())
def test_bigquery_storage():
from sqlalchemy.engine import create_engine

Expand Down

0 comments on commit f3dfb2a

Please sign in to comment.