@malloydata/malloy-tests 0.0.433 → 0.0.434
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTEXT.md +14 -5
- package/data/parquet_loader.ts +106 -0
- package/duckdb/load_test_data.ts +15 -48
- package/mssql/connection_string.ts +12 -0
- package/mssql/load_test_data.sh +12 -0
- package/mssql/load_test_data.ts +63 -0
- package/mssql/mssql_start.sh +13 -132
- package/mysql/load_test_data.sh +12 -0
- package/mysql/load_test_data.ts +39 -0
- package/mysql/mysql_start.sh +36 -30
- package/package.json +10 -10
- package/postgres/load_test_data.sh +12 -0
- package/postgres/load_test_data.ts +34 -0
- package/postgres/postgres_start.sh +2 -6
- package/presto/Dockerfile.slim +12 -6
- package/presto/hive.properties +8 -0
- package/presto/presto_start.sh +58 -36
- package/src/core/restricted-mode.spec.ts +27 -0
- package/src/core/tags.spec.ts +22 -0
- package/src/core/virtual-sql.spec.ts +253 -0
- package/src/databases/all/expr.spec.ts +150 -18
- package/src/databases/all/nest.spec.ts +237 -0
- package/src/databases/all/nomodel.spec.ts +0 -75
- package/src/databases/all/problems.spec.ts +32 -0
- package/src/runtimes.ts +1 -0
- package/trino/hive.properties +11 -0
- package/trino/hive_ddl.ts +148 -0
- package/trino/trino_start.sh +54 -38
- package/tsconfig.json +12 -1
- package/bin/dump_malloytest.sh +0 -1
- package/bin/postgres_init.sh +0 -10
- package/bin/postgres_start.sh +0 -2
- package/bin/postgres_stop.sh +0 -2
- package/data/mysql/malloytest.mysql.gz +0 -0
- package/data/postgres/malloytest-postgres.sql.gz +0 -0
- package/data/postgres/state_facts.sql +0 -366
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Contributors to the Malloy project
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable no-console */
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Print the DDL that serves test/data/malloytest-parquet through the trino or
|
|
10
|
+
* presto hive connector, reading each parquet file in place as an external
|
|
11
|
+
* table. The hive metastore lowercases every name, so a table with nested
|
|
12
|
+
* columns is created under a `_hive` suffix and a view casts the row types
|
|
13
|
+
* back to the parquet's field names.
|
|
14
|
+
*
|
|
15
|
+
* ts-node hive_ddl.ts <catalog> <location> [--presto]
|
|
16
|
+
*
|
|
17
|
+
* <location> is the directory holding one directory per table, in the
|
|
18
|
+
* connector's URL scheme: local:///malloytest for trino, file:///data/malloytest
|
|
19
|
+
* for presto.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type {QueryRecord} from '@malloydata/malloy';
|
|
23
|
+
import {TinyParser} from '../../packages/malloy/src/dialect/tiny_parser';
|
|
24
|
+
import {openDuckDB, parquetPath, parquetTables} from '../data/parquet_loader';
|
|
25
|
+
|
|
26
|
+
const [catalog, location, ...flags] = process.argv.slice(2);
|
|
27
|
+
const presto = flags.length === 1 && flags[0] === '--presto';
|
|
28
|
+
if (!catalog || !location || (flags.length > 0 && !presto)) {
|
|
29
|
+
console.error('usage: hive_ddl.ts <catalog> <location> [--presto]');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
// Presto's timestamp is milliseconds and takes no precision; trino's is
|
|
33
|
+
// declared to match hive.timestamp-precision in the catalog properties.
|
|
34
|
+
const timestampType = presto ? 'TIMESTAMP' : 'TIMESTAMP(6)';
|
|
35
|
+
|
|
36
|
+
// DuckDB types hive spells the same way
|
|
37
|
+
const sameNameTypes = new Set([
|
|
38
|
+
'BIGINT',
|
|
39
|
+
'INTEGER',
|
|
40
|
+
'DOUBLE',
|
|
41
|
+
'VARCHAR',
|
|
42
|
+
'BOOLEAN',
|
|
43
|
+
'DATE',
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Reads a DuckDB type as DESCRIBE writes it and writes the hive type for the
|
|
48
|
+
* same parquet column: STRUCT(a T, b T) becomes ROW("a" T, "b" T), T[]
|
|
49
|
+
* becomes ARRAY(T), DECIMAL(p,s) and the same-name scalars carry over. The
|
|
50
|
+
* dialect's own DuckDBTypeParser reads the same text into Malloy types, which
|
|
51
|
+
* drop the decimal precision hive needs; this one keeps the SQL spelling.
|
|
52
|
+
*/
|
|
53
|
+
class HiveTypeParser extends TinyParser {
|
|
54
|
+
constructor(input: string) {
|
|
55
|
+
super(input, {
|
|
56
|
+
space: /^\s+/,
|
|
57
|
+
qdouble: /^"([^"]|"")*"/,
|
|
58
|
+
precision: /^\(\d+,\d+\)/,
|
|
59
|
+
arrayOf: /^\[]/,
|
|
60
|
+
char: /^[,()]/,
|
|
61
|
+
id: /^\w+/,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
hiveType(): string {
|
|
66
|
+
const id = this.expect('id').text.toUpperCase();
|
|
67
|
+
let type: string;
|
|
68
|
+
if (id === 'STRUCT') {
|
|
69
|
+
this.expect('(');
|
|
70
|
+
const fields: string[] = [];
|
|
71
|
+
for (;;) {
|
|
72
|
+
const name = this.match('qdouble') ?? this.expect('id');
|
|
73
|
+
fields.push(`"${name.text}" ${this.hiveType()}`);
|
|
74
|
+
if (!this.match(',')) {
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.expect(')');
|
|
79
|
+
type = `ROW(${fields.join(', ')})`;
|
|
80
|
+
} else if (id === 'DECIMAL') {
|
|
81
|
+
type = `DECIMAL${this.expect('precision').text}`;
|
|
82
|
+
} else if (id === 'TIMESTAMP') {
|
|
83
|
+
this.matchText('WITH', 'TIME', 'ZONE');
|
|
84
|
+
type = timestampType;
|
|
85
|
+
} else if (sameNameTypes.has(id)) {
|
|
86
|
+
type = id;
|
|
87
|
+
} else {
|
|
88
|
+
throw this.parseError(`No hive type for DuckDB type ${id}`);
|
|
89
|
+
}
|
|
90
|
+
while (this.match('arrayOf')) {
|
|
91
|
+
type = `ARRAY(${type})`;
|
|
92
|
+
}
|
|
93
|
+
return type;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function hiveType(duckdbType: string): string {
|
|
98
|
+
const parser = new HiveTypeParser(duckdbType);
|
|
99
|
+
const type = parser.hiveType();
|
|
100
|
+
if (!parser.eof()) {
|
|
101
|
+
throw parser.parseError('Unexpected text after the type');
|
|
102
|
+
}
|
|
103
|
+
return type;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function isNested(duckdbType: string): boolean {
|
|
107
|
+
return duckdbType.includes('STRUCT(');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function text(row: QueryRecord, column: string): string {
|
|
111
|
+
const value = row[column];
|
|
112
|
+
if (typeof value !== 'string') {
|
|
113
|
+
throw new Error(`DESCRIBE gave no ${column}`);
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
(async () => {
|
|
119
|
+
const db = await openDuckDB();
|
|
120
|
+
const ddl = [`CREATE SCHEMA IF NOT EXISTS ${catalog}.malloytest;`];
|
|
121
|
+
for (const table of parquetTables()) {
|
|
122
|
+
const described = await db.run(
|
|
123
|
+
`DESCRIBE SELECT * FROM read_parquet('${parquetPath(table)}')`
|
|
124
|
+
);
|
|
125
|
+
const columns = described.map(row => ({
|
|
126
|
+
name: text(row, 'column_name'),
|
|
127
|
+
type: text(row, 'column_type'),
|
|
128
|
+
}));
|
|
129
|
+
const nested = columns.some(c => isNested(c.type));
|
|
130
|
+
const hiveTable = nested ? `${table}_hive` : table;
|
|
131
|
+
const declarations = columns.map(c => ` "${c.name}" ${hiveType(c.type)}`);
|
|
132
|
+
ddl.push(
|
|
133
|
+
`CREATE TABLE IF NOT EXISTS ${catalog}.malloytest.${hiveTable} (\n${declarations.join(',\n')}\n) WITH (format = 'PARQUET', external_location = '${location}/${table}');`
|
|
134
|
+
);
|
|
135
|
+
if (nested) {
|
|
136
|
+
const select = columns.map(c =>
|
|
137
|
+
isNested(c.type)
|
|
138
|
+
? ` CAST("${c.name}" AS ${hiveType(c.type)}) AS "${c.name}"`
|
|
139
|
+
: ` "${c.name}"`
|
|
140
|
+
);
|
|
141
|
+
ddl.push(
|
|
142
|
+
`CREATE OR REPLACE VIEW ${catalog}.malloytest.${table} AS SELECT\n${select.join(',\n')}\nFROM ${catalog}.malloytest.${hiveTable};`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
await db.close();
|
|
147
|
+
console.log(ddl.join('\n'));
|
|
148
|
+
})();
|
package/trino/trino_start.sh
CHANGED
|
@@ -1,25 +1,36 @@
|
|
|
1
1
|
#! /bin/bash
|
|
2
|
-
|
|
2
|
+
#
|
|
3
|
+
# Start a trino container whose hive catalog serves test/data/malloytest-parquet
|
|
4
|
+
# as the malloytest schema. The parquet is read in place; nothing is loaded.
|
|
5
|
+
#
|
|
3
6
|
set -e
|
|
4
7
|
|
|
8
|
+
SCRIPTDIR=$(cd $(dirname $0); pwd)
|
|
9
|
+
ROOTDIR=$(cd "$SCRIPTDIR/../.."; pwd)
|
|
10
|
+
DATADIR=$ROOTDIR/test/data/malloytest-parquet
|
|
11
|
+
CONTAINER_NAME="trino-malloy"
|
|
12
|
+
PORT=${TRINO_PORT:-8080}
|
|
13
|
+
|
|
14
|
+
cd "$ROOTDIR"
|
|
5
15
|
rm -rf .tmp
|
|
6
16
|
mkdir .tmp
|
|
7
17
|
|
|
18
|
+
# Only the log since this script started: a restarted container's old log
|
|
19
|
+
# already says SERVER STARTED.
|
|
20
|
+
SINCE=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
8
21
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
CONTAINER_NAME="trino-malloy"
|
|
22
|
+
wait_for_trino() {
|
|
23
|
+
local counter=0
|
|
24
|
+
while ! docker logs --since "$SINCE" "$CONTAINER_NAME" 2>&1 | grep -q "SERVER STARTED"; do
|
|
25
|
+
counter=$((counter+1))
|
|
26
|
+
# give up after 5 minutes
|
|
27
|
+
if [ $counter -eq 300 ]; then
|
|
28
|
+
docker logs "$CONTAINER_NAME" >& ./.tmp/trino-malloy.logs
|
|
29
|
+
return 1
|
|
30
|
+
fi
|
|
31
|
+
sleep 1
|
|
32
|
+
done
|
|
33
|
+
}
|
|
23
34
|
|
|
24
35
|
# Check for existing container
|
|
25
36
|
if docker container inspect "$CONTAINER_NAME" > /dev/null 2>&1; then
|
|
@@ -29,31 +40,36 @@ if docker container inspect "$CONTAINER_NAME" > /dev/null 2>&1; then
|
|
|
29
40
|
fi
|
|
30
41
|
echo "Restarting existing $CONTAINER_NAME container..."
|
|
31
42
|
docker start "$CONTAINER_NAME"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
if ! wait_for_trino; then
|
|
44
|
+
echo "Trino did not restart successfully, check .tmp/trino-malloy.logs"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
echo "Trino running on port localhost:$PORT"
|
|
36
48
|
exit 0
|
|
37
49
|
fi
|
|
38
50
|
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
while ! docker logs "$CONTAINER_NAME" 2>&1 | grep -q "SERVER STARTED"
|
|
45
|
-
do
|
|
46
|
-
sleep 1
|
|
47
|
-
counter=$((counter+1))
|
|
48
|
-
# if doesn't start after 2 minutes, output logs and kill process
|
|
49
|
-
if [ $counter -eq 300 ]
|
|
50
|
-
then
|
|
51
|
-
docker logs "$CONTAINER_NAME" >& ./.tmp/trino-malloy.logs
|
|
52
|
-
docker rm -f "$CONTAINER_NAME"
|
|
53
|
-
echo "Trino did not start successfully, check .tmp/trino-malloy.logs"
|
|
54
|
-
exit 1
|
|
55
|
-
break
|
|
56
|
-
fi
|
|
51
|
+
# A hive external_location is a directory, so each parquet file gets one.
|
|
52
|
+
MOUNTS=()
|
|
53
|
+
for parquet in "$DATADIR"/*.parquet; do
|
|
54
|
+
table=$(basename "$parquet" .parquet)
|
|
55
|
+
MOUNTS+=(-v "$parquet:/data/malloytest/$table/$table.parquet:ro")
|
|
57
56
|
done
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
docker run -p $PORT:8080 -d -e TZ=UTC "${MOUNTS[@]}" \
|
|
59
|
+
-v "$SCRIPTDIR/hive.properties:/etc/trino/catalog/hive.properties:ro" \
|
|
60
|
+
--name "$CONTAINER_NAME" trinodb/trino
|
|
61
|
+
|
|
62
|
+
# A container without its tables must not survive to be "already running"
|
|
63
|
+
trap 'docker rm -f "$CONTAINER_NAME" > /dev/null; echo "Trino setup failed, check .tmp/trino-malloy.logs"' ERR
|
|
64
|
+
|
|
65
|
+
if ! wait_for_trino; then
|
|
66
|
+
false
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
echo "Creating the malloytest tables"
|
|
70
|
+
npx ts-node test/trino/hive_ddl.ts hive local:///malloytest > .tmp/hive_ddl.sql
|
|
71
|
+
docker cp .tmp/hive_ddl.sql "$CONTAINER_NAME":/tmp/hive_ddl.sql
|
|
72
|
+
docker exec "$CONTAINER_NAME" trino -f /tmp/hive_ddl.sql
|
|
73
|
+
trap - ERR
|
|
74
|
+
|
|
75
|
+
echo "Trino running on port localhost:$PORT"
|
package/tsconfig.json
CHANGED
|
@@ -6,7 +6,18 @@
|
|
|
6
6
|
"jsx": "react-jsx",
|
|
7
7
|
"jsxImportSource": "solid-js"
|
|
8
8
|
},
|
|
9
|
-
"include": [
|
|
9
|
+
"include": [
|
|
10
|
+
"src",
|
|
11
|
+
"bin",
|
|
12
|
+
"data",
|
|
13
|
+
"duckdb",
|
|
14
|
+
"mssql",
|
|
15
|
+
"mysql",
|
|
16
|
+
"postgres",
|
|
17
|
+
"trino",
|
|
18
|
+
"./jest.setup.ts",
|
|
19
|
+
"./types/jest.d.ts"
|
|
20
|
+
],
|
|
10
21
|
"references": [
|
|
11
22
|
{
|
|
12
23
|
"path": "../packages/malloy-interfaces"
|
package/bin/dump_malloytest.sh
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
pg_dump -n malloytest -O -x | gzip > ../sql/malloytest-postgres.sql.gz
|
package/bin/postgres_init.sh
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
#! /bin/bash
|
|
2
|
-
export PGHOST=localhost
|
|
3
|
-
pg_ctl -D .tmp/data/malloytestdb -l .tmp/logfile -o "--unix_socket_directories='$PWD/.tmp'" stop
|
|
4
|
-
rm -rf .tmp
|
|
5
|
-
mkdir .tmp
|
|
6
|
-
initdb -d .tmp/data/malloytestdb --no-locale --encoding=UTF8
|
|
7
|
-
pg_ctl -D .tmp/data/malloytestdb -l .tmp/logfile -o "--unix_socket_directories='$PWD/.tmp'" start
|
|
8
|
-
createdb $USER
|
|
9
|
-
gunzip -c ../data/postgres/malloytest-postgres.sql.gz | psql
|
|
10
|
-
echo CREATE EXTENSION tsm_system_rows\; | psql
|
package/bin/postgres_start.sh
DELETED
package/bin/postgres_stop.sh
DELETED
|
Binary file
|
|
Binary file
|
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
-- example of how to take a json blob and insert it into a postgres database
|
|
2
|
-
-- keeping around because it might be useful as we add new tables.
|
|
3
|
-
|
|
4
|
-
create type t as (state varchar, aircraft_count int, airport_count int, births int, popular_name varchar);
|
|
5
|
-
create table malloytest.state_facts as (
|
|
6
|
-
select p.*
|
|
7
|
-
from json_populate_recordset(null::t,'[
|
|
8
|
-
{
|
|
9
|
-
"state": "MN",
|
|
10
|
-
"aircraft_count": "83",
|
|
11
|
-
"airport_count": "507",
|
|
12
|
-
"births": "5574819",
|
|
13
|
-
"popular_name": "Ava"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"state": "LA",
|
|
17
|
-
"aircraft_count": "57",
|
|
18
|
-
"airport_count": "500",
|
|
19
|
-
"births": "5551025",
|
|
20
|
-
"popular_name": "Ava"
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"state": "IA",
|
|
24
|
-
"aircraft_count": "28",
|
|
25
|
-
"airport_count": "319",
|
|
26
|
-
"births": "4108689",
|
|
27
|
-
"popular_name": "Ava"
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"state": "IN",
|
|
31
|
-
"aircraft_count": "62",
|
|
32
|
-
"airport_count": "643",
|
|
33
|
-
"births": "7170553",
|
|
34
|
-
"popular_name": "Emma"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"state": "NC",
|
|
38
|
-
"aircraft_count": "72",
|
|
39
|
-
"airport_count": "400",
|
|
40
|
-
"births": "8440235",
|
|
41
|
-
"popular_name": "Emma"
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"state": "AR",
|
|
45
|
-
"aircraft_count": "31",
|
|
46
|
-
"airport_count": "299",
|
|
47
|
-
"births": "3330382",
|
|
48
|
-
"popular_name": "Emma"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
"state": "AL",
|
|
52
|
-
"aircraft_count": "58",
|
|
53
|
-
"airport_count": "260",
|
|
54
|
-
"births": "5645599",
|
|
55
|
-
"popular_name": "Emma"
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
"state": "MT",
|
|
59
|
-
"aircraft_count": "50",
|
|
60
|
-
"airport_count": "259",
|
|
61
|
-
"births": "942521",
|
|
62
|
-
"popular_name": "Emma"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"state": "ME",
|
|
66
|
-
"aircraft_count": "12",
|
|
67
|
-
"airport_count": "164",
|
|
68
|
-
"births": "1383204",
|
|
69
|
-
"popular_name": "Emma"
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"state": "VA",
|
|
73
|
-
"aircraft_count": "67",
|
|
74
|
-
"airport_count": "421",
|
|
75
|
-
"births": "6693880",
|
|
76
|
-
"popular_name": "Olivia"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"state": "NE",
|
|
80
|
-
"aircraft_count": "24",
|
|
81
|
-
"airport_count": "308",
|
|
82
|
-
"births": "2255039",
|
|
83
|
-
"popular_name": "Olivia"
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"state": "ID",
|
|
87
|
-
"aircraft_count": "36",
|
|
88
|
-
"airport_count": "238",
|
|
89
|
-
"births": "1147445",
|
|
90
|
-
"popular_name": "Olivia"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"state": "UT",
|
|
94
|
-
"aircraft_count": "53",
|
|
95
|
-
"airport_count": "140",
|
|
96
|
-
"births": "2306033",
|
|
97
|
-
"popular_name": "Olivia"
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
"state": "AK",
|
|
101
|
-
"aircraft_count": "85",
|
|
102
|
-
"airport_count": "608",
|
|
103
|
-
"births": "407106",
|
|
104
|
-
"popular_name": "Sophia"
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"state": "WI",
|
|
108
|
-
"aircraft_count": "66",
|
|
109
|
-
"airport_count": "543",
|
|
110
|
-
"births": "6088288",
|
|
111
|
-
"popular_name": "Sophia"
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
"state": "MI",
|
|
115
|
-
"aircraft_count": "102",
|
|
116
|
-
"airport_count": "489",
|
|
117
|
-
"births": "11643455",
|
|
118
|
-
"popular_name": "Sophia"
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
"state": "WA",
|
|
122
|
-
"aircraft_count": "114",
|
|
123
|
-
"airport_count": "484",
|
|
124
|
-
"births": "4631964",
|
|
125
|
-
"popular_name": "Sophia"
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
"state": "OR",
|
|
129
|
-
"aircraft_count": "94",
|
|
130
|
-
"airport_count": "441",
|
|
131
|
-
"births": "2671780",
|
|
132
|
-
"popular_name": "Sophia"
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
"state": "ND",
|
|
136
|
-
"aircraft_count": "26",
|
|
137
|
-
"airport_count": "436",
|
|
138
|
-
"births": "1059330",
|
|
139
|
-
"popular_name": "Sophia"
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
"state": "MD",
|
|
143
|
-
"aircraft_count": "30",
|
|
144
|
-
"airport_count": "229",
|
|
145
|
-
"births": "4468717",
|
|
146
|
-
"popular_name": "Sophia"
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
"state": "SD",
|
|
150
|
-
"aircraft_count": "23",
|
|
151
|
-
"airport_count": "180",
|
|
152
|
-
"births": "1049223",
|
|
153
|
-
"popular_name": "Sophia"
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
"state": "NH",
|
|
157
|
-
"aircraft_count": "30",
|
|
158
|
-
"airport_count": "112",
|
|
159
|
-
"births": "955057",
|
|
160
|
-
"popular_name": "Sophia"
|
|
161
|
-
},
|
|
162
|
-
{
|
|
163
|
-
"state": "VT",
|
|
164
|
-
"aircraft_count": "6",
|
|
165
|
-
"airport_count": "81",
|
|
166
|
-
"births": "545999",
|
|
167
|
-
"popular_name": "Sophia"
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
"state": "DE",
|
|
171
|
-
"aircraft_count": "118",
|
|
172
|
-
"airport_count": "42",
|
|
173
|
-
"births": "615490",
|
|
174
|
-
"popular_name": "Sophia"
|
|
175
|
-
},
|
|
176
|
-
{
|
|
177
|
-
"state": "MS",
|
|
178
|
-
"aircraft_count": "27",
|
|
179
|
-
"airport_count": "243",
|
|
180
|
-
"births": "3969549",
|
|
181
|
-
"popular_name": "Madison"
|
|
182
|
-
},
|
|
183
|
-
{
|
|
184
|
-
"state": "SC",
|
|
185
|
-
"aircraft_count": "28",
|
|
186
|
-
"airport_count": "189",
|
|
187
|
-
"births": "4392042",
|
|
188
|
-
"popular_name": "Madison"
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
"state": "DC",
|
|
192
|
-
"aircraft_count": "6",
|
|
193
|
-
"airport_count": "20",
|
|
194
|
-
"births": "1419047",
|
|
195
|
-
"popular_name": "Madison"
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
"state": "TX",
|
|
199
|
-
"aircraft_count": "287",
|
|
200
|
-
"airport_count": "1845",
|
|
201
|
-
"births": "21467359",
|
|
202
|
-
"popular_name": "Isabella"
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
"state": "CA",
|
|
206
|
-
"aircraft_count": "367",
|
|
207
|
-
"airport_count": "984",
|
|
208
|
-
"births": "28810563",
|
|
209
|
-
"popular_name": "Isabella"
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
"state": "IL",
|
|
213
|
-
"aircraft_count": "111",
|
|
214
|
-
"airport_count": "890",
|
|
215
|
-
"births": "15178876",
|
|
216
|
-
"popular_name": "Isabella"
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
"state": "FL",
|
|
220
|
-
"aircraft_count": "228",
|
|
221
|
-
"airport_count": "856",
|
|
222
|
-
"births": "9277223",
|
|
223
|
-
"popular_name": "Isabella"
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
"state": "PA",
|
|
227
|
-
"aircraft_count": "83",
|
|
228
|
-
"airport_count": "804",
|
|
229
|
-
"births": "16661910",
|
|
230
|
-
"popular_name": "Isabella"
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
"state": "OH",
|
|
234
|
-
"aircraft_count": "106",
|
|
235
|
-
"airport_count": "749",
|
|
236
|
-
"births": "14201526",
|
|
237
|
-
"popular_name": "Isabella"
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
"state": "NY",
|
|
241
|
-
"aircraft_count": "91",
|
|
242
|
-
"airport_count": "576",
|
|
243
|
-
"births": "23694136",
|
|
244
|
-
"popular_name": "Isabella"
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
"state": "MO",
|
|
248
|
-
"aircraft_count": "62",
|
|
249
|
-
"airport_count": "537",
|
|
250
|
-
"births": "6792279",
|
|
251
|
-
"popular_name": "Isabella"
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
"state": "OK",
|
|
255
|
-
"aircraft_count": "99",
|
|
256
|
-
"airport_count": "443",
|
|
257
|
-
"births": "4137117",
|
|
258
|
-
"popular_name": "Isabella"
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
"state": "GA",
|
|
262
|
-
"aircraft_count": "98",
|
|
263
|
-
"airport_count": "440",
|
|
264
|
-
"births": "8183223",
|
|
265
|
-
"popular_name": "Isabella"
|
|
266
|
-
},
|
|
267
|
-
{
|
|
268
|
-
"state": "CO",
|
|
269
|
-
"aircraft_count": "98",
|
|
270
|
-
"airport_count": "425",
|
|
271
|
-
"births": "3424936",
|
|
272
|
-
"popular_name": "Isabella"
|
|
273
|
-
},
|
|
274
|
-
{
|
|
275
|
-
"state": "KS",
|
|
276
|
-
"aircraft_count": "63",
|
|
277
|
-
"airport_count": "415",
|
|
278
|
-
"births": "3212573",
|
|
279
|
-
"popular_name": "Isabella"
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
"state": "NJ",
|
|
283
|
-
"aircraft_count": "47",
|
|
284
|
-
"airport_count": "378",
|
|
285
|
-
"births": "8318769",
|
|
286
|
-
"popular_name": "Isabella"
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
"state": "AZ",
|
|
290
|
-
"aircraft_count": "98",
|
|
291
|
-
"airport_count": "319",
|
|
292
|
-
"births": "3328182",
|
|
293
|
-
"popular_name": "Isabella"
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
"state": "TN",
|
|
297
|
-
"aircraft_count": "62",
|
|
298
|
-
"airport_count": "285",
|
|
299
|
-
"births": "6313851",
|
|
300
|
-
"popular_name": "Isabella"
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
"state": "MA",
|
|
304
|
-
"aircraft_count": "40",
|
|
305
|
-
"airport_count": "225",
|
|
306
|
-
"births": "7576933",
|
|
307
|
-
"popular_name": "Isabella"
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
"state": "KY",
|
|
311
|
-
"aircraft_count": "26",
|
|
312
|
-
"airport_count": "202",
|
|
313
|
-
"births": "5352594",
|
|
314
|
-
"popular_name": "Isabella"
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
"state": "NM",
|
|
318
|
-
"aircraft_count": "46",
|
|
319
|
-
"airport_count": "181",
|
|
320
|
-
"births": "1640394",
|
|
321
|
-
"popular_name": "Isabella"
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
"state": "CT",
|
|
325
|
-
"aircraft_count": "25",
|
|
326
|
-
"airport_count": "153",
|
|
327
|
-
"births": "3361014",
|
|
328
|
-
"popular_name": "Isabella"
|
|
329
|
-
},
|
|
330
|
-
{
|
|
331
|
-
"state": "NV",
|
|
332
|
-
"aircraft_count": "55",
|
|
333
|
-
"airport_count": "128",
|
|
334
|
-
"births": "842854",
|
|
335
|
-
"popular_name": "Isabella"
|
|
336
|
-
},
|
|
337
|
-
{
|
|
338
|
-
"state": "WV",
|
|
339
|
-
"aircraft_count": "13",
|
|
340
|
-
"airport_count": "116",
|
|
341
|
-
"births": "2962442",
|
|
342
|
-
"popular_name": "Isabella"
|
|
343
|
-
},
|
|
344
|
-
{
|
|
345
|
-
"state": "WY",
|
|
346
|
-
"aircraft_count": "15",
|
|
347
|
-
"airport_count": "115",
|
|
348
|
-
"births": "423000",
|
|
349
|
-
"popular_name": "Isabella"
|
|
350
|
-
},
|
|
351
|
-
{
|
|
352
|
-
"state": "HI",
|
|
353
|
-
"aircraft_count": "10",
|
|
354
|
-
"airport_count": "52",
|
|
355
|
-
"births": "950538",
|
|
356
|
-
"popular_name": "Isabella"
|
|
357
|
-
},
|
|
358
|
-
{
|
|
359
|
-
"state": "RI",
|
|
360
|
-
"aircraft_count": "5",
|
|
361
|
-
"airport_count": "28",
|
|
362
|
-
"births": "1148302",
|
|
363
|
-
"popular_name": "Isabella"
|
|
364
|
-
}
|
|
365
|
-
]') as p
|
|
366
|
-
);
|