Code Monkey home page Code Monkey logo

pgcodekeeper's Introduction

Apache 2.0

pgCodeKeeper

A tool for easier PostgreSQL development.

  • Comparing database code is very easy now. Compare live DB instances, pg_dump output, as well as pgCodeKeeper projects.
  • Generate migration scripts via a user-friendly interface. You can use both live DB instances and DB dumps as initial data. You can also compare pgCodeKeeper projects — useful when working with versions control systems.
  • pgCodeKeeper is an Eclipse IDE plug-in. The DB code is saved as an Eclipse project, and the project can be tracked under any of the versions control systems supported by Eclipse — Git, SVN, Mercurial, CVS and many others.

Download

pgCodeKeeper requires Java (JRE) 11+ to run.

You can download prebuilt packages and CLI version from GitHub releases.

If you already have Eclipse IDE installed you can install pgCodeKeeper plugin using Marketplace or https://pgcodekeeper.org/update/ update site.

Documentation

Build

Build requires Java (JDK) 11+ and Apache Maven 3.6+.

git clone https://github.com/pgcodekeeper/pgcodekeeper.git
cd pgcodekeeper
mvn verify

Binaries will be created in ru.taximaxim.codekeeper.mainapp/product/rcp/target/products
CLI package will be created in ru.taximaxim.codekeeper.mainapp/product/standalone/target/products

Notes

  • If you have any questions, suggestions, ideas, etc - contact us in our Telegram chat or create an issue.
  • Pull requests are welcome.
  • Visit https://pgcodekeeper.org for more information.
  • Thanks for using pgCodeKeeper!

Contributing

Project Structure

The project consists of several modules that implement Eclipse RCP plugins (and, by extension, OSGi bundles).

Main Modules

  • pom.xml - first, root pom.xml defines Maven build order and environment. Not required for application development.
  • ru.taximaxim.codekeeper.core - the core module containing database schema classes and loaders, comparison logic, SQL code generators and parsers.
  • ru.taximaxim.codekeeper.cli - CLI implementation module.
  • ru.taximaxim.codekeeper.ui - GUI module, Eclipse integration.

Test Modules

  • ru.taximaxim.codekeeper.core.tests - majority of unit and functional tests.
  • ru.taximaxim.codekeeper.cli.tests - tests for CLI.
  • ru.taximaxim.codekeeper.ui.tests - tests for pieces of logic that were implemented in UI module instead of the core module.

Misc Modules

  • ru.taximaxim.codekeeper.mainapp - "branding plugin", provides Eclipse with feature information, images, etc. Also contains development Target platform files.
  • ru.taximaxim.codekeeper.mainapp/report - tests coverage report module.
  • ru.taximaxim.codekeeper.mainapp/feature - Eclipse feature module.
  • ru.taximaxim.codekeeper.mainapp/updatesite - Eclipse p2 repository/update site module.
  • ru.taximaxim.codekeeper.mainapp/product/rcp - Eclipse product description, used to build pgCodeKeeper packages.
  • ru.taximaxim.codekeeper.mainapp/product/standalone - Eclipse product description, used to build CLI version packages.
  • ru.taximaxim.codekeeper.mainapp/deploy - GitHub deploy module.

Module Contents

ru.taximaxim.codekeeper.core

This module was derived from apgdiff project. At this point it is almost fully rewritten according to our needs.
Primary packages of this module are:

  • ru.taximaxim.codekeeper.core.schema - contains classes that describe SQL objects. Each class contains object properties, creation SQL code generator, object comparison logic and ALTER code generator. Notable classes:
    • PgStatement - all object classes must be derived from this one. Defines main API for working with objects.
    • PgDatabase - root class for every loaded database schema.
    • GenericColumn - generic reference to any object (used to be a column reference).
  • ru.taximaxim.codekeeper.core.schema.meta - simplified SQL object classes for database structure serialization.
  • ru.taximaxim.codekeeper.core.schema.meta (resources) - serialized descriptions of PostgreSQL's system objects (built using JdbcSystemLoader).
  • ru.taximaxim.codekeeper.core.loader - database schema loaders: project, SQL file, JDBC, library.
    • ProjectLoader - loads a database from project structure. (!) Keep in sync with UIProjectLoader.
    • PgDumpLoader - loads objects into a database structure from a file. (!) Keep in sync with PgUIDumpLoader.
  • ru.taximaxim.codekeeper.core.loader (resources) - SQL queries for JdbcLoaders, used by Java code via JdbcQueries.
  • ru.taximaxim.codekeeper.core.loader.jdbc - classes that create schema objects based on JDBC ResultSets.
  • ru.taximaxim.codekeeper.core.parsers.antlr - generated ANTLR4 parser code, plus utility parser classes. Notable classes:
    • AntlrParser - factory methods for parser creation and parallel parser operations.
    • QNameParser - utility class for parsing and splitting qualified names.
    • ScriptParser - simple parser that splits statements for later execution.
    • Custom(T)SQLParserListener - main entry point for parsing SQLs into schema objects.
  • ru.taximaxim.codekeeper.core.parsers.antlr.statements - processor classes that create schema objects based on parser-read data. Notable classes:
    • ParserAbstract - common base class for all processors.
  • ru.taximaxim.codekeeper.core.parsers.antlr.expr - expression analysis classes: find dependencies in expressions and infer expression types for overloaded function call resolution.
  • ru.taximaxim.codekeeper.core.parsers.antlr.expr.launcher - support for parallel expression analysis.
  • ru.taximaxim.codekeeper.core.formatter - SQL and pl/pgsql code formatters.
  • ru.taximaxim.codekeeper.core - util and general-purpose classes. Notable classes:
    • PgDiff - entry point for database schema diff operations.
  • ru.taximaxim.codekeeper.core.model.difftree - classes representing and creating an object diff tree. Notable classes:
    • DbObjType - enum of all SQL object types supported by the program.
    • TreeElement - a node in an object diff tree.
    • DiffTree - object diff tree factory.
    • TreeFlattener - filters and flattens the tree into a list of nodes according to requested parameters.
  • ru.taximaxim.codekeeper.core.model.graph - object dependency graph classes, built using JGraphT library. Notable classes:
    • DepcyGraph - the dependency graph and its builder.
    • DepcyResolver - main script building algorithm. Creates a list of StatementActions according to requested object changes and object dependencies.
    • DepcyTreeExtender - extends an object diff tree according to object dependencies.
    • DepcyWriter - prints a dependency tree for an object.
  • ru.taximaxim.codekeeper.core.model.exporter - classes that save and update the project files on disk. Notable classes:
    • ModelExporter, MsModelExporter, AbstractModelExporter - exporters for PG and MS projects and their common abstract part.
    • OverridesModelExporter - exports project structure containing only permission overrides.
  • ru.taximaxim.codekeeper.core.sql - a categorized list of all PostgreSQL keywords. Generated from PostgreSQL source.
  • ru.taximaxim.codekeeper.core.ignoreparser - builder for IgnoreLists.
  • ru.taximaxim.codekeeper.core - main package containing general stuff: e.g. string constants, utils.
  • antlr-src - sources for ANTLR4 parsers. We maintain parsers for PostgreSQL, pl/pgsql, T-SQL, and also our custom Ignore Lists and PostgreSQL ACLs syntax.
    These need to be built using your preferred ANTLR4 builder into ru.taximaxim.codekeeper.core.parsers.antlr package.

