Esempio n. 1
0
def _fetch_column_info_refs(table_name: str, column_name: str):
    convert_to_collection_ref_set = functools.partial(
        fql.convert_to_ref_set, "information_schema_columns_")

    return q.intersection(
        convert_to_collection_ref_set(
            q.range(
                q.match(
                    q.index(
                        fql.index_name(
                            "information_schema_columns_",
                            column_name="table_name_",
                            index_type=fql.IndexType.VALUE,
                        ))),
                table_name,
                table_name,
            ), ),
        convert_to_collection_ref_set(
            q.range(
                q.match(
                    q.index(
                        fql.index_name(
                            "information_schema_columns_",
                            column_name="name_",
                            index_type=fql.IndexType.VALUE,
                        )), ),
                column_name,
                column_name,
            ), ),
    )
Esempio n. 2
0
    def test_range(self):
        data = list(range(1, 20))

        self._q(query.create_collection({"name": "range_test"}))
        self._q(
            query.create_index({
                "name": "range_idx",
                "source": query.collection("range_test"),
                "active": True,
                "values": [{
                    "field": ["data", "value"]
                }]
            }))
        self._q(
            query.foreach(
                query.lambda_query(lambda x: query.create(
                    query.collection("range_test"), {"data": {
                        "value": x
                    }})), data))
        m = query.match(query.index("range_idx"))

        q1 = query.select("data", query.paginate(query.range(m, 3, 8)))
        q2 = query.select("data", query.paginate(query.range(m, 17, 18)))
        q3 = query.select("data", query.paginate(query.range(m, 19, 0)))

        self.assertEqual(self._q(q1), [3, 4, 5, 6, 7, 8])
        self.assertEqual(self._q(q2), [17, 18])
        self.assertEqual(self._q(q3), [])
Esempio n. 3
0
  def test_range(self):
    self.assertJson(query.range(
			query.match(query.ref("indexes/spellbooks_by_owner"), query.ref("collections/characters/104979509695139637")),
			10,
			50,
		),
		'{"from":10,"range":{"match":{"@ref":"indexes/spellbooks_by_owner"},"terms":{"@ref":"collections/characters/104979509695139637"}},"to":50}')
Esempio n. 4
0
def translate_drop(
        statement: token_groups.Statement) -> typing.List[QueryExpression]:
    """Translate a DROP SQL query into an equivalent FQL query.

    Params:
    -------
    statement: An SQL statement returned by sqlparse.

    Returns:
    --------
    An FQL query expression.
    """
    idx, _ = statement.token_next_by(m=(token_types.Keyword, "TABLE"))
    _, table_identifier = statement.token_next_by(i=token_groups.Identifier,
                                                  idx=idx)
    table_name = table_identifier.value

    deleted_collection = q.select("ref", q.delete(q.collection(table_name)))
    return [
        q.do(
            q.map_(
                q.lambda_("ref", q.delete(q.var("ref"))),
                q.paginate(
                    q.union(
                        q.match(
                            q.index(
                                fql.index_name(
                                    "information_schema_tables_",
                                    column_name="name_",
                                    index_type=fql.IndexType.TERM,
                                )),
                            table_name,
                        ),
                        fql.convert_to_ref_set(
                            "information_schema_columns_",
                            q.range(
                                q.match(
                                    q.index(
                                        fql.index_name(
                                            "information_schema_columns_",
                                            column_name="table_name_",
                                            index_type=fql.IndexType.VALUE,
                                        ))),
                                [table_name],
                                [table_name],
                            ),
                        ),
                        fql.convert_to_ref_set(
                            "information_schema_indexes_",
                            q.range(
                                q.match(
                                    q.index(
                                        fql.index_name(
                                            "information_schema_indexes_",
                                            column_name="table_name_",
                                            index_type=fql.IndexType.VALUE,
                                        ))),
                                [table_name],
                                [table_name],
                            ),
                        ),
                    ), ),
            ),
            q.let(
                {"collection": deleted_collection},
                {"data": [{
                    "id": q.var("collection")
                }]},
            ),
        )
    ]
