sql >> Database >  >> RDS >> PostgreSQL

Wat betekent regclass in Postgresql

Nee, je hebt de cast niet nodig voor regclass bij het aanroepen van een functie zoals nextval die een regclass accepteert parameter, want er is een impliciete cast van text naar regclass . In sommige andere contexten een expliciete cast naar regclass kan nodig zijn.

Uitleg:

::regclass is een cast, zoals ::integer .

regclass is een "magisch" gegevenstype; het is eigenlijk een alias voor oid , of "object-ID". Zie Typen object-ID's in de documentatie. Casten naar regclass is een kortere manier om te zeggen "dit is de naam van een relatie, converteer deze naar de oid van die relatie". Cast naar regclass zijn op de hoogte van het search_path , in tegenstelling tot pg_class voor de oid . van een relatie rechtstreeks, dus casten naar regclass is niet precies gelijk aan subquery's pg_class .

Tabellen zijn relaties. Dat geldt ook voor sequenties en weergaven. Je kunt dus de oid van een weergave of reeks krijgen door ook naar regclass te casten.

Er zijn impliciete casts gedefinieerd voor text naar regclass , dus als je de expliciete cast weglaat en een functie aanroept die regclass accepteert de cast wordt automatisch gedaan. Dus je doet niet heb het bijvoorbeeld nodig in nextval oproepen.

Er zijn andere plaatsen waar u kunt. U kunt bijvoorbeeld text . niet vergelijken rechtstreeks met oid; dus je kunt dit doen:

regress=> select * from pg_class where oid = 'table1'::regclass;

maar niet dit:

regress=> select * from pg_class where oid = 'table1';
ERROR:  invalid input syntax for type oid: "table1"
LINE 1: select * from pg_class where oid = 'table1';

Voor de lol probeerde ik een query te schrijven die de equivalente bewerking uitvoerde van casten naar regclass . Gebruik het niet, het is vooral voor de lol en als een poging om te demonstreren wat er werkelijk gebeurt. Tenzij je echt geïnteresseerd bent in hoe Pg's lef werkt, kun je hier stoppen met lezen.

Zoals ik het begrijp, 'sequence_name'::regclass::oid komt ongeveer overeen met de volgende zoekopdracht:

WITH sp(sp_ord, sp_schema) AS (
  SELECT 
    generate_series(1, array_length(current_schemas('t'),1)),
    unnest(current_schemas('t'))
)
SELECT c.oid
FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid)
INNER JOIN sp ON (n.nspname = sp.sp_schema)
WHERE c.relname = 'sequence_name'
ORDER BY sp.sp_ord
LIMIT 1;

behalve dat het een stuk korter en een stuk sneller is. Zie Systeeminformatiefuncties voor de definitie van current_schemas(...) , enz.

Met andere woorden:

  • Ontvang een ab-array met alle schema's waartoe we toegang hebben en koppel elk item met een rangtelwoord voor zijn positie in de array
  • Zoek pg_class voor relaties met overeenkomende namen en associeer elk met zijn naamruimte (schema)
  • Sorteer de lijst met resterende relaties op de volgorde waarin hun schema's verschenen in search_path
  • en kies de eerste wedstrijd


  1. Oracle sql - join met invoerparameter

  2. Hoe het laden van gegevens in InnoDB versnellen (LOAD DATA INFILE)?

  3. Oracle 11.1 bug die Juliaans dagnummer converteert naar DATE of TIMESTAMP

  4. Kan ik tabelretourfuncties 'opnieuw compileren' nadat die tabel is gewijzigd tijdens de databasemigratie?