ru.taximaxim.codekeeper.ui

Majority of code in this module implements Eclipse integration, and also wraps core logic into a more UI-suitable forms.

  • plugin.xml - main Eclipse integration file. All integration code is referenced from here.
  • ru.taximaxim.codekeeper.ui.editors - main project editor and its supporting classes. Notable classes:
    • ProjectEditorDiffer - main project editor. Loads and compares databases, allows user to select changes and saves the into project or generates and diff script for the database.
  • ru.taximaxim.codekeeper.ui.differ - classes for diff creation. Notable classes:
    • DbSource - an abstraction, factory, and implementations for various database loaders.
    • TreeDiffer, Differ - first creates a diff tree, second creates a diff script based on the tree and user selection.
    • DiffTableViewer - GUI element responsible for showing tree diff elements. Part of ProjectEditorDiffer separated for reuse in other UIs.
  • ru.taximaxim.codekeeper.ui.pgdbproject - project classes and various project wizards (New, Import, etc). Notable classes:
    • PgDbProject - utility wrapper for Eclipse's IProject.
  • ru.taximaxim.codekeeper.ui.pgdbproject.parser - UI-specific parts of database loaders. Notable classes:
    • PgDbParser - stores, serializes and updates project indices (object metadata and references).
    • UIProjectLoader - loads a database from project structure in Eclipse Workspace. (!) Keep in sync with ProjectLoader.
    • PgUIDumpLoader - loads objects into a database structure from an Eclipse's IFile. (!) Keep in sync with PgDumpLoader.
  • ru.taximaxim.codekeeper.ui.builders - Project Builders launch project index updates (metadata, errors etc) when an IDE build is triggered.
  • ru.taximaxim.codekeeper.ui.sqledit - SQL code editor. Notable classes:
    • SQLEditorSourceViewerConfiguration - main editor configuration class, ties in most other editor classes.
  • ru.taximaxim.codekeeper.ui.dbstore - database connection storage and GUI selection classes. Notable classes:
    • DbInfo - database connection parameters.
  • ru.taximaxim.codekeeper.ui.handlers - handlers for commands (IDE actions) registered with Eclipse in plugin.xml.
  • ru.taximaxim.codekeeper.ui.job - singleton wrapper for Eclipse Jobs.
  • ru.taximaxim.codekeeper.ui.dialogs - various dialogs. Notable classes:
    • ExceptionNotifier - reports and logs errors using Eclipse's StatusManager.
  • ru.taximaxim.codekeeper.ui.externalcalls - logic for calling external utilities (pg_dump etc).
  • ru.taximaxim.codekeeper.ui.generators - value generator for dummy data generation wizard (MockDataWizard).
  • ru.taximaxim.codekeeper.ui.prefs - Eclipse Preferences integration - global program settings.
  • ru.taximaxim.codekeeper.ui.properties - per-project settings.
  • ru.taximaxim.codekeeper.ui.reports - Google Analytics reports.
  • ru.taximaxim.codekeeper.ui.views - views showing misc info. Notable classes:
    • DepcyGraphView - shows dependency graph for objects currently selected in Project Editor.
    • ProjectOverrideView - shows library objects overridden by the project in current Project Editor.
    • ResultSetView - shows rows returned by SELECT or other commands executed in a script in SQL Editor.
  • ru.taximaxim.codekeeper.ui.views.navigator - Eclipse Project Explorer integration, see also plugin.xml
  • ru.taximaxim.codekeeper.ui - main package containing general stuff: e.g. string constants, utils. Notable classes:
    • UiSync - exception safety wrapper around SWT's Display.asyncExec(). (!) Use this instead of calling getDisplay().asyncExec().
    • UIConsts - majority of string IDs and other constants commonly used in UI.

ru.taximaxim.codekeeper.core.tests

Majority of tests are here.

  • ru.taximaxim.codekeeper.core - PgDiffTest, MsDiffTest - these test cases load old and new database schemas, generate a migration script and compare it to the expected diff file.
  • ru.taximaxim.codekeeper.core.depcies - tests here work similarly to simple diff tests above, except the concept of "user selection" is added. Migration script is built only with objects in usr files as starting points, other objects must be added to the script via dependency mechanism.
  • ru.taximaxim.codekeeper.core.loader - PgAntlrLoaderTest, MsAntlrLoaderTest - these tests load simple schemas from files and compare loaded PgDatabase objects with predefined ones.
  • ru.taximaxim.codekeeper.core.parsers - these tests simply parse test pieces of code (taken from PostgreSQL source) to verify parser validity.
  • ru.taximaxim.codekeeper.core.parsers.antlr.expr - these tests verify expression analysis and type inference mechanism.
  • ru.taximaxim.codekeeper.core.model.exporter - these test update exported project directories and verify which files have actually been changed.

ru.taximaxim.codekeeper.ui.tests

Simple tests for core logic wrappers: DbSource, Differ, ProjectUpdater.

Program Lifecycle

General program lifecycle goes as follows:

  1. PgDiffArguments object is filled with operation parameters.
  2. PgDatabases are loaded from requested sources, including their libraries and privilege overrides. Ignored schemas are skipped at this step.
    1. During the load dependencies of each object are found and recorded. Expressions are also analyzed to extract their dependencies including overloaded function calls.
    2. All parser and expression analysis operations are run in parallel using AntlrParser.ANTLR_POOL thread pool to speed up the process. Parallel operations are serialized by calling finishLoaders at the end of each loading process.
  3. The diff tree (represented by root TreeElement) is created by comparing two PgDatabases. In GUI this is then shown to the user to assess the situation and choose objects to work with.
  4. The diff tree, now containing "user selection", is used to selectively update project files on disk, or to generate a migration script.
  5. In latter case, each "selected" TreeElement is passed to DepcyResolver to generate script actions fulfilling the requested change, including actions on dependent objects. To do this, JGraphT object dependency graphs are built using dependency information found at the loading stage.
  6. Generated actions are now converted into SQL code with some last-moment post-processing and filtering.
  7. Generated SQL script is written to a file/stdout or shown in the GUI for user to review and run on their database.