Esempio n. 5
0
def _define_match_set(query_filter: sql.Filter) -> QueryExpression:
    field_name = query_filter.column.name
    comparison_value = query_filter.value
    index_name_for_collection = functools.partial(index_name,
                                                  query_filter.table_name)
    convert_to_collection_ref_set = functools.partial(convert_to_ref_set,
                                                      query_filter.table_name)

    get_info_indexes_with_references = lambda collection_name, field_name: q.map_(
        q.lambda_("info_index_ref", q.get(q.var("info_index_ref"))),
        q.paginate(
            q.match(
                q.index(
                    index_name(
                        "information_schema_indexes_",
                        column_name="name_",
                        index_type=IndexType.TERM,
                    )),
                index_name(
                    collection_name,
                    column_name=field_name,
                    index_type=IndexType.REF,
                ),
            ), ),
    )

    index_name_for_field = functools.partial(index_name_for_collection,
                                             field_name)
    equality_range = q.range(
        q.match(q.index(index_name_for_field(IndexType.VALUE))),
        [comparison_value],
        [comparison_value],
    )

    if query_filter.checks_whether_equal:
        if field_name == "ref":
            assert isinstance(comparison_value, str)
            return q.singleton(
                q.ref(q.collection(query_filter.table_name), comparison_value))

        return q.let(
            {
                "ref_index":
                q.index(index_name_for_field(IndexType.REF)),
                "term_index":
                q.index(index_name_for_field(IndexType.TERM)),
                "info_indexes":
                get_info_indexes_with_references(query_filter.table_name,
                                                 field_name),
                "comparison_value":
                comparison_value,
            },
            q.if_(
                q.exists(q.var("ref_index")),
                q.match(
                    q.var("ref_index"),
                    get_foreign_key_ref(
                        q.var("comparison_value"),
                        # Assumes that there is only one reference per foreign key
                        # and that it refers to the associated collection's ID field
                        # (e.g. {'associated_table': 'id'}).
                        # This is enforced via NotSupported errors when creating collections.
                        q.select([0, DATA, "referred_table_"],
                                 q.var("info_indexes")),
                    ),
                ),
                q.if_(
                    q.exists(q.var("term_index")),
                    q.match(
                        q.var("term_index"),
                        q.var("comparison_value"),
                    ),
                    convert_to_collection_ref_set(equality_range),
                ),
            ),
        )

    # In the building of Filter objects from SQL tokens, we enforce the convention
    # of <column name> <operator> <value> for WHERE clauses, so we build the FQL queries
    # assuming that '>' means 'column value greater than literal value'. I can't think
    # of a good way to centralize the knowledge of this convention across
    # all query translation, so I'm leaving this note as a warning.
    if query_filter.checks_whether_greater_than:
        inclusive_comparison_range = q.range(
            q.match(q.index(index_name_for_field(IndexType.VALUE))),
            [comparison_value],
            [],
        )
        return convert_to_collection_ref_set(
            q.difference(inclusive_comparison_range, equality_range))

    if query_filter.checks_whether_greater_than_or_equal:
        inclusive_comparison_range = q.range(
            q.match(q.index(index_name_for_field(IndexType.VALUE))),
            [comparison_value],
            [],
        )
        return convert_to_collection_ref_set(inclusive_comparison_range)

    if query_filter.checks_whether_less_than:
        inclusive_comparison_range = q.range(
            q.match(q.index(index_name_for_field(IndexType.VALUE))),
            [],
            [comparison_value],
        )
        return convert_to_collection_ref_set(
            q.difference(inclusive_comparison_range, equality_range))

    if query_filter.checks_whether_less_than_or_equal:
        inclusive_comparison_range = q.range(
            q.match(q.index(index_name_for_field(IndexType.VALUE))),
            [],
            [comparison_value],
        )
        return convert_to_collection_ref_set(inclusive_comparison_range)

    raise exceptions.NotSupportedError(
        f"Unsupported comparison {query_filter.comparison} was received.")