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)
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)
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
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)
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)
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))
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, )
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, ))