pgcodekeeper's People

Contributors

antoon-r avatar axelcat avatar axepoh avatar baslo2 avatar endeavourl avatar kaldai avatar m1ra9e avatar miketav2016 avatar sik0rr avatar tolikr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pgcodekeeper's Issues

Исчезновение кавычек из RETURNS TABLE...

у меня есть функция вида:

CREATE OR REPLACE FUNCTION message_getcurrentmaxpk() RETURNS 
TABLE("IdMessageMax" integer, "CurrentDateTime" timestamp without time zone)
    LANGUAGE sql STABLE
    AS $$
  select  max(e.id_pk)  as "IdMessageMax",
      LOCALTIMESTAMP  as "CurrentDateTime"
  from sfact_sync.vw_elastic e 
  where e.table_name = 'message';
$$;

после её прогона из проекта в БД назад компаратор выдаёт:
RETURNS TABLE(IdMessageMax integer, CurrentDateTime timestamp without time zone)
то есть исчезли "" кавычки. Проверил что даёт pg_dump... там кавычки на месте:

CREATE FUNCTION sfact_sync.message_getcurrentmaxpk() RETURNS TABLE("IdMessageMax" integer, "CurrentDateTime" timestamp without time zone)
    LANGUAGE sql STABLE
    AS $$
        select  max(e.id_pk)    as "IdMessageMax",
                        LOCALTIMESTAMP  as "CurrentDateTime"
        from sfact_sync.vw_elastic e
        where e.table_name = 'message';
$$;

Поддержка FDW

Коллеги,
нужна поддержка в проекте вот таких команд:

CREATE SERVER IF NOT EXISTS mssql_ross
    FOREIGN DATA WRAPPER tds_fdw
    OPTIONS (servername 'name_server', port '1433', database 'MyDB', tds_version '7.1');

CREATE USER MAPPING IF NOT EXISTS FOR postgres SERVER mssql_ross OPTIONS (username 'Login', password 'password');

CREATE FOREIGN TABLE mssql_ross."ADDRESS"
   ("ID_ADDRESS" integer NOT NULL,
    "ID_REGION" integer NOT NULL,
    "POST_IND" numeric(6) NOT NULL,
    "ADDRESS" character varying(500) NOT NULL)
   SERVER mssql_ross
   OPTIONS (schema_name 'dbo', table_name 'ADDRESS');

default

Комапаратор и GENERATED BY DEFAULT AS IDENTITY

Версия кипера: 5.4.7
Всё таки есть проблемы с компаратором, хотя пока я не добрался ещё до неверного порядка DROP/CREATE :)
Вот смотрите:
Исходная таблица:

CREATE TABLE dbo.union_person_pb_temp (
	id_union_person_pb integer NOT NULL,
	id_union_person integer NOT NULL,
	id_person_bankrupt integer NOT NULL
);

добавляем в проекте "GENERATED BY DEFAULT AS IDENTITY"

CREATE TABLE dbo.union_person_pb_temp (
	id_union_person_pb integer GENERATED BY DEFAULT AS IDENTITY NOT NULL,
	id_union_person integer NOT NULL,
	id_person_bankrupt integer NOT NULL
);

компаратор различий не находит

Сборщик и ошибки для служебных файликов (psql и не только)

Требуется в некоторых отдельных папках хранить некие служебные скрипты.
В моём случае это sql текст для psql.
Сейчас сборщик находит в них синтаксические ошибки.
Желательно иметь настройку которая указывает, что в некоторых папках (по списку) не нужно искать синтаксические ошибки.
Однако желательно в файлах sql оставлять всё же синтаксическую раскраску.
То есть прошу убрать только маркировку ошибочных строк.

Генерация избыточного кода для дочерней секционированной таблицы

  1. Здесь избыточный код по унаследованным от родительской таблицы значениям по-умолчанию

image

  1. Здесь в качестве различий указаны унаследованные от родительской таблицы ограничения после выполнения миграционного скрипта.

image

image

В скрипт попадают изменения для удаленного столбца по дочерним таблицам

Вот как это выглядит:
Удаляем поля в родительской секционированной таблице
image

Одно из полей имеет свойство DEFAULT и для него компаратор видит различие по каждой из дочерних таблиц
image

Т.о. получаем скрипт
image

который падает с ошибкой
image

Добавление новой колонки NOT NULL

добавил в таблицу новую колонку:
job_number smallint DEFAULT 0 NOT NULL
сгенерировался код:
ALTER TABLE checksync_tables
ADD COLUMN job_number smallint;

ALTER TABLE ONLY checksync_tables
ALTER COLUMN job_number SET DEFAULT 0;

ALTER TABLE ONLY checksync_tables
ALTER COLUMN job_number SET NOT NULL;

к сожалению этот код просто так выполнить невозможно.
1-я строка добавит NULL поле
2-я строка объявит что для insert/update надо заполнить поле значением null
3-я строка попытается сделать поле NOT NULL но конечно у неё это не получится, так как в таблице все строки на данный момент есть NULL

для данной операции ожидалась команда
ALTER TABLE checksync_tables
ADD COLUMN job_number smallint NOT NULL DEFAULT 0;

ваш вариант генерации кода я использую в своих PRE скриптах, когда нужно в цикле мелкими пакетами обработать большую таблицу. Но это ручная работа и такой скрипт пишется специально и вручную. В этом случаем между 2-й и 3-й строкой стоит код замены всех строк с NULL на DEFAULT значение.

Искать потенциальные зависимости в теле функции

Сейчас не ищутся зависимости функции.

Можно разбивать тело функции на список слов и искать объекты с названием из этого списка и затем предлагать пользователю решать, какие объекты добавить в скрипт

Размещение триггерных и событийных функций в отдельном месте

Предлагаю рассмотреть возможность введения доп.настроек по местоположению для хранения в дереве папок триггерных и событийных функций.
Данные функции имеют обычно очень специфичный код на который важно обратить внимание любому новому DBA.
Акцент в виде не пустой папки - очень хорошо подходит для этой цели.

