packages/ztd-query-postgres/fuzz/Input/SchemaRows.php
1<?php
2
3declare(strict_types=1);
4
5namespace Fuzz\Input;
6
7use ZtdQuery\Schema\TableDefinition;
8
9/**
10 * Creates reproducible PostgreSQL pipeline fixtures.
11 */
12final class SchemaRows
13{
14 /**
15 * Generate random fixture rows for a table definition.
16 *
17 * @return array<int, array<string, int|float|string|bool>>
18 */
19 public function generateFixtureRows(TableDefinition $definition, int $count): array
20 {
21 $rows = [];
22 for ($i = 0; $i < $count; $i++) {
23 $row = [];
24 foreach ($definition->columns as $col) {
25 $type = strtoupper($definition->columnTypes[$col] ?? 'TEXT');
26 $row[$col] = $this->generateValueForType($type, $i);
27 }
28 $rows[] = $row;
29 }
30 return $rows;
31 }
32
33 /**
34 * Generate a random value appropriate for the given SQL type.
35 */
36 public function generateValueForType(string $type, int $seed): int|float|string|bool
37 {
38 $baseType = preg_replace('/\(.*\)/', '', $type);
39 $baseType = trim($baseType ?? $type);
40 return match (true) {
41 in_array($baseType, ['INT', 'INT2', 'INT4', 'INT8', 'INTEGER', 'SMALLINT', 'BIGINT', 'SERIAL', 'SMALLSERIAL', 'BIGSERIAL'], true) => $seed + 1,
42 in_array($baseType, ['REAL', 'FLOAT4', 'DOUBLE PRECISION', 'FLOAT8', 'DECIMAL', 'NUMERIC'], true) => round($seed + 0.5, 2),
43 in_array($baseType, ['BOOLEAN', 'BOOL'], true) => $seed % 2 === 0,
44 default => 'val_' . $seed,
45 };
46 }
47
48 /**
49 * Extract table name from a CREATE TABLE statement.
50 */
51 public function extractTableName(string $createSql): ?string
52 {
53 if (preg_match('/CREATE\s+(?:TEMPORARY\s+|TEMP\s+|UNLOGGED\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:(?:"([^"]+)"|([a-zA-Z_]\w*))\.)?(?:"([^"]+)"|([a-zA-Z_]\w*))/i', $createSql, $m) !== 1) {
54 return null;
55 }
56 $quotedTable = $m[3] ?? '';
57 return $quotedTable !== '' ? $quotedTable : $m[4] ?? null;
58 }
59}
60