Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into persistent-cache-5
Browse files Browse the repository at this point in the history
  • Loading branch information
fantix committed Feb 21, 2024
2 parents 35bd081 + e3b801f commit 081e54a
Show file tree
Hide file tree
Showing 32 changed files with 2,083 additions and 239 deletions.
6 changes: 6 additions & 0 deletions docs/stdlib/fts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Full-text Search
The ``fts`` built-in module contains various tools that enable full-text
search functionality in EdgeDB.

.. note::

Since full-text search is a natural language search, it may not be ideal
for your use case, particularly if you want to find partial matches. In
that case, you may want to look instead at :ref:`ref_ext_pgtrgm`.

.. list-table::
:class: funcoptable

Expand Down
2 changes: 1 addition & 1 deletion edb/edgeql/tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(
tokens: List[ql_parser.Token],
serialized: bytes,
) -> None:
self._cache_key = hashlib.blake2b(text.encode('utf-8')).digest()
self._cache_key = hashlib.blake2b(serialized).digest()
self._text = text
self._tokens = tokens
self._serialized = serialized
Expand Down
42 changes: 40 additions & 2 deletions edb/lib/ext/auth.edgeql
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,31 @@ CREATE EXTENSION PACKAGE auth VERSION '1.0' {
create required property password_hash: std::str;
};