Добавление PRE и POST скриптов в проект

Предлагаю создать в корне проекта 2 папки и в каждой из них будет находиться файл скрипта

  1. Pre-Deployment
    Script.PreDeployment.sql
    и
  2. Post-Deployment
    Script.PostDeployment.sql

    смысл такой:
    внутри этих скриптов мы будем писать код PRE и POST модификации БД между процессом компаратора схем.
    Т.е.
  • открываем транзакцию
  • выполняем Script.PreDeployment.sql
  • запускаем компаратор
  • после выполнения полученного скрипт от компаратора выполняем Script.PostDeployment.sql
  • закрываем (откатываем транзакцию)
    Таким образом конечный скрипт, если его просто получить, будет состоять из 3-х частей
    1.Script.PreDeployment.sql
    2.скрипт компаратора
    3.Script.PostDeployment.sql

В моей практике достаточно часто нужно перед тем как сравнить схемы сначала выполнить PRE модификации, а потом уже сравнивать.
Потом в конце проливать некие скрипт типа синхронизации справочников или обновления неких полей.

Таким образом в SourceControl будет лежать целостная структура от деплоя к деплою.
В этих папках DBA будут накапливать свои некие скрипты, которые будут вызываться изнутри PRE и POST файлов через простой метаязык
например
:r .\LookupTables\dboAGGREGATE_REPORT_TYPE.sql

где
:r - внешний скрипт
. - корневая папка проекта

процесс, что я описал желательно иметь в виде 2-х вариантов (наверное 2 отдельные вкладки с разным поведением)

  1. как сейчас (то есть просто компаратор)
  2. формирование скрипта PRE+компаратор+POST (проведение полноценного деплоя)
    можно это назвать - publish

pg_dump 10.3 - всегда предваряет имя объекта именем схемы

Коллеги, начиная с 10.3 pg_dump теперь всегда предваряет имя объекта именем схемы. Таким образом внутри дампа нет теперь переключений путей поиска. Очень бы хотелось и внутри проекта не иметь таких команд:
SET search_path = bankrupt, pg_catalog;
Конечно если у человека всего 1 схема, то так сказать чертеж замутняется при этом, но вот если схем много... то это уже насущная необходимость.
Хотелось бы иметь флажок который вводил бы новый синтаксис, такой как в pg_dump 10.3

Для секционированных таблиц создаются индексы для каждой дочерней таблицы

Связано с #36 и #35.

Cейчас для секционированных таблиц генерируется создание индекса для каждой дочерней таблицы (выделил оранжевым).
В PostgreSQL 11 достаточно создать индекс только на родительской (выделил зеленым), на дочерних он создается автоматически.

image

генерация кода drop/create всех зависимых объектов таблицы

В случае когда выполняется перестановка порядка полей (на этапе разработки очень частая процедура), то компаратор эту ситуацию обнаруживает но ничего не генерирует.
Необходимо в данном случае выполнять полное пересоздание таблицы и поэтому нужно сгенерировать весь необходимый для этого код.

Улучшение читабельности функций при возврата таблиц и внешего вида таблиц.

Если функция возвращает таблицу, то сейчас все IN параметры и OUT параметры выстраиваются в очень длинную строку...

CREATE OR REPLACE FUNCTION message_getdetail(p_ids integer[]) RETURNS TABLE("IdMessage" integer, "MessageUid" character varying, "DatePublish" timestamp without time zone, "DateDelete" timestamp without time zone, "IdMessageType" integer, "Body" xml, "Number" character varying, "IdAnnulmentMessage" integer, "LockReason" character varying)

это трудно читать и поддерживать...
Предлагаю начать работы по форматированию кода в более читабельный вид:

CREATE OR REPLACE FUNCTION message_getdetail(p_ids integer[]) RETURNS TABLE(
"IdMessage"                  integer, 
"MessageUid"                 character varying, 
"DatePublish"                timestamp without time zone, 
"DateDelete"                 timestamp without time zone, 
"IdMessageType"              integer, 
"Body"                       xml, 
"Number"                     character varying, 
"IdAnnulmentMessage"         integer, 
"LockReason"                 character varying

такой же стиль форматирования предлагаю делать и для таблиц, которые сейчас не имеют табличного вида, что усложняет отделение имен колонок от их типов и других признаков (not null, default...)
Конечно же компаратор должен это понимать и внутри себя для сравнения использовать канонический вид лучше конечно именно такой - табличный).

Нулевой cost функции

pgcodekeeper округляет в меньшую сторону COST для функции.
Например, такой фрагмент объявления функции:

CREATE OR REPLACE FUNCTION public.test()
 RETURNS integer
 LANGUAGE sql
 COST 0.8
AS $function$
    select 1;
$function$

сгенерирует такой результат:

CREATE OR REPLACE FUNCTION public.test() RETURNS integer
    LANGUAGE sql COST 0
    AS $$
    select 1;
$$;

Добавление в миграционнные скрипты DROP перед CREATE

В дополнение к #40

Для исключения потенциальных ошибок при установке миграционных скриптов на БД заказчика, на наш взгляд, было бы не лишним добавить в миграционные скрипты перед конструкциями:
CREATE VIEW IF NOT EXISTS
CREATE MATERIALIZED VIEW IF NOT EXISTS
CREATE TRIGGER

соответствующую создаваемому объекту конструкцию
DROP { VIEW | MATERIALIZED VIEW | TRIGGER } IF EXISTS
независимо от наличия этих объектов в целевой БД.

Ошибочная ситуация без DROP может возникнуть в случае если объект по какой-то причине, например в рамках критического обращения, создался ранее на БД заказчика вручную, позже перенесен на БД разработки и там доработан. Были такие случаи на практике.

Добавление этой конструкции в скрипты дает гарантию того, что эти объекты в БД заказчика будут однозначно синхронизированы с БД разработки, а в случае триггера не упадут с ошибкой.

Можно реализовать в виде настройки проекта.

P.S. В целом инструмент pgCodeKeeper отличный, за что вам большое спасибо!
Когда можно ждать следующей версии (вероятно 5.4.0) и обновления версии в Marketplace Eclipse ?

11-я версия и DEFAULT

Уважаемые разработчики, может быть уже пора (на дворе 11.2) сделать вместо вот этого:
——————
ALTER TABLE base.hershel_events
ADD COLUMN hershel_event_stage_id smallint;

