Esempio n. 1
0
 def get_condition(self, expression: Expression,
                   remainder: List[str]) -> Any:
     value = get_term_value(expression)
     """
     Target query:
         select cfg from static_config
         where ... exists(
             select 1
             from jsonb_path_query(cfg, '$."indirect"."strings"[*]."a"')
             as json_element
             where json_element  #>> '{}' like '2'
         );
     """
     json_path = make_jsonpath(remainder)
     # Make aliased function call
     json_elements = func.jsonb_path_query(self.column,
                                           json_path).alias("json_element")
     # Use #>>'{}' to extract value as text
     json_element = column("json_element").operate(JSONPATH_ASTEXT,
                                                   "{}",
                                                   result_type=Text)
     if expression.has_wildcard():
         condition = json_element.like(value)
     else:
         condition = json_element == value
     return exists(select([1]).select_from(json_elements).where(condition))
Esempio n. 2
0
    def get_condition(self, expression: Expression,
                      remainder: List[str]) -> Any:
        value = get_term_value(expression)

        def jsonpath_escape(field):
            """Escapes field to be correctly represented in jsonpath"""
            # Escape all unescaped double quotes
            field = regex.sub(r'(?<!\\)(?:\\\\)*\K["]', '\\"', field)
            # Find trailing non-escaped asterisks
            asterisk_r = re.search(r"(?<!\\)(?:\\\\)*([*]+)$", field)
            if not asterisk_r:
                asterisks = ""
            else:
                asterisk_levels = len(asterisk_r.group(1))
                field = field[:-asterisk_levels]
                asterisks = asterisk_levels * "[*]"
            # Unescape all escaped asterisks
            field = regex.sub(r"(?<!\\)(?:\\\\)*\K(\\[*])", "*", field)
            return f'"{field}"{asterisks}'

        """
        Target query:
            select cfg from static_config
            where ... exists(
                select 1
                from jsonb_path_query(cfg, '$."indirect"."strings"[*]."a"')
                as json_element
                where json_element  #>> '{}' like '2'
            );
        """
        json_path = ".".join(["$"] +
                             [jsonpath_escape(field) for field in remainder])
        # Make aliased function call
        json_elements = func.jsonb_path_query(self.column,
                                              json_path).alias("json_element")
        # Use #>>'{}' to extract value as text
        json_element = column("json_element").operate(JSONPATH_ASTEXT,
                                                      "{}",
                                                      result_type=Text)
        if expression.has_wildcard():
            condition = json_element.like(value)
        else:
            condition = json_element == value
        return exists(select([1]).select_from(json_elements).where(condition))
Esempio n. 3
0
    def get_condition(self, expression: Expression,
                      remainder: List[str]) -> Any:
        if remainder:
            attribute_key = remainder[0]
        else:
            raise UnsupportedGrammarException(
                "Missing attribute key (attribute.<key>:)")

        attribute_definition = AttributeDefinition.query_for_read(
            key=attribute_key, include_hidden=True).first()

        if attribute_definition is None:
            raise ObjectNotFoundException(
                f"No such attribute: {attribute_key}")

        if (attribute_definition.hidden and expression.has_wildcard()
                and not g.auth_user.has_rights(
                    Capabilities.reading_all_attributes)):
            raise FieldNotQueryableException(
                "Wildcards are not allowed for hidden attributes")

        value = get_term_value(expression)
        json_path = make_jsonpath(remainder[1:])
        # Make aliased function call
        json_elements = func.jsonb_path_query(Attribute.value,
                                              json_path).alias("json_element")
        # Use #>>'{}' to extract value as text
        json_element = column("json_element").operate(JSONPATH_ASTEXT,
                                                      "{}",
                                                      result_type=Text)
        if expression.has_wildcard():
            condition = json_element.like(value)
        else:
            condition = json_element == value
        value_condition = exists(
            select([1]).select_from(json_elements).where(condition))
        return self.column.any(
            and_(Attribute.key == attribute_key, value_condition))