すべてのプロダクト
Search
ドキュメントセンター

Hologres:生成列

最終更新日:Sep 02, 2026

生成列は、他の列から計算される特殊な列です。格納生成列と仮想生成列に分類されます。Hologres V3.1 以降では、格納生成列がサポートされています。格納生成列は、データの書き込みまたは更新時に自動的に計算され、ストレージ領域を消費します。仮想生成列は現在サポートされていません。このトピックでは、Hologres で格納生成列を使用する方法について説明します。

シナリオ

  • 必要なフィールドの自動計算:計算ロジックを手動で処理する必要がなくなります。

  • データ一貫性:人的ミスやコードロジックの問題による不整合を防止します。

  • クエリパフォーマンスの最適化:高頻度のクエリシナリオでは、格納生成列の読み取りは通常の列の読み取りと同等です。

  • ビジネスロジックの簡素化:定型的なデータ変換操作における SQL の複雑さを低減します。

ビジネス要件に基づいて生成列を適切に使用することで、開発効率を大幅に向上させ、データの信頼性を確保できます。

構文

生成列を宣言するには GENERATED ALWAYS AS 句を使用し、格納生成列を指定するには STORED キーワードを使用します。

  • 生成列を含むテーブルを作成します。

    CREATE TABLE generated_col_t (
        [...,]
        col1 INT,
        col2 INT GENERATED ALWAYS AS (col1 + 1) STORED
    );
  • 生成列を含む論理パーティションテーブルを作成し、その生成列をパーティションキーとして使用します。

    CREATE TABLE generated_col_logical_part (
        a TEXT,
        b INT,
        ts TIMESTAMP NOT NULL,
        d TIMESTAMP GENERATED ALWAYS AS (date_trunc('day', ts)) STORED NOT NULL
    )
    LOGICAL PARTITION BY LIST(d);

注意事項

  • CREATE TABLE

    • 生成列を定義する場合、IMMUTABLE な関数または式のみがサポートされます。CURRENT_DATE や RANDOM など、IMMUTABLE でない関数はサポートされていません。

    • 生成列の式は、別の生成列を参照できません。また、生成列に default 値を定義することもできません。

    • パーティションテーブルを作成する場合、論理パーティションテーブル のパーティションキーとして生成列を設定できますが、物理パーティションテーブル のパーティションキーとして生成列を設定することはできません。パーティションテーブル内の通常の列は生成列に設定できます。

    • CREATE FOREIGN TABLE を使用して外部テーブルを作成する場合、生成列はサポートされていません。

    • 生成列は、プライマリキー、分散キー、セグメントキー、クラスター化インデックス、ビットマップインデックス、辞書エンコード列など、各種 Hologres インデックスとして設定できます。

  • ALTER TABLE

    • 列を生成列として追加することはできません。

    • 生成列は削除できます。ただし、生成列を削除する前に、その生成列が参照する列を削除することはできません。

    • 生成列のデータ型、または生成列が参照する列のデータ型は変更できません。これを実現するには、REBUILD 機能の使用を推奨します。詳細については、「REBUILD」をご参照ください。

    • 生成列の名前は変更できます。

  • DML/DQL

    • データを挿入または更新する際は、文から生成列を省略するか、値として default を指定できます。生成列に特定の値を直接挿入することはできません。

    • データを更新する場合、生成列またはそれが参照する列が分散キーである場合、その列の更新はサポートされていません。

    • 固定実行計画を使用して更新を実行する場合、プライマリキーに生成列が含まれているときは、プライマリキーに生成列が参照するすべての列も含める必要があります。

    • 固定実行計画を使用して部分列更新を実行する場合、生成列が複数の通常列を参照しているときは、それらの列の一部のみを更新することはサポートされていません。

    • 生成列を含むテーブルに対するその他の操作はすべてサポートされています。これには、HQE エンジンによる読み取り/書き込み操作、固定実行計画による読み取り/書き込み操作、および Copy などの操作が含まれます。

  • その他の操作

    • CREATE TABLE LIKE は、生成列を含むテーブルをサポートしています。生成列のプロパティを保持するには、hg_experimental_enable_create_table_like_properties パラメーターを有効にする必要があります。

    • CREATE TABLE AS を使用する場合、生成列を含む元のテーブルはサポートされていません。

    • 生成列を含むテーブルのパラメーターを変更するには、REBUILD 構文 (テーブルグループの移行を含む) を使用できます。詳細については、「REBUILD」をご参照ください。HG_MOVE_TABLE_TO_TABLE_GROUP 構文によるテーブルグループの移行はサポートされていません。

    • 生成列を含むテーブルに対して INSERT OVERWRITE 操作を実行するには、Hologres V3.1 以降でサポートされているネイティブの INSERT OVERWRITE 構文を使用します。従来の hg_insert_overwrite 構文はサポートされていません。詳細については、「INSERT OVERWRITE」をご参照ください。