ALTER TABLE ONLY base.hershel_events
ALTER COLUMN hershel_event_stage_id SET DEFAULT 2;

UPDATE ONLY base.hershel_events
SET hershel_event_stage_id = DEFAULT WHERE hershel_event_stage_id IS NULL;

ALTER TABLE ONLY base.hershel_events
ALTER COLUMN hershel_event_stage_id SET NOT NULL;
————————-
для 11 версии всего одну команду
ALTER TABLE base.hershel_events ADD COLUMN hershel_event_stage_id smallint not null default 2;
просто сейчас за этим приходится следить.... напрягает

да, теперь такая команда работает только на уровне метаданных, за милисекунды

главное чтобы всё проводилось 1-й командой. Тогда новая колонка добавляется и в сразу в метаданных прописывается DEFAULT, а все команды чтения кортежей читают данные из метаданных если нет такого поля в кортеже

Добавление в миграционнные скрипты конструкций IF EXISTS/ IF NOT EXISTS

Есть ли возможность добавить в миграционные скрипты конструкции IF EXISTS/ IF NOT EXISTS для CREATE, DROP, ALTER где это возможно ?

DROP TRIGGER [ IF EXISTS ]
CREATE VIEW [ IF NOT EXISTS ]
DROP VIEW [ IF EXISTS ]
CREATE MATERIALIZED VIEW [ IF NOT EXISTS ]
DROP MATERIALIZED VIEW [ IF EXISTS ]
ALTER TABLE [ IF EXISTS ] ADD [ COLUMN ] [ IF NOT EXISTS ]
ALTER TABLE [ IF EXISTS ] DROP [ COLUMN ] [ IF EXISTS ]
CREATE INDEX [ IF NOT EXISTS ]
DROP INDEX [ IF EXISTS ]
и т.д.

Парсер сейчас тоже не понимает такое.

Поддержка %TYPE в описаниях входных и выходных параметров

Имена типов входных и выходных параметров можно указывать как ссылка на поле некой таблицы.
Ссылка на тип колонки записывается в виде имя_таблицы.имя_колонки%TYPE.
Иногда такое указание бывает полезно, так как позволяет создать функцию, независящую от изменений в определении таблицы.

поддержка команд FTS (Full Text Search)

Прошу внедрить поддержку следующих объектов:

CREATE/DROP/ALTER TEXT SEARCH PARSER ...
CREATE/DROP/ALTER TEXT SEARCH DICTIONARY ...
CREATE/DROP/ALTER TEXT SEARCH CONFIGURATION ...
CREATE/DROP/ALTER TEXT SEARCH TEMPLATE ...
default

Переименовывание колонки

создаем таблицу
CREATE TABLE unit_type (
id_unit_type integer NOT NULL,
code character varying(3) NOT NULL,
"NAME" character varying(50) NOT NULL,
short_name character varying(15) NOT NULL
);
проливаем в БД
потом изменяем колонку "NAME" на name. компаратор видит, что это переименовывание..
default
однако, генерит вот такой код:

SET search_path = sfact, pg_catalog;

ALTER TABLE unit_type
  DROP COLUMN "NAME";

SET search_path = sfact_bulk, pg_catalog;

ALTER TABLE unit_type
  DROP COLUMN "NAME";

SET search_path = sfact, pg_catalog;

ALTER TABLE unit_type
  ADD COLUMN name character varying(50);

ALTER TABLE ONLY unit_type
  ALTER COLUMN name SET NOT NULL;

SET search_path = sfact_bulk, pg_catalog;

ALTER TABLE unit_type
  ADD COLUMN name character varying(50);

оптимизация при конкурентном изменении индексов

Коллеги,
при коррекции индекса получаем вот такой код:
(всё это имеет смысл если стоит галка создавать конкурентно в настройках)

DROP INDEX sfact.idx_message_body_subjects;

CREATE INDEX CONCURRENTLY idx_message_body_subjects ON sfact.message USING gin (dbo.xmlsubjects2text(body, id_message_type) public.gin_trgm_ops)
WHERE (id_message_type = ANY (ARRAY[28, 29, 30, 42, 47, 48, 51, 52, 53, 55]));

может быть стоит делать более умно !?

CREATE INDEX CONCURRENTLY tmpNNN_idx_message_body_subjects ON sfact.message USING gin (dbo.xmlsubjects2text(body, id_message_type) public.gin_trgm_ops)
WHERE (id_message_type = ANY (ARRAY[28, 29, 30, 42, 47, 48, 51, 52, 53, 55]));

begin;
DROP INDEX sfact.idx_message_body_subjects;
alter index sfact.tmpNNN_idx_message_body_subjects RENAME TO idx_message_body_subjects;
commit;

смысл в том, чтобы система жила без индекса крайне малый промежуток времени, а во время его построения работа с таблицей не блокировалась при этом. Таблицы ведь на проде часто велики, и построить по ним индекс без CONCURRENTLY просто нельзя из-за невозможности остановки работы системы.

Генерация кода view и скобки

Коллеги, при генерации кода view расставляется много скобочек...

   FROM ((((((publisher p
     LEFT JOIN individual_entrepreneur ie ON ((ie.id_individual_entrepreneur = p.id_individual_entrepreneur)))
     LEFT JOIN company c ON ((c.id_company = p.id_company)))
     LEFT JOIN appraiser a ON ((a.id_appraiser = p.id_appraiser)))
     LEFT JOIN foreign_system fs ON ((fs.id_foreign_system = p.id_foreign_system)))
     LEFT JOIN person ps ON ((ps.id_person = p.id_person)))
     LEFT JOIN non_resident_company nr ON ((nr.id_non_resident_company = p.id_non_resident_company)));

так генерит дамп pg_dump. Лучше бы так как генерит код вызов pg_get_viewdef с pretty=true, (так это делает psql/pgadmin).
Предлагаю сделать так, чтобы можно было по настройке отказаться от совместимости с pg_dump и выводить код view в стиле psql.

Нет сообщения что имя функции указано без схемы

в папке схемы создал новую папку FUNCTION
вызвал контекстное меню и выбрал "Объект SQL"
в форме в окошко вбил имя функции (без схемы) и нажал Finish
и ничего не произошло... форма не закрылась хотя кнопка нажалась точно.
Указываю схему и снова нажимаю Finish - всё создается.

Загрузка функций в PostgreSQL 11

