operation_param.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. from materialize.output_consistency.data_type.data_type import DataType
  10. from materialize.output_consistency.data_type.data_type_category import DataTypeCategory
  11. from materialize.output_consistency.expression.expression import Expression
  12. from materialize.output_consistency.expression.expression_characteristics import (
  13. ExpressionCharacteristics,
  14. )
  15. from materialize.output_consistency.operation.return_type_spec import ReturnTypeSpec
  16. class OperationParam:
  17. """Parameter of a database operation or database function"""
  18. def __init__(
  19. self,
  20. type_category: DataTypeCategory,
  21. optional: bool = False,
  22. incompatibilities: set[ExpressionCharacteristics] | None = None,
  23. incompatibility_combinations: (
  24. list[set[ExpressionCharacteristics]] | None
  25. ) = None,
  26. ):
  27. """
  28. Create a parameter for an operation.
  29. :param optional: this parameter can be omitted
  30. :param incompatibilities: a value annotated with any of these characteristics is considered invalid
  31. :param incompatibility_combinations: a value annotated with all characteristics of any entry is considered invalid
  32. """
  33. self._type_category = type_category
  34. self.optional = optional
  35. if incompatibility_combinations is None:
  36. incompatibility_combinations = list()
  37. self.incompatibility_combinations = incompatibility_combinations
  38. if incompatibilities is not None:
  39. for incompatibility in incompatibilities:
  40. self.incompatibility_combinations.append({incompatibility})
  41. def supports_type(
  42. self, data_type: DataType, previous_args: list[Expression]
  43. ) -> bool:
  44. raise NotImplementedError
  45. def might_support_type_as_input_assuming_category_matches(
  46. self, return_type_spec: ReturnTypeSpec
  47. ) -> bool:
  48. return True
  49. def supports_expression(self, arg: Expression) -> bool:
  50. for incompatibility_combination in self.incompatibility_combinations:
  51. if arg.has_all_characteristics(incompatibility_combination):
  52. return False
  53. return True
  54. def get_declared_type_category(self) -> DataTypeCategory:
  55. return self._type_category
  56. def resolve_type_category(
  57. self, previous_args: list[Expression]
  58. ) -> DataTypeCategory:
  59. return self._type_category
  60. def __str__(self) -> str:
  61. return f"{type(self).__name__} (optional={self.optional})"