create type ext::auth::WebAuthnFactor extending ext::auth::EmailFactor {
create required property user_handle: std::bytes {
create type ext::auth::MagicLinkFactor extending ext::auth::EmailFactor {
alter property email {
create constraint exclusive;
};
};

create type ext::auth::WebAuthnFactor extending ext::auth::EmailFactor {
create required property user_handle: std::bytes;
create required property credential_id: std::bytes {
create constraint exclusive;
};
create required property public_key: std::bytes {
create constraint exclusive;
};

create trigger email_shares_user_handle after insert for each do (
std::assert(
__new__.user_handle = (
select detached ext::auth::WebAuthnFactor
filter .email = __new__.email
and not .id = __new__.id
).user_handle,
message := "user_handle must be the same for a given email"
)
);
create constraint exclusive on ((.email, .credential_id));
};

Expand All @@ -92,6 +106,16 @@ CREATE EXTENSION PACKAGE auth VERSION '1.0' {
create constraint exclusive on ((.user_handle, .email, .challenge));
};

create type ext::auth::WebAuthnAuthenticationChallenge
extending ext::auth::Auditable {
create required property challenge: std::bytes {
create constraint exclusive;
};
create required link factor: ext::auth::WebAuthnFactor {
create constraint exclusive;
};
};

create type ext::auth::PKCEChallenge extending ext::auth::Auditable {
create required property challenge: std::str {
create constraint exclusive;
Expand Down Expand Up @@ -246,6 +270,20 @@ CREATE EXTENSION PACKAGE auth VERSION '1.0' {
};
};

create type ext::auth::MagicLinkProviderConfig
extending ext::auth::ProviderConfig {
alter property name {
set default := 'builtin::local_magic_link';
set protected := true;
};

create required property token_time_to_live: std::duration {
set default := <std::duration>'10 minutes';
create annotation std::description :=
"The time after which a magic link token expires.";
};
};

create scalar type ext::auth::FlowType extending std::enum<PKCE, Implicit>;

create type ext::auth::UIConfig extending cfg::ConfigObject {
Expand Down
36 changes: 18 additions & 18 deletions edb/schema/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,31 +218,32 @@ def get_subject(self, schema: s_schema.Schema) -> ConsistencySubject:
self.get_field_value(schema, 'subject'),
)

def format_error(
def format_error_message(
self,
schema: s_schema.Schema,
) -> str:
subject = self.get_subject(schema)
titleattr = subject.get_annotation(schema, sn.QualName('std', 'title'))

if not titleattr:
subjname = subject.get_shortname(schema)
subjtitle = subjname.name
title_ann = subject.get_annotation(schema, sn.QualName('std', 'title'))
if title_ann:
subject_name = title_ann
else:
subjtitle = titleattr
short_name = subject.get_shortname(schema)
subject_name = short_name.name

return self.format_error_message(schema, subjtitle)
return self.format_error_text(schema, subject_name)

def format_error_message(
def format_error_text(
self,
schema: s_schema.Schema,
subjtitle: str,
subject_name: str,
) -> str:
errmsg: Optional[str] = self.get_errmessage(schema)
text = self.get_errmessage(schema)
assert text
args = self.get_args(schema)
if args:
args_ql: List[qlast.Base] = [
qlast.Path(steps=[qlast.ObjectRef(name=subjtitle)]),
qlast.Path(steps=[qlast.ObjectRef(name=subject_name)]),
]

args_ql.extend(arg.qlast for arg in args)
Expand All @@ -264,10 +265,9 @@ def format_error_message(
args_map = {name: edgeql.generate_source(val, pretty=False)
for name, val in index_parameters.items()}
else:
args_map = {'__subject__': subjtitle}
args_map = {'__subject__': subject_name}

assert errmsg is not None
return interpolate_errmessage(errmsg, args_map)
return interpolate_error_text(text, args_map)

def as_alter_delta(
self,
Expand Down Expand Up @@ -1578,7 +1578,7 @@ def _get_bases_for_ast(
return ()


def interpolate_errmessage(message: str, args: Dict[str, str]) -> str:
def interpolate_error_text(text: str, args: Dict[str, str]) -> str:
"""
Converts message template "hello {world}! {nope}{{world}}" and
arguments {"world": "Alice", "hell": "Eve"}
Expand All @@ -1589,8 +1589,8 @@ def interpolate_errmessage(message: str, args: Dict[str, str]) -> str:

formatted = ""
last_start = 0
for match in re.finditer(regex, message, flags=0):
formatted += message[last_start : match.start()]
for match in re.finditer(regex, text, flags=0):
formatted += text[last_start : match.start()]
last_start = match.end()

if match[1] is None:
Expand All @@ -1603,5 +1603,5 @@ def interpolate_errmessage(message: str, args: Dict[str, str]) -> str:
# arg not found
formatted += match[0]

formatted += message[last_start:]
formatted += text[last_start:]
return formatted
2 changes: 1 addition & 1 deletion edb/schema/scalars.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ def resolve_sql_type(
) -> Optional[str]:
type, scheme = self.resolve_sql_type_scheme(schema)
if scheme:
return constraints.interpolate_errmessage(
return constraints.interpolate_error_text(
scheme,
{
f'__arg_{i}__': v
Expand Down
31 changes: 31 additions & 0 deletions edb/server/compiler/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,37 @@ def compile(
else:
return unit_group, None

def compile_in_tx_request(
self,
state: dbstate.CompilerConnectionState,
txid: int,
serialized_request: bytes,
original_query: str,
expect_rollback: bool = False,
) -> Tuple[
dbstate.QueryUnitGroup, Optional[dbstate.CompilerConnectionState]
]:
request = rpc.CompilationRequest(
self.state.compilation_config_serializer
)
request.deserialize(serialized_request, original_query)

units, cstate = self.compile_in_tx(
state,
txid,
request.source,
request.output_format,
request.expect_one,
request.implicit_limit,
request.inline_typeids,
request.inline_typenames,
request.protocol_version,
request.inline_objectids,
request.json_parameters,
expect_rollback=expect_rollback,
)
return units, cstate

def compile_in_tx(
self,
state: dbstate.CompilerConnectionState,
Expand Down
12 changes: 9 additions & 3 deletions edb/server/compiler/errormech.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,10 +620,16 @@ def _interpret_constraint_errors(
obj_ptr = obj_type.getptr(schema, sn.UnqualName('id'))
constraint = obj_ptr.get_exclusive_constraints(schema)[0]

msg = constraint.format_error(schema)
# msg is for the "end user" that should not mention pointers and object
# type it is also affected by setting `errmessage` in user schema.
msg = constraint.format_error_message(schema)

# details is for the "developer" that must explain what's going on
# under the hood. It contains verbose descriptions of object involved.
subject = constraint.get_subject(schema)
vname = subject.get_verbosename(schema, with_parent=True)
details = constraint.format_error_message(schema, vname)
subject_description = subject.get_verbosename(schema, with_parent=True)
constraint_description = constraint.get_verbosename(schema)
details = f'violated {constraint_description} on {subject_description}'

if from_graphql:
msg = gql_replace_type_names_in_text(msg)
Expand Down
10 changes: 5 additions & 5 deletions edb/server/compiler/rpc.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,11 @@ cdef class CompilationRequest:
assert buf.read_byte() == 0 # version

flags = buf.read_byte()
self.json_parameters = flags & MASK_JSON_PARAMETERS
self.expect_one = flags & MASK_EXPECT_ONE
self.inline_typeids = flags & MASK_INLINE_TYPEIDS
self.inline_typenames = flags & MASK_INLINE_TYPENAMES
self.inline_objectids = flags & MASK_INLINE_OBJECTIDS
self.json_parameters = flags & MASK_JSON_PARAMETERS > 0
self.expect_one = flags & MASK_EXPECT_ONE > 0
self.inline_typeids = flags & MASK_INLINE_TYPEIDS > 0
self.inline_typenames = flags & MASK_INLINE_TYPENAMES > 0
self.inline_objectids = flags & MASK_INLINE_OBJECTIDS > 0

self.protocol_version = buf.read_int16(), buf.read_int16()
self.output_format = deserialize_output_format(buf.read_byte())
Expand Down
2 changes: 1 addition & 1 deletion edb/server/compiler_pool/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def compile_in_tx(cstate, *args, **kwargs):
cstate = LAST_STATE
else:
cstate = pickle.loads(cstate)
units, cstate = COMPILER.compile_in_tx(cstate, *args, **kwargs)
units, cstate = COMPILER.compile_in_tx_request(cstate, *args, **kwargs)
LAST_STATE = cstate
return units, pickle.dumps(cstate, -1)

Expand Down
11 changes: 2 additions & 9 deletions edb/server/dbview/dbview.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1027,15 +1027,8 @@ cdef class DatabaseConnectionView:
self.txid,
self._last_comp_state,
self._last_comp_state_id,
query_req.source,
query_req.output_format,
query_req.expect_one,
query_req.implicit_limit,
query_req.inline_typeids,
query_req.inline_typenames,
self._protocol_version,
query_req.inline_objectids,
query_req.json_parameters,
query_req.serialize(),
query_req.source.text(),
self.in_tx_error(),
)
else:
Expand Down
Loading

0 comments on commit 081e54a

Please sign in to comment.