При попытке инициализировать проект, происходит ошибка
image
java.lang.reflect.InvocationTargetException: IOException while creating project: Error while reading database schema via JDBC, error occured while processing jdbc:FunctionsReader query
ERROR: column p.proiswindow does not exist
Position: 483
at ru.taximaxim.codekeeper.ui.pgdbproject.InitProjectFromSource.run(InitProjectFromSource.java:41)
at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:122)
Caused by: java.io.IOException: Error while reading database schema via JDBC, error occured while processing jdbc:FunctionsReader query
ERROR: column p.proiswindow does not exist
Position: 483
at cz.startnet.utils.pgdiff.loader.JdbcLoader.getDbFromJdbc(JdbcLoader.java:130)
at cz.startnet.utils.pgdiff.loader.JdbcLoader.getDbFromJdbc(JdbcLoader.java:63)
at ru.taximaxim.codekeeper.ui.differ.DbSourceJdbc.loadInternal(DbSource.java:409)
at ru.taximaxim.codekeeper.ui.differ.DbSource.get(DbSource.java:71)
at ru.taximaxim.codekeeper.ui.pgdbproject.InitProjectFromSource.initRepoFromSource(InitProjectFromSource.java:55)
at ru.taximaxim.codekeeper.ui.pgdbproject.InitProjectFromSource.run(InitProjectFromSource.java:37)
... 1 more
Caused by: org.postgresql.util.PSQLException: ERROR: column p.proiswindow does not exist
Position: 483
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2412)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2125)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:297)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:428)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:354)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:301)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:287)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:264)
at org.postgresql.jdbc.PgStatement.executeQuery(PgStatement.java:231)
at cz.startnet.utils.pgdiff.loader.jdbc.JdbcReader.read(JdbcReader.java:54)
at cz.startnet.utils.pgdiff.loader.JdbcLoader.getDbFromJdbc(JdbcLoader.java:102)
... 6 more

Eclipse - Version: 2018-09 (4.9.0)
Postgres 11.0
pgCodeKeeper 5.1.6

нарушен порядок drop/create объектов в скрипте

что у меня выбрано:
photo_2019-03-22_10-14-50

что получилось в скрипте:
photo_2019-03-22_10-15-10

сам скрипт:
2019-03-22 09'55'26 migration.zip

код таблицы sfact.message:

CREATE TABLE sfact.message (
    date_create timestamp without time zone NOT NULL,
    date_last_modif timestamp without time zone NOT NULL,
    id_message integer NOT NULL,
    id_publisher integer NOT NULL,
    id_message_type integer NOT NULL,
    loaded_in_spark boolean DEFAULT false NOT NULL,
    is_invisible boolean DEFAULT false NOT NULL,
    is_published_by_svc boolean DEFAULT false NOT NULL,
	date_publish timestamp without time zone,
	date_delete timestamp without time zone,
	event_date timestamp without time zone,
	date_sign timestamp without time zone,
	date_disclosure timestamp without time zone,
	id_company integer,
	id_user_creator integer,
	id_annulment_message integer,
	id_notary integer,
	id_arbitr_manager integer,
	has_violation boolean,
	sign_status character varying(30) NOT NULL,
	message_uid character varying(32) DEFAULT reverse(replace(((public.uuid_generate_v1())::character varying(36))::text, '-'::text, ''::text)) NOT NULL,
	number character varying(8),
	lock_reason text,
	pkcs7 bytea,
	signed_data text,
	body xml NOT NULL,
	signed_data_byte bytea
);

ALTER TABLE sfact.message ALTER COLUMN id_message ADD GENERATED BY DEFAULT AS IDENTITY (
	SEQUENCE NAME message_id_message_seq
	START WITH 1
	INCREMENT BY 1
	MAXVALUE 2147483647
	NO MINVALUE
	CACHE 1
);

--------------------------------------------------------------------------------

CREATE INDEX idx_message_id_annulment_message ON sfact.message USING btree (id_annulment_message);

--------------------------------------------------------------------------------

CREATE UNIQUE INDEX unq_message_id_message_guid ON sfact.message USING btree (message_uid);

--------------------------------------------------------------------------------

CREATE UNIQUE INDEX unq_message_number ON sfact.message USING btree (number, date_delete);

--------------------------------------------------------------------------------

CREATE INDEX idx_message_id_publisher ON sfact.message USING btree (id_publisher, date_publish, date_delete);

--------------------------------------------------------------------------------

CREATE INDEX idx_message_body_bond ON sfact.message USING gin (dbo.xmlbond2jsonb(body))
WHERE (id_message_type = ANY (ARRAY[28, 29, 30]));

--------------------------------------------------------------------------------

CREATE INDEX idx_message_body_subjects ON sfact.message USING gin (dbo.xmlsubjects2text(body, id_message_type) public.gin_trgm_ops)
WHERE (id_message_type = ANY (ARRAY[28, 29, 30, 42, 47, 48, 51, 52, 53]));

--------------------------------------------------------------------------------

CREATE TRIGGER trig_message_iu
	BEFORE INSERT OR UPDATE OF id_message ON sfact.message
	FOR EACH ROW
	EXECUTE PROCEDURE sfact.trig_message_iu();

--------------------------------------------------------------------------------

ALTER TABLE sfact.message
	ADD CONSTRAINT pk_message PRIMARY KEY (id_message);

--------------------------------------------------------------------------------

ALTER TABLE sfact.message
	ADD CONSTRAINT chk_sign_status CHECK ((((sign_status)::text = 'Signed'::text) OR ((sign_status)::text = 'Unsigned'::text) OR ((sign_status)::text = 'WithoutSignature'::text)));

Сборщик подчеркивает update как ошибочный

Сборщик не распознает вот такой вид update

update dbo.union_person t set id_region = coalesce(rr.id_region, t.id_region)
from bankrupt.person_bankrupt b
    inner join bankrupt.region r on r.id_region = b.id_region
    inner join dbo.region rr on rr.number = r.number
where t.fio = dbo.make_fio(b.last_name, b.first_name, b.middle_name) and t.inn = b.inn
  and b.date_delete is null;

default

такой код успешно выполняется движком Postgres

Изменение типа поля в таблице

Меняем тип поля с int на text

image

тут все отлично

image

Если было указано свойство NOT NULL

image

то тоже все нормально

image

Но если у поля ранее было указано свойство DEFAULT

image

то получаем уже скрипт с DROP COLUMN:

image

OPERATOR -- не известный для pgcodekeeper объект

