Example #1
0
    async def compile_graphql(
        self,
        dbver: bytes,
        gql: str,
        tokens: Optional[List[Tuple[gql_lexer.TokenKind, int, int, int, int,
                                    str]]],
        substitutions: Optional[Dict[str, Tuple[str, int, int]]],
        operation_name: str = None,
        variables: Optional[Mapping[str, object]] = None,
    ) -> CompiledOperation:

        db = await self._get_database(dbver)

        if tokens is None:
            ast = graphql.parse_text(gql)
        else:
            ast = graphql.parse_tokens(gql, tokens)
        op = graphql.translate_ast(
            db.gqlcore,  # type: ignore[attr-defined]
            ast,
            variables=variables,
            substitutions=substitutions,
            operation_name=operation_name)

        ir = qlcompiler.compile_ast_to_ir(
            op.edgeql_ast,
            schema=db.schema,
            options=qlcompiler.CompilerOptions(
                json_parameters=True,
                allow_top_level_shape_dml=True,
            ),
        )

        if ir.cardinality.is_multi():
            raise errors.ResultCardinalityMismatchError(
                f'compiled GrqphQL query has cardinality {ir.cardinality}, '
                f'expected ONE')

        sql_text, argmap = pg_compiler.compile_ir_to_sql(
            ir,
            pretty=bool(debug.flags.edgeql_compile),
            expected_cardinality_one=True,
            output_format=pg_compiler.OutputFormat.JSON)

        args: List[Optional[str]] = [None] * len(argmap)
        for argname, param in argmap.items():
            args[param.index - 1] = argname

        sql_bytes = sql_text.encode()
        sql_hash = self._hash_sql(sql_bytes)

        return CompiledOperation(
            sql=sql_bytes,
            sql_hash=sql_hash,
            sql_args=args,  # type: ignore[arg-type]  # XXX: optional bug?
            dbver=dbver,
            cacheable=op.cacheable,
            cache_deps_vars=op.cache_deps_vars,
            variables=op.variables_desc,
        )
Example #2
0
def compile_graphql(
    std_schema: s_schema.FlatSchema,
    user_schema: s_schema.FlatSchema,
    global_schema: s_schema.FlatSchema,
    database_config: Mapping[str, Any],
    system_config: Mapping[str, Any],
    gql: str,
    tokens: Optional[List[Tuple[gql_lexer.TokenKind, int, int, int, int,
                                str]]],
    substitutions: Optional[Dict[str, Tuple[str, int, int]]],
    operation_name: str = None,
    variables: Optional[Mapping[str, object]] = None,
) -> CompiledOperation:
    if tokens is None:
        ast = graphql.parse_text(gql)
    else:
        ast = graphql.parse_tokens(gql, tokens)

    gqlcore = _get_gqlcore(std_schema, user_schema, global_schema)

    op = graphql.translate_ast(gqlcore,
                               ast,
                               variables=variables,
                               substitutions=substitutions,
                               operation_name=operation_name)

    ir = qlcompiler.compile_ast_to_ir(
        op.edgeql_ast,
        schema=s_schema.ChainedSchema(
            std_schema,
            user_schema,
            global_schema,
        ),
        options=qlcompiler.CompilerOptions(
            json_parameters=True,
            allow_top_level_shape_dml=True,
        ),
    )

    if ir.cardinality.is_multi():
        raise errors.ResultCardinalityMismatchError(
            f'compiled GrqphQL query has cardinality {ir.cardinality}, '
            f'expected ONE')

    sql_text, argmap = pg_compiler.compile_ir_to_sql(
        ir,
        pretty=bool(debug.flags.edgeql_compile),
        expected_cardinality_one=True,
        output_format=pg_compiler.OutputFormat.JSON)

    args: List[Optional[str]] = [None] * len(argmap)
    for argname, param in argmap.items():
        args[param.index - 1] = argname

    sql_bytes = sql_text.encode()
    sql_hash = hashlib.sha1(sql_bytes).hexdigest().encode('latin1')

    return CompiledOperation(
        sql=sql_bytes,
        sql_hash=sql_hash,
        sql_args=args,  # type: ignore[arg-type]  # XXX: optional bug?
        cacheable=op.cacheable,
        cache_deps_vars=op.cache_deps_vars,
        variables=op.variables_desc,
    )