Skip to content
This repository was archived by the owner on Sep 23, 2024. It is now read-only.

Commit 19ed99d

Browse files
committed
Use underlying type of domain type when defined
This fixes issues with primary keys being defined using domain types, and deselected by default. E.g. for a domain type `email_domain` with base type `text`, the `data_type` column will now be `text` rather than `email_domain`.
1 parent c0eb14e commit 19ed99d

File tree

2 files changed

+93
-6
lines changed

2 files changed

+93
-6
lines changed

tap_postgres/discovery_utils.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ def produce_table_info(conn, filter_schemas=None, tables: Optional[List[str]] =
6464
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor, name='stitch_cursor') as cur:
6565
cur.itersize = post_db.CURSOR_ITER_SIZE
6666
table_info = {}
67-
# SELECT CASE WHEN $2.typtype = 'd' THEN $2.typbasetype ELSE $1.atttypid END
6867
sql = """
6968
SELECT
7069
pg_class.reltuples::BIGINT AS approximate_row_count,
@@ -73,7 +72,7 @@ def produce_table_info(conn, filter_schemas=None, tables: Optional[List[str]] =
7372
pg_class.relname AS table_name,
7473
attname AS column_name,
7574
i.indisprimary AS primary_key,
76-
format_type(a.atttypid, NULL::integer) AS data_type,
75+
format_type(CASE WHEN pgt.typtype = 'd' THEN pgt.typbasetype ELSE a.atttypid END, NULL::integer) AS data_type,
7776
information_schema._pg_char_max_length(CASE WHEN COALESCE(subpgt.typtype, pgt.typtype) = 'd'
7877
THEN COALESCE(subpgt.typbasetype, pgt.typbasetype) ELSE COALESCE(subpgt.oid, pgt.oid)
7978
END,

tests/test_discovery.py

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,94 @@ def test_catalog(self):
452452
'definitions' : BASE_RECURSIVE_SCHEMAS},
453453
stream_dict.get('schema'))
454454

455+
class TestDomainsTable(unittest.TestCase):
456+
maxDiff = None
457+
table_name = "CHICKEN TIMES"
458+
459+
def setUp(self):
460+
table_spec = {
461+
"columns": [
462+
{
463+
"name": "our_test_domain_pk",
464+
"type": "test_domain",
465+
"primary_key": True,
466+
},
467+
{"name": "our_test_domain", "type": "test_domain"},
468+
{"name": "our_test_integer_domain", "type": "test_integer_domain"},
469+
],
470+
"name": TestHStoreTable.table_name,
471+
}
472+
with get_test_connection() as conn:
473+
cur = conn.cursor()
474+
cur.execute(""" DROP DOMAIN IF EXISTS test_domain CASCADE """)
475+
cur.execute(""" CREATE DOMAIN test_domain AS text; """)
476+
cur.execute(""" DROP DOMAIN IF EXISTS test_integer_domain CASCADE """)
477+
cur.execute(""" CREATE DOMAIN test_integer_domain AS integer; """)
478+
479+
ensure_test_table(table_spec)
480+
481+
def test_catalog(self):
482+
conn_config = get_test_connection_config()
483+
streams = tap_postgres.do_discovery(conn_config)
484+
chicken_streams = [
485+
s for s in streams if s["tap_stream_id"] == "public-CHICKEN TIMES"
486+
]
487+
self.assertEqual(len(chicken_streams), 1)
488+
stream_dict = chicken_streams[0]
489+
stream_dict.get("metadata").sort(key=lambda md: md["breadcrumb"])
490+
491+
with get_test_connection() as conn:
492+
with conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
493+
cur.execute(
494+
"""INSERT INTO "CHICKEN TIMES" (our_test_domain_pk, our_test_domain, our_test_integer_domain) VALUES ('sad', 'happy', 3)"""
495+
)
496+
cur.execute("""SELECT * FROM "CHICKEN TIMES" """)
497+
498+
self.assertEqual(
499+
metadata.to_map(stream_dict.get("metadata")),
500+
{
501+
(): {
502+
"table-key-properties": ["our_test_domain_pk"],
503+
"database-name": "postgres",
504+
"schema-name": "public",
505+
"is-view": False,
506+
"row-count": 0,
507+
},
508+
("properties", "our_test_domain_pk"): {
509+
"inclusion": "automatic",
510+
"sql-datatype": "text",
511+
"selected-by-default": True,
512+
},
513+
("properties", "our_test_domain"): {
514+
"inclusion": "available",
515+
"sql-datatype": "text",
516+
"selected-by-default": True,
517+
},
518+
("properties", "our_test_integer_domain"): {
519+
"inclusion": "available",
520+
"sql-datatype": "integer",
521+
"selected-by-default": True,
522+
},
523+
},
524+
)
525+
526+
self.assertEqual(
527+
{
528+
"properties": {
529+
"our_test_domain_pk": {"type": ["string"]},
530+
"our_test_domain": {"type": ["null", "string"]},
531+
"our_test_integer_domain": {
532+
"minimum": -2147483648,
533+
"maximum": 2147483647,
534+
"type": ["null", "integer"],
535+
},
536+
},
537+
"type": "object",
538+
"definitions": BASE_RECURSIVE_SCHEMAS,
539+
},
540+
stream_dict.get("schema"),
541+
)
542+
455543
class TestArraysTable(unittest.TestCase):
456544
maxDiff = None
457545
table_name = 'CHICKEN TIMES'
@@ -536,7 +624,7 @@ class TestColumnGrants(unittest.TestCase):
536624
table_name = 'CHICKEN TIMES'
537625
user = 'tmp_user_for_grant_tests'
538626
password = 'password'
539-
627+
540628
def setUp(self):
541629
table_spec = {"columns": [{"name" : "id", "type" : "integer", "serial" : True},
542630
{"name" : 'size integer', "type" : "integer", "quoted" : True},
@@ -560,8 +648,8 @@ def setUp(self):
560648
LOGGER.info("running sql: {}".format(sql))
561649
cur.execute(sql)
562650

563-
564-
651+
652+
565653

566654
def test_catalog(self):
567655
conn_config = get_test_connection_config()
@@ -587,7 +675,7 @@ def test_catalog(self):
587675
('properties', 'id'): {'inclusion': 'available',
588676
'selected-by-default': True,
589677
'sql-datatype': 'integer'}})
590-
678+
591679
self.assertEqual({'definitions' : BASE_RECURSIVE_SCHEMAS,
592680
'type': 'object',
593681
'properties': {'id': {'type': ['null', 'integer'],

0 commit comments

Comments
 (0)