CREATE OPERATOR
pgcodekeeper об этом не знает и пишет в лог такое:
!ENTRY apgdiff 2 0 2018-10-05 15:20:08.767
!MESSAGE ANTLR Error:
dmp.sql line 47673:7 mismatched input 'OPERATOR' expecting {DOMAIN, EVENT, EXTENSION, FUNCTION, GLOBAL, INDEX, LANGUAGE, LOCAL, MATERIALIZED, PROCEDURAL, RECURSIVE, RULE, SCHEMA, SEQUENCE, SERVER, TEMP, TEMPORAR
Y, TEXT, TRANSFORM, TRIGGER, TRUSTED, TYPE, UNLOGGED, VIEW, COLLATION, CONSTRAINT, FOREIGN, OR, TABLE, UNIQUE, USER}

документация по OPERATOR — тут https://postgrespro.ru/docs/postgresql/9.6/xoper

Информирование об ошибках в скрипте наката

Коллеги, если в скрипте наката есть ошибка, то при выполнении появляется сообщение, что накат не удался и пишется позиция с ошибкой... но нет никакой информации ни о самой строке кода ни о номере строки....
С накатом и информированием что-то надо сделать. Сейчас слишком примитивно. Ошибки в большом скрипте искать трудно.
К примеру можно позиционироваться на нужную строку и подсветить проблемный участок.

окно сравнения кода отображает не весь код сравниваемого объекта

у меня есть в БД и в проекте табличка. В БД есть 2 индекса:

    "idx_union_company_temp_id_company" btree (id_company)
    "idx_union_company_temp_ogrn_inn" btree (ogrn, inn)

в проекте есть:

CREATE INDEX idx_union_company_temp_ogrn_inn ON union_company_temp USING btree (ogrn, inn);

и вот как это показывает окошко компаратора:
default

что в проекте:

SET search_path = dbo, pg_catalog;

CREATE UNLOGGED TABLE union_company_temp (
	id_union_company integer DEFAULT nextval('union_company_temp_id_union_company_seq'::regclass) NOT NULL,
	id_region integer,
	id_company integer,
	id_firm_bankrupt integer,
	id_sro integer,
	id_firm_trade_org integer,
	id_sro_trade_place integer,
	id_trade_place integer,
	is_active boolean DEFAULT true NOT NULL,
	ogrn character varying(13),
	inn character varying(10),
	short_name character varying(512),
	full_name character varying(1024) NOT NULL
);

ALTER TABLE union_company_temp OWNER TO postgres;

-- TABLE union_company_temp GRANT

REVOKE ALL ON TABLE union_company_temp FROM PUBLIC;
REVOKE ALL ON TABLE union_company_temp FROM postgres;
GRANT ALL ON TABLE union_company_temp TO postgres;
GRANT ALL ON TABLE union_company_temp TO developer_group;
GRANT ALL ON TABLE union_company_temp TO deploy;
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE union_company_temp TO public_group;

--------------------------------------------------------------------------------

CREATE INDEX idx_union_company_temp_ogrn_inn ON union_company_temp USING btree (ogrn, inn);

что в БД:

-- Table: union_company_temp

-- DROP TABLE union_company_temp;

CREATE UNLOGGED TABLE union_company_temp
(
  id_union_company serial NOT NULL,
  id_region integer,
  id_company integer,
  id_firm_bankrupt integer,
  id_sro integer,
  id_firm_trade_org integer,
  id_sro_trade_place integer,
  id_trade_place integer,
  is_active boolean NOT NULL DEFAULT true,
  ogrn character varying(13),
  inn character varying(10),
  short_name character varying(512),
  full_name character varying(1024) NOT NULL
)
WITH (
  OIDS=FALSE
);
ALTER TABLE union_company_temp
  OWNER TO postgres;
GRANT ALL ON TABLE union_company_temp TO developer_group;
GRANT ALL ON TABLE union_company_temp TO deploy;
GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE union_company_temp TO public_group;
GRANT ALL ON TABLE union_company_temp TO postgres;

-- Index: idx_union_company_temp_id_company

-- DROP INDEX idx_union_company_temp_id_company;

CREATE INDEX idx_union_company_temp_id_company
  ON union_company_temp
  USING btree
  (id_company);

-- Index: idx_union_company_temp_ogrn_inn

-- DROP INDEX idx_union_company_temp_ogrn_inn;

CREATE INDEX idx_union_company_temp_ogrn_inn
  ON union_company_temp
  USING btree
  (ogrn COLLATE pg_catalog."default", inn COLLATE pg_catalog."default");

Поддержка типов SERIAL (синтаксический сахар)

Типы данных smallserial, serial и bigserial не являются настоящими типами, а представляют собой просто удобное средство для создания колонок с уникальными идентификаторами (подобное свойству AUTO_INCREMENT в некоторых СУБД). В текущей реализации запись:

CREATE TABLE имя_таблицы (
имя_колонки SERIAL
);
равнозначна следующим командам:

CREATE SEQUENCE имя_таблицы_имя_колонки_seq;
CREATE TABLE имя_таблицы (
имя_колонки integer NOT NULL DEFAULT nextval('имя_таблицы_имя_колонки_seq')
);
ALTER SEQUENCE имя_таблицы_имя_колонки_seq OWNED BY имя_таблицы.имя_колонки;
То есть при определении такого типа создаётся целочисленная колонка со значением по умолчанию, извлекаемым из генератора последовательности. Чтобы в колонку нельзя было вставить NULL, в её определение добавляется ограничение NOT NULL. (Во многих случаях также имеет смысл добавить для этой колонки ограничения UNIQUE или PRIMARY KEY для защиты от ошибочного добавления дублирующихся значений, но автоматически это не происходит.) Последняя команда определяет, что последовательность «принадлежит» колонке, так что она будет удалена при удалении колонки или таблицы.

Имена типов serial и serial4 равнозначны: они создают колонки integer. Так же являются синонимами имена bigserial и serial8, но они создают колонки bigint.
И наконец, синонимами являются имена типов smallserial и serial2, но они создают колонку smallint.

Последовательность, созданная для колонки serial, автоматически удаляется при удалении связанной колонки. Последовательность можно удалить и отдельно от колонки, но при этом также будет удалено определение значения по умолчанию.

типы данных из расширения postgis не поддерживаются

