Skip to content

Commit

Permalink
Fix static evaluation TypeCast str->bool bug (#8113)
Browse files Browse the repository at this point in the history
`<bool>'false'` was evaluated as `True`.
  • Loading branch information
fantix authored Dec 12, 2024
1 parent 446045f commit d911068
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 4 deletions.
33 changes: 29 additions & 4 deletions edb/ir/staeval.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,35 @@ def cast_const_to_python(ir: irast.TypeCast, schema: s_schema.Schema) -> Any:
schema, stype = irtyputils.ir_typeref_to_type(schema, ir.to_type)
pytype = scalar_type_to_python_type(stype, schema)
sval = evaluate_to_python_val(ir.expr, schema=schema)
if sval is None:
return None
elif isinstance(sval, tuple):
return tuple(pytype(elem) for elem in sval)
return python_cast(sval, pytype)


@functools.singledispatch
def python_cast(sval: Any, pytype: type) -> Any:
return pytype(sval)


@python_cast.register(type(None))
def python_cast_none(sval: None, pytype: type) -> None:
return None


@python_cast.register(tuple)
def python_cast_tuple(sval: Tuple[Any, ...], pytype: type) -> Any:
return tuple(python_cast(elem, pytype) for elem in sval)


@python_cast.register(str)
def python_cast_str(sval: str, pytype: type) -> Any:
if pytype is bool:
if sval.lower() == 'true':
return True
elif sval.lower() == 'false':
return False
else:
raise errors.InvalidValueError(
f"invalid input syntax for type bool: {sval!r}"
)
else:
return pytype(sval)

Expand Down
5 changes: 5 additions & 0 deletions edb/lib/_testmode.edgeql
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ ALTER TYPE cfg::AbstractConfig {
SET default := cfg::TestEnum.One;
};

CREATE PROPERTY boolprop -> std::bool {
CREATE ANNOTATION cfg::internal := 'true';
SET default := true;
};

CREATE PROPERTY __pg_max_connections -> std::int64 {
CREATE ANNOTATION cfg::internal := 'true';
CREATE ANNOTATION cfg::backend_setting := '"max_connections"';
Expand Down
39 changes: 39 additions & 0 deletions tests/test_server_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,45 @@ async def test_server_proto_configure_08(self):
CONFIGURE INSTANCE RESET _pg_prepared_statement_cache_size;
''')

async def test_server_proto_configure_09(self):
con2 = await self.connect(database=self.con.dbname)
default_value = await con2.query_single(
'SELECT assert_single(cfg::Config).boolprop'
)
try:
for value in [True, False, True, False]:
await self.con.execute(f'''
CONFIGURE SESSION SET boolprop := <bool>'{value}';
''')
# The first immediate query is likely NOT syncing in-memory
# state to the backend connection, so this will test that
# the state in the SQL temp table is correctly set.
await self.assert_query_result(
'''
SELECT cfg::Config.boolprop
''',
[value],
)
# Now change the state on the backend connection, hopefully,
# by running a query with con2 with different state.
self.assertEqual(
await con2.query_single(
'SELECT assert_single(cfg::Config).boolprop'
),
default_value,
)
# The second query shall sync in-memory state to the backend
# connection, so this tests if the statically evaluated bool
# value is correct.
await self.assert_query_result(
'''
SELECT cfg::Config.boolprop
''',
[value],
)
finally:
await con2.aclose()

async def test_server_proto_configure_describe_system_config(self):
try:
conf1 = "CONFIGURE INSTANCE SET singleprop := '1337';"
Expand Down

0 comments on commit d911068

Please sign in to comment.