Skip to content

Commit ecabda4

Browse files
authored
Remove extra blob arg indexes from server param conversions. (#8612)
The server param conversions passed in a `extra_blob_arg_indexes` which described how to extract the parameter's conversion data from the extra blobs. This is redundant if the bind_args_index is extended to index into the extra blobs.
1 parent 6bed5db commit ecabda4

File tree

10 files changed

+101
-198
lines changed

10 files changed

+101
-198
lines changed

edb/_edgeql_parser.pyi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class Entry:
3838
extra_counts: list[int]
3939

4040
def get_variables(self) -> dict[str, typing.Any]: ...
41-
def get_extra_variable_indexes(self) -> dict[str, tuple[int, int]]: ...
4241
def pack(self) -> bytes: ...
4342

4443
def normalize(text: str) -> Entry: ...

edb/edgeql-parser/edgeql-parser-python/src/pynormalize.rs

Lines changed: 12 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use gel_protocol::codec;
88
use gel_protocol::model::{BigInt, Decimal};
99
use pyo3::exceptions::{PyAssertionError, PyValueError};
1010
use pyo3::prelude::*;
11-
use pyo3::types::{PyBytes, PyDict, PyFloat, PyInt, PyList, PyString, PyTuple};
11+
use pyo3::types::{PyBytes, PyDict, PyFloat, PyInt, PyList, PyString};
1212

1313
use crate::errors::SyntaxError;
1414
use crate::normalize::{normalize as _normalize, Error, PackedEntry, Variable};
@@ -74,23 +74,22 @@ impl Entry {
7474
impl Entry {
7575
fn get_variables(&self, py: Python) -> PyResult<PyObject> {
7676
let vars = PyDict::new(py);
77-
for (param_name, _, _, value) in VariableNameIter::new(self) {
78-
vars.set_item(param_name, TokenizerValue(value))?;
77+
let first = match self.first_extra {
78+
Some(first) => first,
79+
None => return Ok(vars.into()),
80+
};
81+
for (idx, var) in self.entry_pack.variables.iter().flatten().enumerate() {
82+
let s = if self.extra_named {
83+
format!("__edb_arg_{}", first + idx)
84+
} else {
85+
(first + idx).to_string()
86+
};
87+
vars.set_item(s, TokenizerValue(&var.value))?;
7988
}
8089

8190
Ok(vars.into())
8291
}
8392

84-
// This function returns a dictionary mapping normalized parameter names to their blob and var indexes.
85-
fn get_extra_variable_indexes(&self, py: Python) -> PyResult<PyObject> {
86-
let indexes = PyDict::new(py);
87-
for (param_name, blob_index, var_index, _) in VariableNameIter::new(self) {
88-
indexes.set_item(param_name, PyTuple::new(py, [blob_index, var_index])?)?;
89-
}
90-
91-
Ok(indexes.into())
92-
}
93-
9493
fn pack(&self, py: Python) -> PyResult<PyObject> {
9594
let mut buf = vec![1u8]; // type and version
9695
bincode::serialize_into(&mut buf, &self.entry_pack)
@@ -99,69 +98,6 @@ impl Entry {
9998
}
10099
}
101100

102-
struct VariableNameIter<'a> {
103-
entry_pack: &'a PackedEntry,
104-
first_extra: Option<usize>,
105-
extra_named: bool,
106-
name_index: usize,
107-
blob_index: usize,
108-
var_index: usize,
109-
}
110-
111-
impl<'a> VariableNameIter<'a> {
112-
pub fn new(entry: &'a Entry) -> Self {
113-
VariableNameIter {
114-
entry_pack: &entry.entry_pack,
115-
first_extra: entry.first_extra,
116-
extra_named: entry.extra_named,
117-
name_index: 0,
118-
blob_index: 0,
119-
var_index: 0,
120-
}
121-
}
122-
}
123-
124-
impl<'a> Iterator for VariableNameIter<'a> {
125-
type Item = (String, usize, usize, &'a Value);
126-
127-
fn next(&mut self) -> Option<Self::Item> {
128-
// Check termination
129-
let first = self.first_extra?;
130-
if self.blob_index >= self.entry_pack.variables.len() {
131-
return None;
132-
}
133-
if self.var_index >= self.entry_pack.variables[self.blob_index].len() {
134-
return None;
135-
}
136-
137-
// Get result
138-
let blob_vars = self.entry_pack.variables.get(self.blob_index)?;
139-
140-
let name = if self.extra_named {
141-
format!("__edb_arg_{}", first + self.name_index)
142-
} else {
143-
(first + self.name_index).to_string()
144-
};
145-
146-
let result = (
147-
name,
148-
self.blob_index,
149-
self.var_index,
150-
&blob_vars[self.var_index].value,
151-
);
152-
153-
// Advance indexes
154-
self.var_index += 1;
155-
if self.var_index >= blob_vars.len() {
156-
self.var_index = 0;
157-
self.blob_index += 1;
158-
}
159-
self.name_index += 1;
160-
161-
Some(result)
162-
}
163-
}
164-
165101
pub fn serialize_extra(variables: &[Variable]) -> Result<Bytes, String> {
166102
use gel_protocol::codec::Codec;
167103
use gel_protocol::value::Value as P;

edb/edgeql/compiler/context.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,6 @@ class ServerParamConversion:
145145
volatility: qltypes.Volatility
146146

147147
# If the parameter is a query parameter, track its script params index.
148-
# This is passed to the server if the query parameter is not a normalized
149-
# constant.
150148
script_param_index: Optional[int] = None
151149

152150
# If the parameter is a constant value, pass to directly to the server.

edb/edgeql/tokenizer.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ def extra_counts(self) -> Sequence[int]:
7777
def extra_blobs(self) -> list[bytes]:
7878
return []
7979

80-
def extra_variable_indexes(self) -> dict[str, tuple[int, int]]:
81-
return {}
82-
8380
def extra_formatted_as_text(self) -> bool:
8481
return False
8582

@@ -116,7 +113,6 @@ def __init__(
116113
self._first_extra = normalized.first_extra
117114
self._extra_counts = normalized.extra_counts
118115
self._extra_blobs = normalized.extra_blobs
119-
self._extra_variable_indexes = normalized.get_extra_variable_indexes()
120116
self._serialized = serialized
121117

122118
def text(self) -> str:
@@ -140,9 +136,6 @@ def extra_counts(self) -> Sequence[int]:
140136
def extra_blobs(self) -> list[bytes]:
141137
return self._extra_blobs
142138

143-
def extra_variable_indexes(self) -> dict[str, tuple[int, int]]:
144-
return self._extra_variable_indexes
145-
146139
@staticmethod
147140
def from_string(text: str) -> NormalizedSource:
148141
normalized = _normalize(text)

edb/ir/ast.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -779,8 +779,6 @@ class ServerParamConversion:
779779
additional_info: tuple[str, ...]
780780

781781
# If the parameter is a query parameter, track its script params index.
782-
# This is passed to the server if the query parameter is not a normalized
783-
# constant.
784782
script_param_index: typing.Optional[int] = None
785783

786784
# If the parameter is a constant value, pass to directly to the server.

edb/server/compiler/compiler.py

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,45 +1925,20 @@ def _compile_ql_query(
19251925
list[dbstate.ServerParamConversion]
19261926
] = None
19271927
if isinstance(ir, irast.Statement) and ir.server_param_conversions:
1928-
# A server param conversion is either:
1929-
# - a query parameter
1930-
# eg. `<str>$my_var`;
1931-
# - a normalized constant
1932-
# eg. `select 1` normalizes to `select <int64>$0`; or,
1933-
# - a constant value, when a conversion is part of a schema expression,
1934-
# no normalization takes place.
1935-
#
19361928
# The irast.ServerParamConversion we get from the ql compiler contains
19371929
# either a script_param_index or a constant value.
19381930
#
1939-
# The script_param_index may refer to either a query param or a
1940-
# normalized constant. We need to check the source's extra variable
1941-
# indexes to see if a param_name refers to an normalized constant.
1942-
#
1943-
# If a parameter is a normalized constant, pass on the blob and arg
1944-
# indexes to the server.
1931+
# A script_param_index can refer to either an actual query param or a
1932+
# constant that was normalized out of a query.
19451933
#
1946-
# Query parameters and constant values can be passed on as they are.
1947-
1948-
extra_variable_indexes = (
1949-
ctx.source.extra_variable_indexes() if ctx.source else {}
1950-
)
1934+
# A constant value is used as is by the server.
19511935

19521936
server_param_conversions = [
19531937
dbstate.ServerParamConversion(
19541938
param_name=p.param_name,
19551939
conversion_name=p.conversion_name,
19561940
additional_info=p.additional_info,
1957-
bind_args_index=(
1958-
p.script_param_index
1959-
if p.param_name not in extra_variable_indexes else
1960-
None
1961-
),
1962-
extra_blob_arg_indexes=(
1963-
extra_variable_indexes[p.param_name]
1964-
if p.param_name in extra_variable_indexes else
1965-
None
1966-
),
1941+
script_param_index=p.script_param_index,
19671942
constant_value=p.constant_value
19681943
)
19691944
for p in ir.server_param_conversions

edb/server/compiler/dbstate.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,7 @@ class ServerParamConversion:
106106
additional_info: tuple[str, ...]
107107

108108
# If the parameter is a query parameter, track its bind_args index.
109-
bind_args_index: Optional[int] = None
110-
111-
# If the parameter was originally a literal which was normalized,
112-
# store the location in the extra blobs to find its encoded data.
113-
#
114-
# The location is stored as a tuple of:
115-
# - blob index
116-
# - arg index
117-
extra_blob_arg_indexes: Optional[tuple[int, int]] = None
109+
script_param_index: Optional[int] = None
118110

119111
# If the parameter is a constant value, pass to directly to the server.
120112
constant_value: Optional[Any] = None

edb/server/protocol/args_ser.pxd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ cdef list[ParamConversion] get_param_conversions(
6767
)
6868

6969
cdef dict[int, bytes] get_args_data_for_indexes(
70-
bytes args,
70+
bytes bind_args,
71+
list[bytes] extra_blobs,
7172
list[int] target_indexes,
72-
args_needs_recoding: bool,
7373
)
7474

7575
cdef class ConvertedArg:

0 commit comments

Comments
 (0)