Для таблица где есть столбцы с типами данных из расширения возвращается ошибка
Multiple markers at this line

  • mismatched input 'NOT' expecting {INHERITS, PARTITION, TABLESPACE, WITHOUT, ON, WITH, ';'}
  • mismatched input '(' expecting {EXCLUDE, GENERATED, CHECK, COLLATE, CONSTRAINT, DEFAULT, FOREIGN, NOT, NULL, PRIMARY, REFERENCES, UNIQUE, ',', ')', '['}

пример:
my_point public.geography(Point,0) NOT NULL

Сборщик подчеркивает truncate как ошибочный

Коллеги,
создал обычный sql файл и вбил следующий код.
Сборщик пометил truncate как ошибочную команду...

create temporary table if not exists tmp
(
    source              character varying(50)   not null,
    bulk_schema         character varying(50)   not null,
    table_name          character varying(64)   not null,
    pkey                character varying(50)   not null,
    procedure           character varying(64)   not null,
    is_needupdate_allow boolean                 not null,
    job_number          smallint                not null,
    specialbatch        smallint                not null,
    list_columns_ins    character varying(2048) not null,
    list_columns_upd    character varying(2048) not null
);
--
truncate table tmp;
--

extraneous input 'truncate' expecting {, ALTER, COMMENT, COMMIT, DELETE, DROP, INSERT, NOTIFY, REVOKE, SET, START, UPDATE, VALUES, CREATE, GRANT, SELECT, TABLE, WITH, '('} dbo.checksync_tables.sql /fedresurs/Post-Deployment/LookupTables line 21 pgCodeKeeper SQL ошибка

default

ошибка в сборщике?

нарушен порядок выкладки объектов в деплойном скрипте

Сейчас выполняется провод кода функций до изменений в таблицах и вьюхах.
Проявляется проблема если включить проверку синтаксиса в функциях.
Конечно её можно выключить и проблема завуалируется... но считаю что всё же порядок в деплойном скрипте должен учитывать зависимости.

Обработка синонимов типов данных

В PostgreSQL очень много разных типов данных.
Многие из них означают одно и тоже :)
Например: varchar и character varying, integer и int4, bigint и int8....
Однако на данный момент компаратор видит это как разные типы данных.
Необходимо научить его всем возможным синонимам (ну или хотя бы начать этот процесс).

Компартор не видит зависимости между PK и FK (таблицы разные)

Исходная модель:

CREATE UNLOGGED TABLE dbo.union_person_temp (
    id_union_person_guid uuid DEFAULT public.uuid_generate_v1() NOT NULL,
    id_union_person integer NOT NULL,
    id_person integer,
    id_appraiser integer,
    id_arbitr_manager integer,
    id_person_trade_org integer,
    id_person_efrsb integer,
    id_region integer,
    inn character varying(12),
    fio character varying(305) NOT NULL
);

ALTER TABLE dbo.union_person_temp ALTER COLUMN id_union_person ADD GENERATED BY DEFAULT AS IDENTITY (
    SEQUENCE NAME union_person_temp_id_union_person_seq
    START WITH 1
    INCREMENT BY 1
    NO MAXVALUE
    NO MINVALUE
    CACHE 1
);

--------------------------------------------------------------------------------

ALTER TABLE dbo.union_person_temp
    ADD CONSTRAINT union_person_temp_pkey PRIMARY KEY (id_union_person);


CREATE UNLOGGED TABLE dbo.union_person_pb_temp (
	id_union_person_pb integer NOT NULL,
	id_union_person integer NOT NULL,
	id_person_bankrupt integer NOT NULL
);

ALTER TABLE dbo.union_person_pb_temp ALTER COLUMN id_union_person_pb ADD GENERATED BY DEFAULT AS IDENTITY (
	SEQUENCE NAME union_person_pb_temp_id_union_person_pb_seq
	START WITH 1
	INCREMENT BY 1
	NO MAXVALUE
	NO MINVALUE
	CACHE 1
);

--------------------------------------------------------------------------------

ALTER TABLE dbo.union_person_pb_temp
	ADD CONSTRAINT union_person_pb_temp_pkey PRIMARY KEY (id_union_person_pb);

--------------------------------------------------------------------------------

ALTER TABLE dbo.union_person_pb_temp
	ADD CONSTRAINT fk_union_person_pb_temp_union_person_temp FOREIGN KEY (id_union_person) REFERENCES dbo.union_person_temp(id_union_person) ON DELETE CASCADE;

удаляем PK на таблице dbo.union_person_temp т.е. в проекте стираем строки:

ALTER TABLE dbo.union_person_temp
    ADD CONSTRAINT union_person_temp_pkey PRIMARY KEY (id_union_person);

строим деплойный скрипт. компаратор создал скрипт:

ALTER TABLE dbo.union_person_temp
  DROP CONSTRAINT union_person_temp_pkey;

однако, при наличии FK это не пройдет

ERROR: cannot drop constraint union_person_temp_pkey on table dbo.union_person_temp because other objects depend on it
  Подробности: constraint fk_union_person_ie_temp_union_person_temp on table dbo.union_person_ie_temp depends on index dbo.union_person_temp_pkey
constraint fk_union_person_pb_temp_union_person_temp on table dbo.union_person_pb_temp depends on index dbo.union_person_temp_pkey
  Подсказка: Use DROP ... CASCADE to drop the dependent objects too.

Понимание default значений у описаний объектов

У многих описаний объектов в виде скрипта есть default части, которые можно опустить или указать.
Сейчас при попытке их указать в явном виде это воспринимается как различие кода.
Наример:
при описании функций - COST 100, ROWS 1000, VOLATILE ...
при написании индексов если не указана явно сортировка, то понимается как ASC
и т.д.

К примеру, мы захотим навести порядок и написать в индексе asc
CREATE INDEX newsbreak_source_id_web_block_id_idx ON newsbreak USING btree (source_id, web_block_id asc);
и получим после этого :
DROP INDEX newsbreak_source_id_web_block_id_idx;
CREATE INDEX newsbreak_source_id_web_block_id_idx ON newsbreak USING btree (source_id, web_block_id asc);

а ведь по сути ничего не изменилось!

CREATE AGGREGATE и CREATE OPERATOR

Уважаемые разработчики
прошу добавить поддержку операторов и агрегаций
CREATE/DROP/ALTER AGGREGATE
CREATE/DROP/ALTER OPERATOR

если создать CREATE OPERATOR то сейчас компаратор просто падает с сообщением:
Ошибка при сравнении БД
Ошибка при чтении схемы БД через JDBC, ошибка произошла при обработке jdbc:finalizing antlr
null

CREATE AGGREGATE к таким последствиям не приводит

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.