예제 #1
0
    def _in_testmode(self, ctx: CompileContext):
        current_tx = ctx.state.current_tx()
        session_config = current_tx.get_session_config()

        return config.lookup(config.get_settings(),
                             '__internal_testmode',
                             session_config,
                             allow_unrecognized=True)
예제 #2
0
 async def introspect_db_config(self, conn):
     query = self.get_sys_query('dbconfig')
     result = await conn.parse_execute_json(
         query,
         b'__backend_dbconfig',
         dbver=0,
         use_prep_stmt=True,
         args=(),
     )
     return config.from_json(config.get_settings(), result)
예제 #3
0
    async def get_auth_method(self, user):
        authlist = self._sys_auth

        if not authlist:
            default_method = 'SCRAM'
            return config.get_settings().get_type_by_name(default_method)()
        else:
            for auth in authlist:
                match = ((user in auth.user or '*' in auth.user))

                if match:
                    return auth.method
예제 #4
0
파일: bootstrap.py 프로젝트: syyunn/edgedb
async def _configure(schema, conn, cluster, *, insecure=False, testmode=False):
    scripts = []

    if not testmode:
        memory_kb = psutil.virtual_memory().total // 1024
        settings = {
            'shared_buffers': f'"{int(memory_kb * 0.2)}kB"',
            'effective_cache_size': f'"{int(memory_kb * 0.5)}kB"',
            'query_work_mem': f'"{6 * (2 ** 10)}kB"',
        }

        for setting, value in settings.items():
            scripts.append(f'''
                CONFIGURE SYSTEM SET {setting} := {value};
            ''')
    else:
        settings = {}

    if insecure:
        scripts.append('''
            CONFIGURE SYSTEM INSERT Auth {
                priority := 0,
                method := (INSERT Trust),
            };
        ''')

    config_spec = config.get_settings()

    for script in scripts:
        _, sql = compiler.compile_bootstrap_script(
            schema, schema, script, single_statement=True)

        if debug.flags.bootstrap:
            debug.header('Bootstrap')
            debug.dump_code(sql, lexer='sql')

        config_op_data = await conn.fetchval(sql)
        if config_op_data is not None and isinstance(config_op_data, str):
            config_op = config.Operation.from_json(config_op_data)
            settings = config_op.apply(config_spec, immutables.Map())

    config_json = config.to_json(config_spec, settings)
    block = dbops.PLTopBlock()
    dbops.UpdateMetadata(
        dbops.Database(name=edbdef.EDGEDB_TEMPLATE_DB),
        {'sysconfig': json.loads(config_json)},
    ).generate(block)

    await _execute_block(conn, block)
예제 #5
0
    async def load_sys_config(self):
        syscon = await self._acquire_sys_pgcon()
        try:
            query = self.get_sys_query('sysconfig')
            sys_config_json = await syscon.parse_execute_json(
                query,
                b'__backend_sysconfig',
                dbver=0,
                use_prep_stmt=True,
                args=(),
            )
        finally:
            self._release_sys_pgcon()

        return config.from_json(config.get_settings(), sys_config_json)
예제 #6
0
async def _configure(schema, conn, cluster, *, insecure=False, testmode=False):
    scripts = []

    if not testmode:
        memory_kb = psutil.virtual_memory().total // 1024
        settings = {
            'shared_buffers': f'"{int(memory_kb * 0.2)}kB"',
            'effective_cache_size': f'"{int(memory_kb * 0.5)}kB"',
            'query_work_mem': f'"{6 * (2 ** 10)}kB"',
        }

        for setting, value in settings.items():
            scripts.append(f'''
                CONFIGURE SYSTEM SET {setting} := {value};
            ''')
    else:
        settings = {}

    if insecure:
        scripts.append('''
            CONFIGURE SYSTEM INSERT Auth {
                priority := 0,
                method := (INSERT Trust),
            };
        ''')

    config_spec = config.get_settings()

    for script in scripts:
        _, sql = compiler.compile_bootstrap_script(schema,
                                                   schema,
                                                   script,
                                                   single_statement=True)

        if debug.flags.bootstrap:
            debug.header('Bootstrap')
            debug.dump_code(sql, lexer='sql')

        config_op_data = await conn.fetchval(sql)
        if config_op_data is not None and isinstance(config_op_data, str):
            config_op = config.Operation.from_json(config_op_data)
            settings = config_op.apply(config_spec, immutables.Map())

    data_dir = cluster.get_data_dir()
    overrides_fn = os.path.join(data_dir, 'config_sys.json')

    with open(overrides_fn, 'wt') as f:
        f.write(config.to_json(config_spec, settings))
예제 #7
0
    def _compile_ql_config_op(self, ctx: CompileContext, ql: qlast.Base):

        current_tx = ctx.state.current_tx()
        schema = current_tx.get_schema()

        modaliases = ctx.state.current_tx().get_modaliases()
        session_config = ctx.state.current_tx().get_session_config()

        if ql.system and not current_tx.is_implicit():
            raise errors.QueryError('CONFIGURE SYSTEM cannot be executed in a '
                                    'transaction block')

        ir = ql_compiler.compile_ast_to_ir(
            ql,
            schema=schema,
            modaliases=modaliases,
        )

        is_backend_setting = bool(getattr(ir, 'backend_setting', None))
        requires_restart = bool(getattr(ir, 'requires_restart', False))

        if is_backend_setting:
            if isinstance(ql, qlast.ConfigReset):
                val = None
            else:
                # Postgres is fine with all setting types to be passed
                # as strings.
                value = ireval.evaluate_to_python_val(ir.expr, schema=schema)
                val = pg_ast.StringConstant(val=str(value))

            if ir.system:
                sql_ast = pg_ast.AlterSystem(
                    name=ir.backend_setting,
                    value=val,
                )
            else:
                sql_ast = pg_ast.Set(
                    name=ir.backend_setting,
                    value=val,
                )

            sql_text = pg_codegen.generate_source(sql_ast) + ';'

            sql = (sql_text.encode(), )

        else:
            sql_text, _ = pg_compiler.compile_ir_to_sql(
                ir,
                pretty=debug.flags.edgeql_compile,
                output_format=pg_compiler.OutputFormat.JSONB)

            sql = (sql_text.encode(), )

        if not ql.system:
            config_op = ireval.evaluate_to_config_op(ir, schema=schema)

            session_config = config_op.apply(config.get_settings(),
                                             session_config)
            ctx.state.current_tx().update_session_config(session_config)
        else:
            config_op = None

        return dbstate.SessionStateQuery(
            sql=sql,
            is_backend_setting=is_backend_setting,
            is_system_setting=ql.system,
            requires_restart=requires_restart,
            config_op=config_op,
        )
