Repository: schemaspy/schemaspy

Issue #1115: Postgres 11 Long Routine Names Cause Crash
Created: 2023-03-27T00:58:16Z
Expected Behavior
With a Postgres 14.6 database that has a routine with a long name, running schemaspy with the schemaspy.t=pgsql11 option should successfully retrieve the routine's information.
Current Behavior
It crashes with this stack trace:
Caused by: java.lang.NullPointerException
  at org.schemaspy.util.CaseInsensitiveMap.put(CaseInsensitiveMap.java:59)
  at org.schemaspy.util.CaseInsensitiveMap.put(CaseInsensitiveMap.java:35)
  at org.schemaspy.input.dbms.service.RoutineService.initRoutines(RoutineService.java:95)
  at org.schemaspy.input.dbms.service.RoutineService.gatherRoutines(RoutineService.java:46)
  at org.schemaspy.input.dbms.service.DatabaseService.gatherSchemaDetails(DatabaseService.java:132)
  at org.schemaspy.SchemaAnalyzer.analyze(SchemaAnalyzer.java:269)
  at org.schemaspy.SchemaAnalyzer.analyzeMultipleSchemas(SchemaAnalyzer.java:185)
  at org.schemaspy.SchemaAnalyzer.analyze(SchemaAnalyzer.java:126)
  at org.schemaspy.cli.SchemaSpyRunner.runAnalyzer(SchemaSpyRunner.java:109)
  at org.schemaspy.cli.SchemaSpyRunner.run(SchemaSpyRunner.java:98)
  at org.schemaspy.Main.main(Main.java:55)

Possible Solution
It appears that it's broken by this change,

  
    
      schemaspy/src/main/resources/org/schemaspy/types/pgsql11.properties
    
    
         Line 43
      in
      96cfe16
    
  
  
    

        
          
           left join pg_proc pp on r.specific_name = pp.proname || '_' || pp.oid \ 
        
    
  


Usually, r.specific_name is made up of pp.proname || '_' || pp.oid. However, when that expression exceeds Postgres's max length for SQL identifiers, i.e. 63, pp.proname is truncated to ensure r.specific_name meets the maximum length. When the truncation occurs, the above SQL returns NULL routine_name, which leads to the above NPE.
A possible solution is to revert it to its previous implementation,
LEFT JOIN pg_proc p ON ns.oid = p.pronamespace
    AND r.routine_name = p.proname
Perhaps, it's even better to not mix up information_schema with pg_catalog tables and views. See https://www.postgresql.org/docs/current/infoschema-routines.html,

specific_name sql_identifier
The “specific name” of the function. This is a name that uniquely identifies the function in the schema, even if the real name of the function is overloaded. The format of the specific name is not defined, it should only be used to compare it to other instances of specific routine names.

Steps to Reproduce (for bugs)

Run this SQL to create a function in a Postgres 14.6 database

CREATE FUNCTION loooooooooooooooooooooooooooooooong_function_with_63_characters()
RETURNS integer
AS $$
SELECT 1
$$
LANGUAGE SQL;

Run schemaspy with the schemaspy.t=pgsql11 option.

Your Environment

Version used: 6.2.2
Operating System and version: Windows 10
Java version: AdoptJDK/jdk-17.0.6+10
Postgres version: 14.6

Duplicate issue #1166: NullPointerException after upgrading to 6.2.2
Created: 2023-05-14T06:54:12Z
We started getting NullPointerException after upgrading from 6.1.0 to 6.2.2
Expected Behavior

it should work

Current Behavior

INFO - Analyzing 'public'
INFO - Starting schema analysis
INFO - Connected to PostgreSQL - 12.4
INFO - Gathering schema details
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52)
Caused by: java.lang.NullPointerException: Cannot invoke "String.toUpperCase()" because "key" is null
at org.schemaspy.util.CaseInsensitiveMap.put(CaseInsensitiveMap.java:59)
at org.schemaspy.util.CaseInsensitiveMap.put(CaseInsensitiveMap.java:35)
at org.schemaspy.input.dbms.service.RoutineService.initRoutines(RoutineService.java:95)
at org.schemaspy.input.dbms.service.RoutineService.gatherRoutines(RoutineService.java:46)
at org.schemaspy.input.dbms.service.DatabaseService.gatherSchemaDetails(DatabaseService.java:132)
at org.schemaspy.SchemaAnalyzer.analyze(SchemaAnalyzer.java:269)
at org.schemaspy.SchemaAnalyzer.analyzeMultipleSchemas(SchemaAnalyzer.java:185)
at org.schemaspy.SchemaAnalyzer.analyze(SchemaAnalyzer.java:126)
at org.schemaspy.cli.SchemaSpyRunner.runAnalyzer(SchemaSpyRunner.java:109)
at org.schemaspy.cli.SchemaSpyRunner.run(SchemaSpyRunner.java:98)
at org.schemaspy.Main.main(Main.java:55)
... 8 more


Context

schemaspy fails and doesn't generate the files for all schemas



Database type (e.g. MySQL): postgres
Database driver version (is you use a special one): default
Your DDL (sample how to reproduce the issue):
Full command including arguments how you run SchemaSpy:

java -jar ./schemaspy-6.2.2.jar \
        -t pgsql11_partitions.properties \
        -db $DBNAME \
        -host $DBHOST \
        -port $DBPORT \
        -u $DBUSER \
        -p $SCHEMASPY_PG_PASSWORD \
        -o /output_tmp/$DBNAME \
        -dp /drivers \
        -schemas $LIST_OF_SCHEMAS \
        -noimplied \
        -nopages \
        -norows \
        -noexportedkeys

where pgsql11_partitions.properties is
extends=pgsql11

# relkind IN ('r','p') --> regular or partitioned \
# NOT relispartition --> not a partition
selectTablesSql=SELECT relname table_name, current_database() table_catalog, ns.nspname table_schema, description table_comment, 0 table_rows \
FROM pg_class obj \
INNER JOIN pg_namespace ns ON (obj.relnamespace=ns.oid) \
LEFT JOIN pg_catalog.pg_description ON (objoid=obj.oid AND objsubid =0) \
WHERE nspname = :schema \
AND relkind IN ('r','p') \
AND NOT relispartition

Your Environment


Version used: 6.2.2
Operating System and version (e.g. Windows 10): linux
Java version: openjdk:17-alpine3.14
JDBC version 42.2.25

Closing comment (2023-05-14T06:57:54Z): Can you check if this is a duplicate of #1115