Skip to content

Commit 91f0b1e

Browse files
committed
Add renderer-level identifier cache to avoid cross-object method calls
Cache quoted identifiers on AbstractSqlRenderer as a public array, letting all hot-path callers use a simple array lookup instead of dispatching through $platform->quoteIdentifier() on every access.
1 parent b418074 commit 91f0b1e

File tree

8 files changed

+31
-17
lines changed

8 files changed

+31
-17
lines changed

src/Sql/Insert.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public function buildSqlString(AbstractSqlRenderer $renderer): string
158158
if ($columnNames !== []) {
159159
$columns = [];
160160
foreach ($columnNames as $col) {
161-
$columns[] = $renderer->platform->quoteIdentifier($col);
161+
$columns[] = $renderer->identifier[$col] ??= $renderer->platform->quoteIdentifier($col);
162162
}
163163
return $keyword . ' ' . $tableSql
164164
. ' (' . implode(', ', $columns) . ') ' . $selectSql;
@@ -178,7 +178,7 @@ public function buildSqlString(AbstractSqlRenderer $renderer): string
178178
$hasParamContainer = $renderer->parameterContainer instanceof ParameterContainer;
179179

180180
foreach ($this->columns as $column => $value) {
181-
$columns[] = $renderer->platform->quoteIdentifier($column);
181+
$columns[] = $renderer->identifier[$column] ??= $renderer->platform->quoteIdentifier($column);
182182

183183
if ($value === null) {
184184
$values[] = 'NULL';

src/Sql/Part/Columns.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,19 @@ public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', i
6161
$column = $ref->column;
6262

6363
if ($column instanceof Identifier) {
64-
$columnSql = $prefix . $platform->quoteIdentifier($column->identifier);
64+
$columnSql = $prefix
65+
. ($renderer->identifier[$column->identifier]
66+
??= $platform->quoteIdentifier($column->identifier));
6567
} elseif ($column instanceof ArgumentInterface) {
6668
$columnSql = $prefix . $renderer->renderArgument($column, '', $pi);
6769
} else {
6870
$columnSql = $renderer->render($column, $ref->columnAlias ?? 'column');
6971
}
7072

7173
if ($ref->columnAlias !== null) {
72-
$fragments[] = $columnSql . ' AS ' . $platform->quoteIdentifier($ref->columnAlias);
74+
$fragments[] = $columnSql . ' AS '
75+
. ($renderer->identifier[$ref->columnAlias]
76+
??= $platform->quoteIdentifier($ref->columnAlias));
7377
} elseif ($ref->containsAlias) {
7478
$fragments[] = $columnSql;
7579
} else {

src/Sql/Part/GroupBy.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', i
2929
$column = $ref->column;
3030

3131
if ($column instanceof Identifier) {
32-
$groups[] = $platform->quoteIdentifier($column->identifier);
32+
$id = $column->identifier;
33+
$groups[] = $renderer->identifier[$id] ??= $platform->quoteIdentifier($id);
3334
} elseif ($column instanceof ArgumentInterface) {
3435
$pi = 0;
3536
$groups[] = $renderer->renderArgument($column, '', $pi);

src/Sql/Part/InsertSelect.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', i
3434

3535
$columns = [];
3636
foreach (array_keys($this->columns) as $name) {
37-
$columns[] = $renderer->platform->quoteIdentifier($name);
37+
$columns[] = $renderer->identifier[$name] ??= $renderer->platform->quoteIdentifier($name);
3838
}
3939
$columnsSql = implode(', ', $columns);
4040

src/Sql/Part/InsertValues.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', i
4848
$isPdoDriver = $renderer->driver instanceof PdoDriverInterface;
4949

5050
foreach ($this->columnValues as $cv) {
51-
$columns[] = $renderer->platform->quoteIdentifier($cv->column);
51+
$columns[] = $renderer->identifier[$cv->column] ??= $renderer->platform->quoteIdentifier($cv->column);
5252

5353
$values[] = match ($cv->value->getType()) {
5454
ArgumentType::Parameter => $renderer->bindParameter(

src/Sql/Part/OrderBy.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', i
3737
$column = $spec->column;
3838

3939
if ($column instanceof Identifier) {
40-
$orders[] = $platform->quoteIdentifier($column->identifier)
41-
. ' ' . $spec->direction;
40+
$orders[] = ($renderer->identifier[$column->identifier]
41+
??= $platform->quoteIdentifier($column->identifier))
42+
. ' ' . $spec->direction;
4243
} elseif ($column instanceof ArgumentInterface) {
4344
$pi = 0;
4445
$orders[] = $renderer->renderArgument($column, '', $pi)

src/Sql/Part/Set.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', i
3939
$isPdoDriver = $renderer->driver instanceof PdoDriverInterface;
4040

4141
foreach ($this->model as $column => $arg) {
42-
$prefix = $renderer->platform->quoteIdentifier($this->columnIds[$column]->identifier) . ' = ';
42+
$id = $this->columnIds[$column]->identifier;
43+
$prefix = ($renderer->identifier[$id] ??= $renderer->platform->quoteIdentifier($id)) . ' = ';
4344

4445
$setSql[] = $prefix . match ($arg->getType()) {
4546
ArgumentType::Parameter => $renderer->bindParameter(

src/Sql/Platform/AbstractSqlRenderer.php

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ abstract class AbstractSqlRenderer
4646

4747
private string $identifierSeparator = '.';
4848

49+
/** @var array<string, string> */
50+
public array $identifier = [];
51+
4952
/** @var array<int, string> */
5053
private array $tablePrefixCache = [];
5154

@@ -67,6 +70,7 @@ public function init(
6770
$this->platform = $platform;
6871
$this->identifierSeparator = $platform->getIdentifierSeparator();
6972
$this->tablePrefixCache = [];
73+
$this->identifier = [];
7074
}
7175

7276
$this->driver = $driver;
@@ -120,14 +124,14 @@ public function renderTableSource(
120124
} elseif ($table instanceof Select) {
121125
$rendered = '(' . $this->processSubSelect($table) . ')';
122126
} elseif (is_string($table)) {
123-
$rendered = $this->platform->quoteIdentifier($table);
127+
$rendered = $this->identifier[$table] ??= $this->platform->quoteIdentifier($table);
124128
} else {
125129
$pi = 0;
126130
$rendered = $table->toSql($this, '', $pi);
127131
}
128132

129133
if ($alias !== null) {
130-
$rendered .= ' AS ' . $this->platform->quoteIdentifier($alias);
134+
$rendered .= ' AS ' . ($this->identifier[$alias] ??= $this->platform->quoteIdentifier($alias));
131135
}
132136

133137
return $rendered;
@@ -143,10 +147,10 @@ public function renderResolvedTable(
143147

144148
if ($table instanceof TableIdentifier) {
145149
$prefix = $alias !== null
146-
? $this->platform->quoteIdentifier($alias)
150+
? ($this->identifier[$alias] ??= $this->platform->quoteIdentifier($alias))
147151
: $this->platform->quoteIdentifier(name: $table->table, prefix: $table->schema);
148152
} else {
149-
$prefix = $this->platform->quoteIdentifier($alias);
153+
$prefix = $this->identifier[$alias] ??= $this->platform->quoteIdentifier($alias);
150154
}
151155

152156
return $this->tablePrefixCache[$id] = $prefix . $this->identifierSeparator;
@@ -158,7 +162,8 @@ public function renderIdentifiersIn(string $part): string
158162
$count = count($identifiers);
159163

160164
for ($idx = 1; $idx < $count; $idx += 2) {
161-
$identifiers[$idx] = $this->platform->quoteIdentifier($identifiers[$idx]);
165+
$id = $identifiers[$idx];
166+
$identifiers[$idx] = $this->identifier[$id] ??= $this->platform->quoteIdentifier($id);
162167
}
163168

164169
return implode('', $identifiers);
@@ -184,7 +189,8 @@ public function renderArgument(
184189
int &$paramIndex,
185190
): string {
186191
return match (true) {
187-
$argument instanceof Identifier => $this->platform->quoteIdentifier($argument->identifier),
192+
$argument instanceof Identifier => $this->identifier[$argument->identifier]
193+
??= $this->platform->quoteIdentifier($argument->identifier),
188194
$argument instanceof Literal => $argument->literal,
189195
$argument instanceof NullValue => 'NULL',
190196
$argument instanceof Parameter => $this->bindParameter($argument),
@@ -245,7 +251,8 @@ private function renderIdentifiers(array $identifiers): string
245251
{
246252
$quoted = [];
247253
foreach ($identifiers as $id) {
248-
$quoted[] = $this->platform->quoteIdentifier($id->identifier);
254+
$name = $id->identifier;
255+
$quoted[] = $this->identifier[$name] ??= $this->platform->quoteIdentifier($name);
249256
}
250257
return implode(', ', $quoted);
251258
}

0 commit comments

Comments
 (0)