Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #11058: postgresql_adapter.diff

File postgresql_adapter.diff, 7.5 kB (added by cfis, 5 months ago)

Data dictionary caching patch for Postgreqql

  • Copy

    old new  
    435435 
    436436      # SCHEMA STATEMENTS ======================================== 
    437437 
     438      # Use to clear out the dd (data dictionary) cache 
     439      def flush_dd_cache 
     440        @tables = Hash.new 
     441        @indexes = Hash.new 
     442        @sequences = Hash.new 
     443        @column_defs = Hash.new 
     444      end 
     445       
    438446      # Returns the list of all tables in the schema search path or a specified schema. 
    439447      def tables(name = nil) 
    440         schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',') 
    441         query(<<-SQL, name).map { |row| row[0] } 
    442           SELECT tablename 
    443             FROM pg_tables 
    444            WHERE schemaname IN (#{schemas}) 
    445         SQL 
     448        @tables ||= Hash.new 
     449         
     450        @tables[name] ||= begin  
     451          schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',') 
     452          query(<<-SQL, name).map { |row| row[0] } 
     453            SELECT tablename 
     454              FROM pg_tables 
     455             WHERE schemaname IN (#{schemas}) 
     456          SQL 
     457        end 
    446458      end 
    447  
     459       
    448460      # Returns the list of all indexes for a table. 
    449461      def indexes(table_name, name = nil) 
    450         result = query(<<-SQL, name) 
    451           SELECT i.relname, d.indisunique, a.attname 
    452             FROM pg_class t, pg_class i, pg_index d, pg_attribute a 
    453            WHERE i.relkind = 'i' 
    454              AND d.indexrelid = i.oid 
    455              AND d.indisprimary = 'f' 
    456              AND t.oid = d.indrelid 
    457              AND t.relname = '#{table_name}' 
    458              AND a.attrelid = t.oid 
    459              AND ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum 
    460                 OR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum 
    461                 OR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum 
    462                 OR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum 
    463                 OR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum ) 
    464           ORDER BY i.relname 
    465         SQL 
    466  
     462        @indexes ||= Hash.new 
     463         
     464        @indexes[table_name] ||= begin 
     465          result = query(<<-SQL, name) 
     466            SELECT i.relname, d.indisunique, a.attname 
     467              FROM pg_class t, pg_class i, pg_index d, pg_attribute a 
     468             WHERE i.relkind = 'i' 
     469               AND d.indexrelid = i.oid 
     470               AND d.indisprimary = 'f' 
     471               AND t.oid = d.indrelid 
     472               AND t.relname = '#{table_name}' 
     473               AND a.attrelid = t.oid 
     474               AND ( d.indkey[0]=a.attnum OR d.indkey[1]=a.attnum 
     475                  OR d.indkey[2]=a.attnum OR d.indkey[3]=a.attnum 
     476                  OR d.indkey[4]=a.attnum OR d.indkey[5]=a.attnum 
     477                  OR d.indkey[6]=a.attnum OR d.indkey[7]=a.attnum 
     478                  OR d.indkey[8]=a.attnum OR d.indkey[9]=a.attnum ) 
     479            ORDER BY i.relname 
     480          SQL 
     481        end 
     482         
    467483        current_index = nil 
    468484        indexes = [] 
    469485 
     
    542558      def pk_and_sequence_for(table) #:nodoc: 
    543559        # First try looking for a sequence with a dependency on the 
    544560        # given table's primary key. 
    545         result = query(<<-end_sql, 'PK and serial sequence')[0] 
    546           SELECT attr.attname, seq.relname 
    547           FROM pg_class      seq, 
    548                pg_attribute  attr, 
    549                pg_depend     dep, 
    550                pg_namespace  name, 
    551                pg_constraint cons 
    552           WHERE seq.oid           = dep.objid 
    553             AND seq.relkind       = 'S' 
    554             AND attr.attrelid     = dep.refobjid 
    555             AND attr.attnum       = dep.refobjsubid 
    556             AND attr.attrelid     = cons.conrelid 
    557             AND attr.attnum       = cons.conkey[1] 
    558             AND cons.contype      = 'p' 
    559             AND dep.refobjid      = '#{table}'::regclass 
    560         end_sql 
    561  
    562         if result.nil? or result.empty? 
    563           # If that fails, try parsing the primary key's default value. 
    564           # Support the 7.x and 8.0 nextval('foo'::text) as well as 
    565           # the 8.1+ nextval('foo'::regclass). 
    566           result = query(<<-end_sql, 'PK and custom sequence')[0] 
    567             SELECT attr.attname, split_part(def.adsrc, '''', 2) 
    568             FROM pg_class       t 
    569             JOIN pg_attribute   attr ON (t.oid = attrelid) 
    570             JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum) 
    571             JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1]) 
    572             WHERE t.oid = '#{table}'::regclass 
    573               AND cons.contype = 'p' 
    574               AND def.adsrc ~* 'nextval' 
     561         
     562        @sequences ||= Hash.new 
     563         
     564        @sequences[table] ||= begin 
     565          result = query(<<-end_sql, 'PK and serial sequence')[0] 
     566            SELECT attr.attname, seq.relname 
     567            FROM pg_class      seq, 
     568                 pg_attribute  attr, 
     569                 pg_depend     dep, 
     570                 pg_namespace  name, 
     571                 pg_constraint cons 
     572            WHERE seq.oid           = dep.objid 
     573              AND seq.relkind       = 'S' 
     574              AND attr.attrelid     = dep.refobjid 
     575              AND attr.attnum       = dep.refobjsubid 
     576              AND attr.attrelid     = cons.conrelid 
     577              AND attr.attnum       = cons.conkey[1] 
     578              AND cons.contype      = 'p' 
     579              AND dep.refobjid      = '#{table}'::regclass 
    575580          end_sql 
    576         end 
    577         # [primary_key, sequence] 
    578         [result.first, result.last] 
     581 
     582          if result.nil? or result.empty? 
     583            # If that fails, try parsing the primary key's default value. 
     584            # Support the 7.x and 8.0 nextval('foo'::text) as well as 
     585            # the 8.1+ nextval('foo'::regclass). 
     586            result = query(<<-end_sql, 'PK and custom sequence')[0] 
     587              SELECT attr.attname, split_part(def.adsrc, '''', 2) 
     588              FROM pg_class       t 
     589              JOIN pg_attribute   attr ON (t.oid = attrelid) 
     590              JOIN pg_attrdef     def  ON (adrelid = attrelid AND adnum = attnum) 
     591              JOIN pg_constraint  cons ON (conrelid = adrelid AND adnum = conkey[1]) 
     592              WHERE t.oid = '#{table}'::regclass 
     593                AND cons.contype = 'p' 
     594                AND def.adsrc ~* 'nextval' 
     595            end_sql 
     596          end 
     597          # [primary_key, sequence] 
     598          [result.first, result.last] 
     599        end           
    579600      rescue 
    580601        nil 
    581602      end 
     
    833854        #  - format_type includes the column size constraint, e.g. varchar(50) 
    834855        #  - ::regclass is a function that gives the id for a table name 
    835856        def column_definitions(table_name) #:nodoc: 
    836           query <<-end_sql 
    837             SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull 
    838               FROM pg_attribute a LEFT JOIN pg_attrdef d 
    839                 ON a.attrelid = d.adrelid AND a.attnum = d.adnum 
    840              WHERE a.attrelid = '#{table_name}'::regclass 
    841                AND a.attnum > 0 AND NOT a.attisdropped 
    842              ORDER BY a.attnum 
    843           end_sql 
     857          @column_defs ||= Hash.new 
     858           
     859          @column_defs[table_name] ||= begin 
     860            query <<-end_sql 
     861              SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull 
     862                FROM pg_attribute a LEFT JOIN pg_attrdef d 
     863                  ON a.attrelid = d.adrelid AND a.attnum = d.adnum 
     864               WHERE a.attrelid = '#{table_name}'::regclass 
     865                 AND a.attnum > 0 AND NOT a.attisdropped 
     866               ORDER BY a.attnum 
     867            end_sql 
     868          end 
    844869        end 
    845870    end 
    846871  end