예제 #8
0
    def _compile_ql_query(self, ctx: CompileContext,
                          ql: qlast.Base) -> dbstate.BaseQuery:

        current_tx = ctx.state.current_tx()
        session_config = current_tx.get_session_config()

        native_out_format = (ctx.output_format is
                             pg_compiler.OutputFormat.NATIVE)

        single_stmt_mode = ctx.stmt_mode is enums.CompileStatementMode.SINGLE

        implicit_fields = (native_out_format and single_stmt_mode)

        disable_constant_folding = config.lookup(config.get_settings(),
                                                 '__internal_no_const_folding',
                                                 session_config,
                                                 allow_unrecognized=True)

        # the capability to execute transaction or session control
        # commands indicates that session mode is available
        session_mode = ctx.state.capability & (enums.Capability.TRANSACTION
                                               | enums.Capability.SESSION)
        ir = ql_compiler.compile_ast_to_ir(
            ql,
            schema=current_tx.get_schema(),
            modaliases=current_tx.get_modaliases(),
            implicit_tid_in_shapes=implicit_fields,
            implicit_id_in_shapes=implicit_fields,
            disable_constant_folding=disable_constant_folding,
            json_parameters=ctx.json_parameters,
            session_mode=session_mode)

        if ir.cardinality is qltypes.Cardinality.ONE:
            result_cardinality = enums.ResultCardinality.ONE
        else:
            result_cardinality = enums.ResultCardinality.MANY
            if ctx.expected_cardinality_one:
                raise errors.ResultCardinalityMismatchError(
                    f'the query has cardinality {result_cardinality} '
                    f'which does not match the expected cardinality ONE')

        sql_text, argmap = pg_compiler.compile_ir_to_sql(
            ir,
            pretty=debug.flags.edgeql_compile,
            expected_cardinality_one=ctx.expected_cardinality_one,
            output_format=ctx.output_format)

        sql_bytes = sql_text.encode(defines.EDGEDB_ENCODING)

        if single_stmt_mode:
            if native_out_format:
                out_type_data, out_type_id = sertypes.TypeSerializer.describe(
                    ir.schema, ir.stype, ir.view_shapes,
                    ir.view_shapes_metadata)
            else:
                out_type_data, out_type_id = \
                    sertypes.TypeSerializer.describe_json()

            in_array_backend_tids: typing.Optional[typing.Mapping[int,
                                                                  int]] = None

            if ir.params:
                array_params = []
                subtypes = [None] * len(ir.params)
                first_param_name = next(iter(ir.params))
                if first_param_name.isdecimal():
                    named = False
                    for param_name, param_type in ir.params.items():
                        idx = int(param_name)
                        subtypes[idx] = (param_name, param_type)
                        if param_type.is_array():
                            el_type = param_type.get_element_type(ir.schema)
                            array_params.append(
                                (idx, el_type.get_backend_id(ir.schema)))
                else:
                    named = True
                    for param_name, param_type in ir.params.items():
                        idx = argmap[param_name] - 1
                        subtypes[idx] = (param_name, param_type)
                        if param_type.is_array():
                            el_type = param_type.get_element_type(ir.schema)
                            array_params.append(
                                (idx, el_type.get_backend_id(ir.schema)))

                params_type = s_types.Tuple.create(
                    ir.schema,
                    element_types=collections.OrderedDict(subtypes),
                    named=named)
                if array_params:
                    in_array_backend_tids = {p[0]: p[1] for p in array_params}
            else:
                params_type = s_types.Tuple.create(ir.schema,
                                                   element_types={},
                                                   named=False)

            in_type_data, in_type_id = sertypes.TypeSerializer.describe(
                ir.schema, params_type, {}, {})

            in_type_args = None
            if ctx.json_parameters:
                in_type_args = [None] * len(argmap)
                for argname, argpos in argmap.items():
                    in_type_args[argpos - 1] = argname

            sql_hash = self._hash_sql(sql_bytes,
                                      mode=str(ctx.output_format).encode(),
                                      intype=in_type_id.bytes,
                                      outtype=out_type_id.bytes)

            return dbstate.Query(
                sql=(sql_bytes, ),
                sql_hash=sql_hash,
                cardinality=result_cardinality,
                in_type_id=in_type_id.bytes,
                in_type_data=in_type_data,
                in_type_args=in_type_args,
                in_array_backend_tids=in_array_backend_tids,
                out_type_id=out_type_id.bytes,
                out_type_data=out_type_data,
            )

        else:
            if ir.params:
                raise errors.QueryError(
                    'EdgeQL script queries cannot accept parameters')

            return dbstate.SimpleQuery(sql=(sql_bytes, ))