例

  1. 生成列を含むテーブルを作成します。

    CREATE TABLE generated_col_t (
        id INT PRIMARY KEY,
        col1 INT,
        col2 INT GENERATED ALWAYS AS (col1 + 1) STORED
    );
  2. データをインポートします。

    • 生成列以外のすべての列にデータをインポートできます。例:

      INSERT INTO generated_col_t VALUES (1, 1);
      INSERT INTO generated_col_t(id, col1) VALUES (2, 2);

      SELECT * FROM generated_col_t; クエリを実行すると、次の結果が返されます。

      id	col1	col2
      1	1	2
      2	2	3
    • データのインポート時に、生成列に default キーワードを使用します。例:

      INSERT INTO generated_col_t VALUES (3, 3, default);
      INSERT INTO generated_col_t(id, col1, col2) VALUES (4, 4, default);

      SELECT * FROM generated_col_t; クエリを実行すると、次の結果が返されます。

      id	col1	col2
      4	4	5
      2	2	3
      3	3	4
      1	1	2
    • 非サポート:生成列に直接データをインポートします。例:

      INSERT INTO generated_col_t VALUES (5, 5, 6);
      INSERT INTO generated_col_t(id, col1, col2) VALUES (6, 6, 7);

      次のエラーが返されます。

      ERROR: cannot insert into column "col2"
      Detail: Column "col2" is a generated column.
  3. データを更新します。

    • 生成列以外の列は更新できます。例:

      UPDATE generated_col_t SET col1 = 2 WHERE id = 1;

      SELECT * FROM generated_col_t; クエリを実行すると、次の結果が返されます。

      id	col1	col2
      2	2	3
      3	3	4
      4	4	5
      1	2	3     -- この行は変更されています 
    • 更新時に、生成列に default キーワードを使用します。例:

      UPDATE generated_col_t SET col1 = 3, col2 = default WHERE id = 2;

      SELECT * FROM generated_col_t; クエリを実行すると、次の結果が返されます。

      id	col1	col2
      3	3	4
      2	3	4    -- この行は変更されています
      4	4	5
      1	2	3
    • 非サポート:生成列を直接更新します。例:

      UPDATE generated_col_t SET col2 = 4 WHERE id = 3;

      次のエラーが返されます。

      ERROR: column "col2" can only be updated to DEFAULT
      Detail: Column "col2" is a generated column.

特定のパラメーター型に対して関数が IMMUTABLE であるかどうかは、次の SQL クエリで確認できます。たとえば、to_char 関数が IMMUTABLE となるのは、入力が TIMESTAMP WITH TIME ZONE 型である場合に限られます。したがって、この関数を生成列で使用する場合は、パラメーター型が一致していることを確認する必要があります。

SELECT n.nspname AS "Schema",
  p.proname AS "Name",
  pg_catalog.pg_get_function_result(p.oid) AS "Result data type",
  pg_catalog.pg_get_function_arguments(p.oid) AS "Argument data types",
 CASE p.prokind
  WHEN 'a' THEN 'agg'
  WHEN 'w' THEN 'window'
  WHEN 'p' THEN 'proc'
  ELSE 'func'
 END AS "Type",
 CASE
  WHEN p.provolatile = 'i' THEN 'immutable'
  WHEN p.provolatile = 's' THEN 'stable'
  WHEN p.provolatile = 'v' THEN 'volatile'
 END AS "Volatility",
 CASE
  WHEN p.proparallel = 'r' THEN 'restricted'
  WHEN p.proparallel = 's' THEN 'safe'
  WHEN p.proparallel = 'u' THEN 'unsafe'
 END AS "Parallel",
 pg_catalog.pg_get_userbyid(p.proowner) AS "Owner",
 CASE WHEN prosecdef THEN 'definer' ELSE 'invoker' END AS "Security",
 pg_catalog.array_to_string(p.proacl, E'\n') AS "Access privileges",
 l.lanname AS "Language",
 p.prosrc AS "Source code",
 pg_catalog.obj_description(p.oid, 'pg_proc') AS "Description"
FROM pg_catalog.pg_proc p
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
     LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang
-- Target function
WHERE p.proname OPERATOR(pg_catalog.~) '^(to_char)$' COLLATE pg_catalog.default
  AND pg_catalog.pg_function_is_visible(p.oid)
ORDER BY 1, 2, 4;