Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions pyiceberg/expressions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,9 @@ def as_unbound(self) -> type[NotNull]:
class IsNull(UnaryPredicate):
type: TypingLiteral["is-null"] = Field(default="is-null")

def __init__(self, term: str | UnboundTerm, **_: Any) -> None:
super().__init__(term)

def __invert__(self) -> NotNull:
"""Transform the Expression into its negated version."""
return NotNull(self.term)
Expand All @@ -612,6 +615,9 @@ def as_bound(self) -> type[BoundIsNull]: # type: ignore
class NotNull(UnaryPredicate):
type: TypingLiteral["not-null"] = Field(default="not-null")

def __init__(self, term: str | UnboundTerm, **_: Any) -> None:
super().__init__(term)

def __invert__(self) -> IsNull:
"""Transform the Expression into its negated version."""
return IsNull(self.term)
Expand Down Expand Up @@ -656,6 +662,9 @@ def as_unbound(self) -> type[NotNaN]:
class IsNaN(UnaryPredicate):
type: TypingLiteral["is-nan"] = Field(default="is-nan")

def __init__(self, term: str | UnboundTerm, **_: Any) -> None:
super().__init__(term)

def __invert__(self) -> NotNaN:
"""Transform the Expression into its negated version."""
return NotNaN(self.term)
Expand All @@ -668,6 +677,9 @@ def as_bound(self) -> type[BoundIsNaN]: # type: ignore
class NotNaN(UnaryPredicate):
type: TypingLiteral["not-nan"] = Field(default="not-nan")

def __init__(self, term: str | UnboundTerm, **_: Any) -> None:
super().__init__(term)

def __invert__(self) -> IsNaN:
"""Transform the Expression into its negated version."""
return IsNaN(self.term)
Expand Down Expand Up @@ -811,6 +823,11 @@ def as_unbound(self) -> type[NotIn]:
class In(SetPredicate):
type: TypingLiteral["in"] = Field(default="in", alias="type")

def __init__(
self, term: str | UnboundTerm, literals: Iterable[Any] | Iterable[LiteralValue] | None = None, **kwargs: Any
) -> None:
super().__init__(term, literals, **kwargs)

def __new__( # pylint: disable=W0221
cls, term: str | UnboundTerm, literals: Iterable[Any] | Iterable[LiteralValue] | None = None, **kwargs: Any
) -> In:
Expand Down Expand Up @@ -841,6 +858,11 @@ def as_bound(self) -> type[BoundIn]: # type: ignore
class NotIn(SetPredicate, ABC):
type: TypingLiteral["not-in"] = Field(default="not-in", alias="type")

def __init__(
self, term: str | UnboundTerm, literals: Iterable[Any] | Iterable[LiteralValue] | None = None, **kwargs: Any
) -> None:
super().__init__(term, literals, **kwargs)

