packages/ztd-query-postgres/tests/Unit/Sql/Value/PgSqlCastRendererTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Value;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use ZtdQuery\Platform\Postgres\Sql\Value\PgSqlCastRenderer;
9use ZtdQuery\Schema\ColumnDeclaration;
10use ZtdQuery\Schema\ColumnTypeFamily;
11
12#[CoversClass(PgSqlCastRenderer::class)]
13#[CoversClass(\ZtdQuery\Platform\Postgres\Sql\Value\CastTypeMapper::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Platform\Postgres\Sql\Value\NativeCastTarget::class)]
15final class PgSqlCastRendererTest extends \PHPUnit\Framework\TestCase
16{
17 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::INTEGER, 'INTEGER'])]
18 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::FLOAT, 'REAL'])]
19 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DOUBLE, 'DOUBLE PRECISION'])]
20 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DECIMAL, 'NUMERIC(10,2)'])]
21 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::STRING, 'VARCHAR(255)'])]
22 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TEXT, 'TEXT'])]
23 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BOOLEAN, 'BOOLEAN'])]
24 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATE, 'DATE'])]
25 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIME, 'TIME'])]
26 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATETIME, 'TIMESTAMP'])]
27 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIMESTAMP, 'TIMESTAMPTZ'])]
28 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BINARY, 'BYTEA'])]
29 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::JSON, 'JSONB'])]
30 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::UNKNOWN, 'UUID'])]
31 public function testRenderCastReturnsNonEmptyString(ColumnTypeFamily $family, string $nativeType): void
32 {
33 $renderer = new PgSqlCastRenderer();
34 $type = new ColumnDeclaration($family, $nativeType);
35 $result = $renderer->renderCast("'test'", $type);
36 self::assertNotEmpty($result, sprintf('renderCast returned empty string for family %s', $family->value));
37 }
38 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::INTEGER, 'INTEGER'])]
39 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::FLOAT, 'REAL'])]
40 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DOUBLE, 'DOUBLE PRECISION'])]
41 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DECIMAL, 'NUMERIC(10,2)'])]
42 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::STRING, 'VARCHAR(255)'])]
43 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TEXT, 'TEXT'])]
44 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BOOLEAN, 'BOOLEAN'])]
45 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATE, 'DATE'])]
46 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIME, 'TIME'])]
47 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATETIME, 'TIMESTAMP'])]
48 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIMESTAMP, 'TIMESTAMPTZ'])]
49 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BINARY, 'BYTEA'])]
50 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::JSON, 'JSONB'])]
51 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::UNKNOWN, 'UUID'])]
52 public function testRenderNullCastReturnsNonEmptyString(ColumnTypeFamily $family, string $nativeType): void
53 {
54 $renderer = new PgSqlCastRenderer();
55 $type = new ColumnDeclaration($family, $nativeType);
56 $result = $renderer->renderNullCast($type);
57 self::assertNotEmpty($result, sprintf('renderNullCast returned empty string for family %s', $family->value));
58 }
59 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::INTEGER, 'INTEGER'])]
60 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::FLOAT, 'REAL'])]
61 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DOUBLE, 'DOUBLE PRECISION'])]
62 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DECIMAL, 'NUMERIC(10,2)'])]
63 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::STRING, 'VARCHAR(255)'])]
64 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TEXT, 'TEXT'])]
65 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BOOLEAN, 'BOOLEAN'])]
66 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATE, 'DATE'])]
67 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIME, 'TIME'])]
68 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATETIME, 'TIMESTAMP'])]
69 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIMESTAMP, 'TIMESTAMPTZ'])]
70 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BINARY, 'BYTEA'])]
71 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::JSON, 'JSONB'])]
72 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::UNKNOWN, 'UUID'])]
73 public function testRenderNullCastContainsCastKeyword(ColumnTypeFamily $family, string $nativeType): void
74 {
75 $renderer = new PgSqlCastRenderer();
76 $type = new ColumnDeclaration($family, $nativeType);
77 $result = $renderer->renderNullCast($type);
78 self::assertStringContainsString('CAST(', strtoupper($result), sprintf('renderNullCast output for family %s does not contain CAST(', $family->value));
79 }
80 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::INTEGER, 'INTEGER'])]
81 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::FLOAT, 'REAL'])]
82 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DOUBLE, 'DOUBLE PRECISION'])]
83 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DECIMAL, 'NUMERIC(10,2)'])]
84 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::STRING, 'VARCHAR(255)'])]
85 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TEXT, 'TEXT'])]
86 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BOOLEAN, 'BOOLEAN'])]
87 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATE, 'DATE'])]
88 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIME, 'TIME'])]
89 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATETIME, 'TIMESTAMP'])]
90 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIMESTAMP, 'TIMESTAMPTZ'])]
91 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BINARY, 'BYTEA'])]
92 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::JSON, 'JSONB'])]
93 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::UNKNOWN, 'UUID'])]
94 public function testRenderNullCastContainsNullKeyword(ColumnTypeFamily $family, string $nativeType): void
95 {
96 $renderer = new PgSqlCastRenderer();
97 $type = new ColumnDeclaration($family, $nativeType);
98 $result = $renderer->renderNullCast($type);
99 self::assertStringContainsString('NULL', strtoupper($result), sprintf('renderNullCast output for family %s does not contain NULL', $family->value));
100 }
101 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::INTEGER, 'INTEGER'])]
102 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::FLOAT, 'REAL'])]
103 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DOUBLE, 'DOUBLE PRECISION'])]
104 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DECIMAL, 'NUMERIC(10,2)'])]
105 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::STRING, 'VARCHAR(255)'])]
106 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TEXT, 'TEXT'])]
107 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BOOLEAN, 'BOOLEAN'])]
108 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATE, 'DATE'])]
109 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIME, 'TIME'])]
110 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::DATETIME, 'TIMESTAMP'])]
111 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::TIMESTAMP, 'TIMESTAMPTZ'])]
112 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::BINARY, 'BYTEA'])]
113 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::JSON, 'JSONB'])]
114 #[\PHPUnit\Framework\Attributes\TestWith([ColumnTypeFamily::UNKNOWN, 'UUID'])]
115 public function testAllColumnTypeFamiliesHandled(ColumnTypeFamily $family, string $nativeType): void
116 {
117 $renderer = new PgSqlCastRenderer();
118 $type = new ColumnDeclaration($family, $nativeType);
119 $castResult = $renderer->renderCast("'value'", $type);
120 $nullResult = $renderer->renderNullCast($type);
121 self::assertNotEmpty($castResult, sprintf('renderCast returned empty for family %s', $family->value));
122 self::assertNotEmpty($nullResult, sprintf('renderNullCast returned empty for family %s', $family->value));
123 }
124 public function testRenderCastForIntegerProducesExactForm(): void
125 {
126 $renderer = new PgSqlCastRenderer();
127 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INTEGER');
128 $result = $renderer->renderCast("'42'", $type);
129 self::assertMatchesRegularExpression('/^CAST\(\'42\'\s+AS\s+\S+\)$/i', $result, 'renderCast for INTEGER must produce CAST(expression AS type) format');
130 }
131 public function testRenderNullCastProducesExactForm(): void
132 {
133 $renderer = new PgSqlCastRenderer();
134 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INTEGER');
135 $result = $renderer->renderNullCast($type);
136 self::assertMatchesRegularExpression('/^CAST\(NULL\s+AS\s+\S+\)$/i', $result, 'renderNullCast must produce CAST(NULL AS type) format');
137 }
138 public function testRenderCastForStringIncludesStringType(): void
139 {
140 $renderer = new PgSqlCastRenderer();
141 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'VARCHAR(255)');
142 $result = $renderer->renderCast("'hello'", $type);
143 $upper = strtoupper($result);
144 self::assertTrue(str_contains($upper, 'VARCHAR') || str_contains($upper, 'TEXT') || str_contains($upper, 'CHAR'), sprintf('renderCast for STRING must include VARCHAR, TEXT, or CHAR, got: %s', $result));
145 }
146 public function testRenderCastIsDeterministic(): void
147 {
148 $renderer = new PgSqlCastRenderer();
149 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INTEGER');
150 self::assertSame($renderer->renderNullCast($type), $renderer->renderNullCast($type));
151 }
152 public function testRenderCastInteger(): void
153 {
154 $renderer = new PgSqlCastRenderer();
155 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INTEGER');
156 self::assertSame("CAST('42' AS INTEGER)", $renderer->renderCast("'42'", $type));
157 }
158 public function testRenderCastBigIntPreservesWidth(): void
159 {
160 $renderer = new PgSqlCastRenderer();
161 self::assertSame('CAST(9223372036854775807 AS BIGINT)', $renderer->renderCast('9223372036854775807', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'BIGINT')));
162 }
163 public function testRenderCastPreservesArrayType(): void
164 {
165 $renderer = new PgSqlCastRenderer();
166 self::assertSame("CAST('{1,2}' AS INT4[])", $renderer->renderCast("'{1,2}'", new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INT4[]')));
167 }
168 public function testRenderCastTrimsArrayType(): void
169 {
170 $renderer = new PgSqlCastRenderer();
171 self::assertSame("CAST('{1,2}' AS INT4[])", $renderer->renderCast("'{1,2}'", new ColumnDeclaration(ColumnTypeFamily::INTEGER, ' INT4[] ')));
172 }
173 public function testRenderCastPreservesInt2Alias(): void
174 {
175 $renderer = new PgSqlCastRenderer();
176 self::assertSame('CAST(1 AS SMALLINT)', $renderer->renderCast('1', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'int2')));
177 }
178 public function testRenderCastPreservesSmallIntAlias(): void
179 {
180 $renderer = new PgSqlCastRenderer();
181 self::assertSame('CAST(1 AS SMALLINT)', $renderer->renderCast('1', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'smallint')));
182 }
183 public function testRenderCastPreservesSmallSerialAlias(): void
184 {
185 $renderer = new PgSqlCastRenderer();
186 self::assertSame('CAST(1 AS SMALLINT)', $renderer->renderCast('1', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'smallserial')));
187 }
188 public function testRenderCastPreservesInt8Alias(): void
189 {
190 $renderer = new PgSqlCastRenderer();
191 self::assertSame('CAST(1 AS BIGINT)', $renderer->renderCast('1', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'int8')));
192 }
193 public function testRenderCastPreservesBigIntAlias(): void
194 {
195 $renderer = new PgSqlCastRenderer();
196 self::assertSame('CAST(1 AS BIGINT)', $renderer->renderCast('1', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'bigint')));
197 }
198 public function testRenderCastPreservesBigSerialAlias(): void
199 {
200 $renderer = new PgSqlCastRenderer();
201 self::assertSame('CAST(1 AS BIGINT)', $renderer->renderCast('1', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'bigserial')));
202 }
203 public function testRenderNullCastInteger(): void
204 {
205 $renderer = new PgSqlCastRenderer();
206 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INTEGER');
207 self::assertSame('CAST(NULL AS INTEGER)', $renderer->renderNullCast($type));
208 }
209 public function testRenderNullCastString(): void
210 {
211 $renderer = new PgSqlCastRenderer();
212 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'VARCHAR(255)');
213 self::assertSame('CAST(NULL AS VARCHAR(255))', $renderer->renderNullCast($type));
214 }
215 public function testRenderNullCastText(): void
216 {
217 $renderer = new PgSqlCastRenderer();
218 $type = new ColumnDeclaration(ColumnTypeFamily::TEXT, 'TEXT');
219 self::assertSame('CAST(NULL AS TEXT)', $renderer->renderNullCast($type));
220 }
221 public function testRenderNullCastBoolean(): void
222 {
223 $renderer = new PgSqlCastRenderer();
224 $type = new ColumnDeclaration(ColumnTypeFamily::BOOLEAN, 'BOOLEAN');
225 self::assertSame('CAST(NULL AS BOOLEAN)', $renderer->renderNullCast($type));
226 }
227 public function testRenderNullCastFloat(): void
228 {
229 $renderer = new PgSqlCastRenderer();
230 $type = new ColumnDeclaration(ColumnTypeFamily::FLOAT, 'REAL');
231 self::assertSame('CAST(NULL AS REAL)', $renderer->renderNullCast($type));
232 }
233 public function testRenderNullCastDouble(): void
234 {
235 $renderer = new PgSqlCastRenderer();
236 $type = new ColumnDeclaration(ColumnTypeFamily::DOUBLE, 'DOUBLE PRECISION');
237 self::assertSame('CAST(NULL AS DOUBLE PRECISION)', $renderer->renderNullCast($type));
238 }
239 public function testRenderNullCastDecimal(): void
240 {
241 $renderer = new PgSqlCastRenderer();
242 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'NUMERIC(10,2)');
243 self::assertSame('CAST(NULL AS NUMERIC(10,2))', $renderer->renderNullCast($type));
244 }
245 public function testRenderNullCastDate(): void
246 {
247 $renderer = new PgSqlCastRenderer();
248 $type = new ColumnDeclaration(ColumnTypeFamily::DATE, 'DATE');
249 self::assertSame('CAST(NULL AS DATE)', $renderer->renderNullCast($type));
250 }
251 public function testRenderNullCastTime(): void
252 {
253 $renderer = new PgSqlCastRenderer();
254 $type = new ColumnDeclaration(ColumnTypeFamily::TIME, 'TIME');
255 self::assertSame('CAST(NULL AS TIME)', $renderer->renderNullCast($type));
256 }
257 public function testRenderNullCastDatetime(): void
258 {
259 $renderer = new PgSqlCastRenderer();
260 $type = new ColumnDeclaration(ColumnTypeFamily::DATETIME, 'TIMESTAMP');
261 self::assertSame('CAST(NULL AS TIMESTAMP)', $renderer->renderNullCast($type));
262 }
263 public function testRenderNullCastTimestamp(): void
264 {
265 $renderer = new PgSqlCastRenderer();
266 $type = new ColumnDeclaration(ColumnTypeFamily::TIMESTAMP, 'TIMESTAMPTZ');
267 self::assertSame('CAST(NULL AS TIMESTAMP)', $renderer->renderNullCast($type));
268 }
269 public function testRenderNullCastBinary(): void
270 {
271 $renderer = new PgSqlCastRenderer();
272 $type = new ColumnDeclaration(ColumnTypeFamily::BINARY, 'BYTEA');
273 self::assertSame('CAST(NULL AS BYTEA)', $renderer->renderNullCast($type));
274 }
275 public function testRenderNullCastJson(): void
276 {
277 $renderer = new PgSqlCastRenderer();
278 $type = new ColumnDeclaration(ColumnTypeFamily::JSON, 'JSONB');
279 self::assertSame('CAST(NULL AS JSONB)', $renderer->renderNullCast($type));
280 }
281 public function testRenderNullCastUnknownUsesNativeType(): void
282 {
283 $renderer = new PgSqlCastRenderer();
284 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'UUID');
285 self::assertSame('CAST(NULL AS UUID)', $renderer->renderNullCast($type));
286 }
287 public function testRenderNullCastUnknownEmptyNativeType(): void
288 {
289 $renderer = new PgSqlCastRenderer();
290 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, '');
291 self::assertSame('CAST(NULL AS TEXT)', $renderer->renderNullCast($type));
292 }
293 public function testColumnTypeFamilyIntegerHandled(): void
294 {
295 $renderer = new PgSqlCastRenderer();
296 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'SOME_TYPE');
297 $result = $renderer->renderNullCast($type);
298 self::assertNotEmpty($result);
299 self::assertStringContainsString('CAST(', $result);
300 }
301 public function testColumnTypeFamilyFloatHandled(): void
302 {
303 $renderer = new PgSqlCastRenderer();
304 $type = new ColumnDeclaration(ColumnTypeFamily::FLOAT, 'SOME_TYPE');
305 $result = $renderer->renderNullCast($type);
306 self::assertNotEmpty($result);
307 self::assertStringContainsString('CAST(', $result);
308 }
309 public function testColumnTypeFamilyDoubleHandled(): void
310 {
311 $renderer = new PgSqlCastRenderer();
312 $type = new ColumnDeclaration(ColumnTypeFamily::DOUBLE, 'SOME_TYPE');
313 $result = $renderer->renderNullCast($type);
314 self::assertNotEmpty($result);
315 self::assertStringContainsString('CAST(', $result);
316 }
317 public function testColumnTypeFamilyDecimalHandled(): void
318 {
319 $renderer = new PgSqlCastRenderer();
320 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'SOME_TYPE');
321 $result = $renderer->renderNullCast($type);
322 self::assertNotEmpty($result);
323 self::assertStringContainsString('CAST(', $result);
324 }
325 public function testColumnTypeFamilyStringHandled(): void
326 {
327 $renderer = new PgSqlCastRenderer();
328 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'SOME_TYPE');
329 $result = $renderer->renderNullCast($type);
330 self::assertNotEmpty($result);
331 self::assertStringContainsString('CAST(', $result);
332 }
333 public function testColumnTypeFamilyTextHandled(): void
334 {
335 $renderer = new PgSqlCastRenderer();
336 $type = new ColumnDeclaration(ColumnTypeFamily::TEXT, 'SOME_TYPE');
337 $result = $renderer->renderNullCast($type);
338 self::assertNotEmpty($result);
339 self::assertStringContainsString('CAST(', $result);
340 }
341 public function testColumnTypeFamilyBooleanHandled(): void
342 {
343 $renderer = new PgSqlCastRenderer();
344 $type = new ColumnDeclaration(ColumnTypeFamily::BOOLEAN, 'SOME_TYPE');
345 $result = $renderer->renderNullCast($type);
346 self::assertNotEmpty($result);
347 self::assertStringContainsString('CAST(', $result);
348 }
349 public function testColumnTypeFamilyDateHandled(): void
350 {
351 $renderer = new PgSqlCastRenderer();
352 $type = new ColumnDeclaration(ColumnTypeFamily::DATE, 'SOME_TYPE');
353 $result = $renderer->renderNullCast($type);
354 self::assertNotEmpty($result);
355 self::assertStringContainsString('CAST(', $result);
356 }
357 public function testColumnTypeFamilyTimeHandled(): void
358 {
359 $renderer = new PgSqlCastRenderer();
360 $type = new ColumnDeclaration(ColumnTypeFamily::TIME, 'SOME_TYPE');
361 $result = $renderer->renderNullCast($type);
362 self::assertNotEmpty($result);
363 self::assertStringContainsString('CAST(', $result);
364 }
365 public function testColumnTypeFamilyDatetimeHandled(): void
366 {
367 $renderer = new PgSqlCastRenderer();
368 $type = new ColumnDeclaration(ColumnTypeFamily::DATETIME, 'SOME_TYPE');
369 $result = $renderer->renderNullCast($type);
370 self::assertNotEmpty($result);
371 self::assertStringContainsString('CAST(', $result);
372 }
373 public function testColumnTypeFamilyTimestampHandled(): void
374 {
375 $renderer = new PgSqlCastRenderer();
376 $type = new ColumnDeclaration(ColumnTypeFamily::TIMESTAMP, 'SOME_TYPE');
377 $result = $renderer->renderNullCast($type);
378 self::assertNotEmpty($result);
379 self::assertStringContainsString('CAST(', $result);
380 }
381 public function testColumnTypeFamilyBinaryHandled(): void
382 {
383 $renderer = new PgSqlCastRenderer();
384 $type = new ColumnDeclaration(ColumnTypeFamily::BINARY, 'SOME_TYPE');
385 $result = $renderer->renderNullCast($type);
386 self::assertNotEmpty($result);
387 self::assertStringContainsString('CAST(', $result);
388 }
389 public function testColumnTypeFamilyJsonHandled(): void
390 {
391 $renderer = new PgSqlCastRenderer();
392 $type = new ColumnDeclaration(ColumnTypeFamily::JSON, 'SOME_TYPE');
393 $result = $renderer->renderNullCast($type);
394 self::assertNotEmpty($result);
395 self::assertStringContainsString('CAST(', $result);
396 }
397 public function testColumnTypeFamilyUnknownHandled(): void
398 {
399 $renderer = new PgSqlCastRenderer();
400 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'SOME_TYPE');
401 $result = $renderer->renderNullCast($type);
402 self::assertNotEmpty($result);
403 self::assertStringContainsString('CAST(', $result);
404 }
405 public function testRenderCastDecimalWithPrecisionAndScale(): void
406 {
407 $renderer = new PgSqlCastRenderer();
408 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'NUMERIC(10,2)');
409 self::assertSame("CAST('42.5' AS NUMERIC(10,2))", $renderer->renderCast("'42.5'", $type));
410 }
411 public function testRenderCastDecimalWithPrecisionOnly(): void
412 {
413 $renderer = new PgSqlCastRenderer();
414 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'NUMERIC(8)');
415 self::assertSame("CAST('100' AS NUMERIC(8,0))", $renderer->renderCast("'100'", $type));
416 }
417 public function testRenderCastDecimalBare(): void
418 {
419 $renderer = new PgSqlCastRenderer();
420 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'NUMERIC');
421 self::assertSame("CAST('99' AS NUMERIC)", $renderer->renderCast("'99'", $type));
422 }
423 public function testRenderCastDecimalLowercaseNativeType(): void
424 {
425 $renderer = new PgSqlCastRenderer();
426 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'numeric(10,2)');
427 self::assertSame("CAST('42.5' AS NUMERIC(10,2))", $renderer->renderCast("'42.5'", $type));
428 }
429 public function testRenderCastDecimalFromDecimalKeyword(): void
430 {
431 $renderer = new PgSqlCastRenderer();
432 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'DECIMAL(12,4)');
433 self::assertSame("CAST('3.14' AS NUMERIC(12,4))", $renderer->renderCast("'3.14'", $type));
434 }
435 public function testRenderCastStringWithVarcharLength(): void
436 {
437 $renderer = new PgSqlCastRenderer();
438 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'VARCHAR(100)');
439 self::assertSame("CAST('hi' AS VARCHAR(100))", $renderer->renderCast("'hi'", $type));
440 }
441 public function testRenderCastStringLowercaseVarchar(): void
442 {
443 $renderer = new PgSqlCastRenderer();
444 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'varchar(50)');
445 self::assertSame("CAST('hi' AS VARCHAR(50))", $renderer->renderCast("'hi'", $type));
446 }
447 public function testRenderCastStringWithoutLength(): void
448 {
449 $renderer = new PgSqlCastRenderer();
450 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'VARCHAR');
451 self::assertSame("CAST('hi' AS VARCHAR)", $renderer->renderCast("'hi'", $type));
452 }
453 public function testRenderCastCharacterVaryingWithoutLength(): void
454 {
455 $renderer = new PgSqlCastRenderer();
456 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'CHARACTER VARYING');
457 self::assertSame("CAST('hi' AS VARCHAR)", $renderer->renderCast("'hi'", $type));
458 }
459 public function testRenderCastUnknownStringNativeTypeFallsBackToText(): void
460 {
461 $renderer = new PgSqlCastRenderer();
462 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'CUSTOM_STRING');
463 self::assertSame("CAST('hi' AS TEXT)", $renderer->renderCast("'hi'", $type));
464 }
465 public function testRenderCastDecimalLowercaseDecimalKeyword(): void
466 {
467 $renderer = new PgSqlCastRenderer();
468 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'decimal(5,2)');
469 self::assertSame("CAST('1.0' AS NUMERIC(5,2))", $renderer->renderCast("'1.0'", $type));
470 }
471 public function testRenderCastDecimalPrecisionOnlyLowercase(): void
472 {
473 $renderer = new PgSqlCastRenderer();
474 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'decimal(6)');
475 self::assertSame("CAST('1' AS NUMERIC(6,0))", $renderer->renderCast("'1'", $type));
476 }
477}
478