Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions dblinter/rules/T001/TableWithoutPrimaryKey.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand All @@ -15,10 +16,10 @@ def table_without_primary_key(
NB_PK = """SELECT count(*) FROM pg_catalog.pg_class pc
JOIN pg_catalog.pg_namespace pn ON pc.relnamespace = pn.oid
JOIN pg_catalog.pg_index pi ON pi.indrelid = pc.oid
WHERE pi.indisprimary=true AND nspname='{}' AND relname='{}'
WHERE pi.indisprimary=true AND nspname='{}' AND relname='{}' and nspname NOT IN ('{}')
"""
uri = f"{db.database}.{table[0]}.{table[1]}"
pk_count = db.query(NB_PK.format(table[0], table[1]))[0][0]
pk_count = db.query(NB_PK.format(table[0], table[1], EXCLUDED_SCHEMAS_STR))[0][0]
if pk_count == 0:
message_args = (db.database, table[0], table[1])
sarif_document.add_check(
Expand Down
8 changes: 6 additions & 2 deletions dblinter/rules/T002/TableWithoutIndex.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand All @@ -11,10 +12,13 @@ def table_without_index(
LOGGER.debug(
"table_without_index for %s.%s in db %s", table[0], table[1], db.database
)
NB_TABLE_WITHOUT_INDEX = """SELECT count(*) FROM pg_catalog.pg_indexes WHERE schemaname='{}' AND tablename='{}'"""
NB_TABLE_WITHOUT_INDEX = """SELECT count(*) FROM pg_catalog.pg_indexes WHERE schemaname='{}' AND tablename='{}'
AND schemaname NOT IN ('{}')"""

uri = f"{db.database}.{table[0]}.{table[1]}"
index_count = db.query(NB_TABLE_WITHOUT_INDEX.format(table[0], table[1]))[0][0]
index_count = db.query(
NB_TABLE_WITHOUT_INDEX.format(table[0], table[1], EXCLUDED_SCHEMAS_STR)
)[0][0]
if index_count == 0:
message_args = (db.database, table[0], table[1])
sarif_document.add_check(
Expand Down
3 changes: 2 additions & 1 deletion dblinter/rules/T003/TableWithRedundantIndex.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand All @@ -17,7 +18,7 @@ def table_with_redundant_index(
pg_namespace ns
WHERE c.oid = i.indrelid
AND ns.oid = c.relnamespace
AND ns.nspname||'.'||c.relname = '{table[0]}.{table[1]}'
AND ns.nspname||'.'||c.relname = '{table[0]}.{table[1]}' AND ns.nspname NOT IN ('{EXCLUDED_SCHEMAS_STR}')
GROUP BY indrelid,indkey,ns.nspname,c.relname
HAVING COUNT(*) > 1;
"""
Expand Down
7 changes: 5 additions & 2 deletions dblinter/rules/T004/TableWithFkNotIndexed.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand All @@ -23,7 +24,7 @@ def table_without_index_on_fk(
join pg_catalog.pg_attribute ta on ta.attnum = tx.attnum and ta.attrelid = tc.conrelid
inner join pg_class c on c.oid=tc.conrelid
inner join pg_namespace ns on ns.oid = c.relnamespace
where ns.nspname='{}' and c.relname='{}' and not exists (
where ns.nspname NOT IN ('{}') AND ns.nspname='{}' and c.relname='{}' and not exists (
select 1 from pg_catalog.pg_index i
where
i.indrelid = tc.conrelid and
Expand All @@ -33,7 +34,9 @@ def table_without_index_on_fk(
tc.conrelid,
tc.conname,
tc.confrelid"""
index_count = db.query(NB_TABLE_WITHOUT_INDEX_ON_FK.format(table[0], table[1]))
index_count = db.query(
NB_TABLE_WITHOUT_INDEX_ON_FK.format(EXCLUDED_SCHEMAS_STR, table[0], table[1])
)
uri = f"{db.database}.{table[0]}.{table[1]}"
if index_count:
for elt in index_count:
Expand Down
4 changes: 2 additions & 2 deletions dblinter/rules/T005/TableWithPotentialMissingIdx.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import extract_param
from dblinter.function_library import EXCLUDED_SCHEMAS_STR, extract_param

LOGGER = logging.getLogger("dblinter")

Expand All @@ -20,7 +20,7 @@ def table_with_missing_index(
seq_tup_read / seq_scan AS avg
FROM pg_stat_user_tables
WHERE seq_scan > 0 and
schemaname='{table[0]}' and relname='{table[1]}'
schemaname='{table[0]}' and relname='{table[1]}' and schemaname NOT IN ('{EXCLUDED_SCHEMAS_STR}')
"""
uri = f"{db.database}.{table[0]}.{table[1]}"
threshold = int(extract_param(param, "threshold"))
Expand Down
2 changes: 2 additions & 0 deletions dblinter/rules/T008/TableWithFkMismatch.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand Down Expand Up @@ -42,6 +43,7 @@ def table_with_fk_type_mixmatch(
where
cls.relname = '{table[1]}'
and ns.nspname='{table[0]}'
and ns.nspname NOT IN ('{EXCLUDED_SCHEMAS_STR}')
and contype = 'f'
) sub
join pg_attribute as ta on
Expand Down
3 changes: 2 additions & 1 deletion dblinter/rules/T009/TableWithRoleNotGranted.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand All @@ -16,7 +17,7 @@ def table_with_role_not_granted(
)

if table[0] != "public":
TABLE_WITH_ROLE_NOT_GRANTED = f"""SELECT count(*) FROM information_schema.role_table_grants tg inner join pg_roles pgr on pgr.rolname=tg.grantee WHERE table_schema='{table[0]}' and table_name='{table[1]}' and pgr.rolcanlogin=false"""
TABLE_WITH_ROLE_NOT_GRANTED = f"""SELECT count(*) FROM information_schema.role_table_grants tg inner join pg_roles pgr on pgr.rolname=tg.grantee WHERE table_schema NOT IN ('{EXCLUDED_SCHEMAS_STR}') and table_schema='{table[0]}' and table_name='{table[1]}' and pgr.rolcanlogin=false"""
table_with_roles = db.query(TABLE_WITH_ROLE_NOT_GRANTED)[0][0]
uri = f"{db.database}.{table[0]}.{table[1]}"
if table_with_roles == 0:
Expand Down
2 changes: 2 additions & 0 deletions dblinter/rules/T010/ReservedKeyWord.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand Down Expand Up @@ -134,6 +135,7 @@ def reserved_keyword(self, db: DatabaseConnection, _, context, table, sarif_docu
pn.oid = pc.relnamespace
WHERE
pn.nspname = '{table[0]}'
AND pn.nspname NOT IN ('{EXCLUDED_SCHEMAS_STR}')
AND relname = '{table[1]}'
AND attnum > 0
"""
Expand Down
3 changes: 2 additions & 1 deletion dblinter/rules/T011/TableWithUppercase.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from dblinter.database_connection import DatabaseConnection
from dblinter.function_library import EXCLUDED_SCHEMAS_STR

LOGGER = logging.getLogger("dblinter")

Expand All @@ -13,7 +14,7 @@ def table_with_uppercase(
)
NB_UPPERCASE_COLS = f"""SELECT count(distinct table_name)
FROM information_schema.columns
WHERE table_schema='{table[0]}' AND table_name='{table[1]}'
WHERE table_schema NOT IN ('{EXCLUDED_SCHEMAS_STR}') AND table_schema='{table[0]}' AND table_name='{table[1]}'
AND (lower(table_name) <> table_name
OR lower(column_name) <> column_name)
"""
Expand Down