def __new__( # pylint: disable=W0221
cls, term: str | UnboundTerm, literals: Iterable[Any] | Iterable[LiteralValue] | None = None, **kwargs: Any
) -> NotIn:
Expand Down Expand Up @@ -1028,6 +1050,9 @@ def as_unbound(self) -> type[NotStartsWith]:
class EqualTo(LiteralPredicate):
type: TypingLiteral["eq"] = Field(default="eq", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> NotEqualTo:
"""Transform the Expression into its negated version."""
return NotEqualTo(self.term, self.literal)
Expand All @@ -1040,6 +1065,9 @@ def as_bound(self) -> type[BoundEqualTo]: # type: ignore
class NotEqualTo(LiteralPredicate):
type: TypingLiteral["not-eq"] = Field(default="not-eq", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> EqualTo:
"""Transform the Expression into its negated version."""
return EqualTo(self.term, self.literal)
Expand All @@ -1052,6 +1080,9 @@ def as_bound(self) -> type[BoundNotEqualTo]: # type: ignore
class LessThan(LiteralPredicate):
type: TypingLiteral["lt"] = Field(default="lt", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> GreaterThanOrEqual:
"""Transform the Expression into its negated version."""
return GreaterThanOrEqual(self.term, self.literal)
Expand All @@ -1064,6 +1095,9 @@ def as_bound(self) -> type[BoundLessThan]: # type: ignore
class GreaterThanOrEqual(LiteralPredicate):
type: TypingLiteral["gt-eq"] = Field(default="gt-eq", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> LessThan:
"""Transform the Expression into its negated version."""
return LessThan(self.term, self.literal)
Expand All @@ -1076,6 +1110,9 @@ def as_bound(self) -> type[BoundGreaterThanOrEqual]: # type: ignore
class GreaterThan(LiteralPredicate):
type: TypingLiteral["gt"] = Field(default="gt", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> LessThanOrEqual:
"""Transform the Expression into its negated version."""
return LessThanOrEqual(self.term, self.literal)
Expand All @@ -1088,6 +1125,9 @@ def as_bound(self) -> type[BoundGreaterThan]: # type: ignore
class LessThanOrEqual(LiteralPredicate):
type: TypingLiteral["lt-eq"] = Field(default="lt-eq", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> GreaterThan:
"""Transform the Expression into its negated version."""
return GreaterThan(self.term, self.literal)
Expand All @@ -1100,6 +1140,9 @@ def as_bound(self) -> type[BoundLessThanOrEqual]: # type: ignore
class StartsWith(LiteralPredicate):
type: TypingLiteral["starts-with"] = Field(default="starts-with", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> NotStartsWith:
"""Transform the Expression into its negated version."""
return NotStartsWith(self.term, self.literal)
Expand All @@ -1112,6 +1155,9 @@ def as_bound(self) -> type[BoundStartsWith]: # type: ignore
class NotStartsWith(LiteralPredicate):
type: TypingLiteral["not-starts-with"] = Field(default="not-starts-with", alias="type")

def __init__(self, term: str | UnboundTerm, literal: Any | None = None, **kwargs: Any) -> None:
super().__init__(term, literal, **kwargs)

def __invert__(self) -> StartsWith:
"""Transform the Expression into its negated version."""
return StartsWith(self.term, self.literal)
Expand Down
6 changes: 6 additions & 0 deletions pyiceberg/expressions/literals.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ def literal(value: L) -> Literal[L]:


class AboveMax(Literal[L]):
def __init__(self, value: L, value_type: type[L], /, **data: Any) -> None:
Literal.__init__(self, value, value_type, **data)

def __repr__(self) -> str:
"""Return the string representation of the AboveMax class."""
return f"{self.__class__.__name__}()"
Expand All @@ -184,6 +187,9 @@ def __str__(self) -> str:


class BelowMin(Literal[L]):
def __init__(self, value: L, value_type: type[L], /, **data: Any) -> None:
Literal.__init__(self, value, value_type, **data)

def __repr__(self) -> str:
"""Return the string representation of the BelowMin class."""
return f"{self.__class__.__name__}()"
Expand Down
2 changes: 1 addition & 1 deletion tests/catalog/integration_test_glue.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def fixture_glue_client() -> boto3.client:
def fixture_test_catalog() -> Generator[Catalog, None, None]:
"""Configure the pre- and post-setting of aws integration test."""
test_catalog = GlueCatalog(
CATALOG_NAME, **{"warehouse": get_s3_path(get_bucket_name()), GLUE_CATALOG_ENDPOINT: get_glue_endpoint()}
CATALOG_NAME, client=None, **{"warehouse": get_s3_path(get_bucket_name()), GLUE_CATALOG_ENDPOINT: get_glue_endpoint()}
)
yield test_catalog
clean_up(test_catalog)
Expand Down
64 changes: 45 additions & 19 deletions tests/catalog/test_dynamodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_create_dynamodb_catalog_with_table_name(_dynamodb, _bucket_initialize:
assert response["Table"]["TableStatus"] == ACTIVE

custom_table_name = "custom_table_name"
DynamoDbCatalog("test_ddb_catalog", **{"table-name": custom_table_name})
DynamoDbCatalog("test_ddb_catalog", client=None, **{"table-name": custom_table_name})
response = _dynamodb.describe_table(TableName=custom_table_name)
assert response["Table"]["TableName"] == custom_table_name
assert response["Table"]["TableStatus"] == ACTIVE
Expand All @@ -69,7 +69,7 @@ def test_create_table_with_database_location(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(catalog_name, client=None, **{"s3.endpoint": moto_endpoint_url})
test_catalog.create_namespace(namespace=database_name, properties={"location": f"s3://{BUCKET_NAME}/{database_name}.db"})
table = test_catalog.create_table(identifier, table_schema_nested)
assert table.name() == identifier
Expand All @@ -86,7 +86,7 @@ def test_create_table_with_pyarrow_schema(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(catalog_name, client=None, **{"s3.endpoint": moto_endpoint_url})
test_catalog.create_namespace(namespace=database_name, properties={"location": f"s3://{BUCKET_NAME}/{database_name}.db"})
table = test_catalog.create_table(identifier, pyarrow_schema_simple_without_ids)
assert table.name() == identifier
Expand All @@ -99,7 +99,9 @@ def test_create_table_with_default_warehouse(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"s3.endpoint": moto_endpoint_url, "warehouse": f"s3://{BUCKET_NAME}"})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"s3.endpoint": moto_endpoint_url, "warehouse": f"s3://{BUCKET_NAME}"}
)
test_catalog.create_namespace(namespace=database_name)
table = test_catalog.create_table(identifier, table_schema_nested)
assert table.name() == identifier
Expand All @@ -112,7 +114,7 @@ def test_create_table_with_given_location(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(catalog_name, client=None, **{"s3.endpoint": moto_endpoint_url})
test_catalog.create_namespace(namespace=database_name)
table = test_catalog.create_table(
identifier=identifier, schema=table_schema_nested, location=f"s3://{BUCKET_NAME}/{database_name}.db/{table_name}"
Expand All @@ -127,7 +129,7 @@ def test_create_table_removes_trailing_slash_in_location(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(catalog_name, client=None, **{"s3.endpoint": moto_endpoint_url})
test_catalog.create_namespace(namespace=database_name)
location = f"s3://{BUCKET_NAME}/{database_name}.db/{table_name}"
table = test_catalog.create_table(identifier=identifier, schema=table_schema_nested, location=f"{location}/")
Expand All @@ -153,7 +155,7 @@ def test_create_table_with_strips(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(catalog_name, client=None, **{"s3.endpoint": moto_endpoint_url})
test_catalog.create_namespace(namespace=database_name, properties={"location": f"s3://{BUCKET_NAME}/{database_name}.db/"})
table = test_catalog.create_table(identifier, table_schema_nested)
assert table.name() == identifier
Expand All @@ -166,7 +168,9 @@ def test_create_table_with_strips_bucket_root(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"s3.endpoint": moto_endpoint_url, "warehouse": f"s3://{BUCKET_NAME}/"})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"s3.endpoint": moto_endpoint_url, "warehouse": f"s3://{BUCKET_NAME}/"}
)
test_catalog.create_namespace(namespace=database_name)
table_strip = test_catalog.create_table(identifier, table_schema_nested)
assert table_strip.name() == identifier
Expand All @@ -188,7 +192,9 @@ def test_create_duplicated_table(
_bucket_initialize: None, moto_endpoint_url: str, table_schema_nested: Schema, database_name: str, table_name: str
) -> None:
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog("test_ddb_catalog", **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
"test_ddb_catalog", client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
test_catalog.create_table(identifier, table_schema_nested)
with pytest.raises(TableAlreadyExistsError):
Expand All @@ -200,7 +206,9 @@ def test_create_table_if_not_exists_duplicated_table(
_bucket_initialize: None, moto_endpoint_url: str, table_schema_nested: Schema, database_name: str, table_name: str
) -> None:
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog("test_ddb_catalog", **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
"test_ddb_catalog", client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
table1 = test_catalog.create_table(identifier, table_schema_nested)
table2 = test_catalog.create_table_if_not_exists(identifier, table_schema_nested)
Expand All @@ -213,7 +221,9 @@ def test_load_table(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
test_catalog.create_table(identifier, table_schema_nested)
table = test_catalog.load_table(identifier)
Expand All @@ -227,7 +237,9 @@ def test_load_table_from_self_identifier(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
test_catalog.create_table(identifier, table_schema_nested)
intermediate = test_catalog.load_table(identifier)
Expand All @@ -251,7 +263,9 @@ def test_drop_table(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
test_catalog.create_table(identifier, table_schema_nested)
table = test_catalog.load_table(identifier)
Expand All @@ -268,7 +282,9 @@ def test_drop_table_from_self_identifier(
) -> None:
catalog_name = "test_ddb_catalog"
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
test_catalog.create_table(identifier, table_schema_nested)
table = test_catalog.load_table(identifier)
Expand Down Expand Up @@ -297,7 +313,9 @@ def test_rename_table(
new_table_name = f"{table_name}_new"
identifier = (database_name, table_name)
new_identifier = (database_name, new_table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
table = test_catalog.create_table(identifier, table_schema_nested)
assert table.name() == identifier
Expand All @@ -320,7 +338,9 @@ def test_rename_table_from_self_identifier(
new_table_name = f"{table_name}_new"
identifier = (database_name, table_name)
new_identifier = (database_name, new_table_name)
test_catalog = DynamoDbCatalog(catalog_name, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
catalog_name, client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
table = test_catalog.create_table(identifier, table_schema_nested)
assert table.name() == identifier
Expand Down Expand Up @@ -394,7 +414,9 @@ def test_fail_on_rename_non_iceberg_table(
def test_list_tables(
_bucket_initialize: None, moto_endpoint_url: str, table_schema_nested: Schema, database_name: str, table_list: list[str]
) -> None:
test_catalog = DynamoDbCatalog("test_ddb_catalog", **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
"test_ddb_catalog", client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
for table_name in table_list:
test_catalog.create_table((database_name, table_name), table_schema_nested)
Expand Down Expand Up @@ -469,7 +491,9 @@ def test_drop_non_empty_namespace(
_bucket_initialize: None, moto_endpoint_url: str, table_schema_nested: Schema, database_name: str, table_name: str
) -> None:
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog("test_ddb_catalog", **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
"test_ddb_catalog", client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
test_catalog.create_table(identifier, table_schema_nested)
assert len(test_catalog.list_tables(database_name)) == 1
Expand Down Expand Up @@ -618,7 +642,9 @@ def test_table_exists(
_bucket_initialize: None, moto_endpoint_url: str, table_schema_nested: Schema, database_name: str, table_name: str
) -> None:
identifier = (database_name, table_name)
test_catalog = DynamoDbCatalog("test_ddb_catalog", **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url})
test_catalog = DynamoDbCatalog(
"test_ddb_catalog", client=None, **{"warehouse": f"s3://{BUCKET_NAME}", "s3.endpoint": moto_endpoint_url}
)
test_catalog.create_namespace(namespace=database_name)
test_catalog.create_table(identifier, table_schema_nested)
# Act and Assert for an existing table
Expand Down
Loading
Loading