create unique index with function in hsqldb / liquibase - postgresql

Is there a way to use function index in hsqldb?
I tried those 4:
<column name="LOWER(name)"/>
<column name="LCASE(name)"/>
<column name="LOWER(name)" computed="true"/>
<column name="LCASE(name)" computed="true"/>
Inside my createIndex changeset:
<changeSet author="dgt" id="unique-postgres" dbms="hsqldb">
<createIndex indexName="lower_case_index" tableName="users" unique="true">
<column name="LOWER(name)" computed="true"/>
</createIndex>
In documentation I noticed that hsqldb got: LOWER and LCASE built in function, but any of those do not work for me.
Every single time I've got an error:
Reason: liquibase.exception.DatabaseException: unexpected token: (
required: ) [Failed SQL: CREATE UNIQUE INDEX PUBLIC.lower_case_index
ON PUBLIC.users(LOWER(name))]
I know about a solution that I can change column type from VARCHAR to VARCHAR_IGNORECASE, but it's not a case for me, because I need a solution to work on both db: hsqldb and postgres.
My ideal solution should look like this:
<changeSet author="dgt" id="users-unique-index-postgres" dbms="hsqldb">
<createIndex indexName="name_index" tableName="users" unique="true">
<column name="LOWER(name)" computed="true"/>
</createIndex>
</changeSet>
<changeSet author="dgt" id="users-unique-index-hsqldb" dbms="postgresql">
<createIndex indexName="name_index" tableName="users" unique="true">
<column name="lower(name)" computed="true"/>
</createIndex>
</changeSet>
But it doesn't work.

HSQLDB does not support function based indexes at all, so you need to find a different solution. You could e.g. define the column as varchar_ignorecase instead of varchar and then create a "normal" unique index on that column.
You can keep a single table definition by using properties.
That could look like this:
<changeSet author="dgt" id="create-users-table">
<property name="users_name_type" value="varchar" dbms="postgresql"/>
<property name="users_name_type" value="varchar_ignorecase" dbms="hsqldb"/>
<createTable tableName="users">
<column name="name" type="${users_name_type}">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
<changeSet author="dgt" id="users-unique-index-postgres" dbms="postgresql">
<createIndex indexName="name_index" tableName="users" unique="true">
<column name="lower(name)" computed="true"/>
</createIndex>
</changeSet>
<changeSet author="dgt" id="users-unique-index-hsqldb" dbms="hsqldb">
<createIndex indexName="name_index" tableName="users" unique="true">
<column name="name"/>
</createIndex>
</changeSet>

Related

Unstable data from XML mapping from a correct XML Dataset from Business central

Thanks in advance if you can help me with this behaviour!
(image links on the bottom of this question)
Included: images and the XML code to reproduce this issue. The Word-document you make it on your own, with the Development module - XML mapping pane.
From Business central support reponse: I made additional research and contact our production team for conformation. According to them XML Mapping is a Word feature which is outside of the control of BC.
If you run the word document with this data, the only the Item_Attr_Name appears; or only the Item_Attr_Value appears. Or you see nothing.
I tried already a lot of things.
-From time to time the data values Item_Attr_Value appears
-In other cases, from a similar dataset the values are disappeared.
![image 1]
-Maybe not relevant, if I remove the object in word, then also it's removed in XML mapping panel? See
image
-Made an RDL file with Report builder there's the data as in the dataset.
Hereunder a copy of the dataset from Business Central: when I run a RDL report from this data the data appears correctly.
<ReportDataSet name="1 Order Confirmation" id="51305">
<DataItems>
<DataItem name="Header">
<Columns>
<Column name="CompanyAddress1">ABC</Column>
<Column name="CompanyAddress2">No adress street</Column>
<Column name="CompanyAddress3">9999 </Column>
<Column name="CompanyAddress4">Belgique</Column>
<Column name="CompanyAddress5"></Column>
<Column name="CompanyAddress6"></Column>
<Column name="CompanyAddress7"></Column>
<Column name="CompanyAddress8"></Column>
<Column name="CompanyHomePage"></Column>
<Column name="CompanyEMail"></Column>
<Column name="CompanyPicture"></Column>
<Column name="CompanyPhoneNo"></Column>
<Column name="CompanyPhoneNo_Lbl">Tél.</Column>
<Column name="CompanyGiroNo"></Column>
<Column name="CompanyGiroNo_Lbl">Giro No.</Column>
<Column name="CompanyBankName"></Column>
<Column name="CompanyBankName_Lbl">Banque</Column>
<Column name="CompanyBankBranchNo">01</Column>
<Column name="CompanyBankBranchNo_Lbl">Code établissement</Column>
<Column name="CompanyBankAccountNo"></Column>
<Column name="CompanyBankAccountNo_Lbl">Account No.</Column>
<Column name="CompanyContactPerson_Lbl">Personne à contacter</Column>
<Column name="CompanyContactPerson">Mr. S</Column>
<Column name="Contact_Lbl">Des questions ?</Column>
<Column name="Sell_to_Email_Lbl">Sell to email</Column>
<Column name="Sell_to_E_Mail">notused#abc.be</Column>
<Column name="CompanyShipToAddress_Lbl">Notre adresse de livraison</Column>
<Column name="CompanyShipToAddress1">Entrepôt</Column>
<Column name="CompanyShipToAddress2">Rue de la livraison 123</Column>
<Column name="CompanyShipToAddress3">9999 </Column>
<Column name="CompanyShipToAddress4">Belgique</Column>
<Column name="CompanyShipToAddress5"></Column>
<Column name="CompanyShipToAddress6"></Column>
<Column name="CompanyShipToAddress7"></Column>
<Column name="CompanyShipToAddress8"></Column>
<Column name="CompanyIBAN_Lbl">IBAN</Column>
<Column name="CompanySWIFT_Lbl">Code SWIFT</Column>
<Column name="CompanyLogoPosition">0</Column>
<Column name="CompanyRegistrationNumber"></Column>
<Column name="CompanyRegistrationNumber_Lbl">N° de société</Column>
<Column name="CompanyVATRegNo"></Column>
<Column name="CompanyVATRegNo_Lbl">N° de société</Column>
<Column name="CompanyVATRegistrationNo"></Column>
<Column name="CompanyVATRegistrationNo_Lbl">N° de société</Column>
<Column name="CompanyLegalOffice"></Column>
<Column name="CompanyLegalOffice_Lbl"></Column>
<Column name="CompanyCustomGiro"></Column>
<Column name="CompanyCustomGiro_Lbl"></Column>
<Column name="CompanyLegalStatement"></Column>
<Column name="CustomerAddress1">ADM. </Column>
<Column name="CustomerAddress2">RUE DU CENTRE 1080</Column>
<Column name="CustomerAddress3">9990</Column>
<Column name="CustomerAddress4">Belgique</Column>
<Column name="CustomerAddress5"></Column>
<Column name="CustomerAddress6"></Column>
<Column name="CustomerAddress7"></Column>
<Column name="CustomerAddress8"></Column>
<Column name="CustomerPostalBarCode"></Column>
<Column name="YourReference"></Column>
<Column name="YourReference_Lbl">Votre référence</Column>
<Column name="ShipmentMethodDescription"></Column>
<Column name="ShipmentMethodDescription_Lbl">Mode d'envoi</Column>
<Column name="Shipment_Lbl">Note d'envoi</Column>
<Column name="ShipmentDate">22/02/21</Column>
<Column name="ShipmentDate_Lbl">Date de préparation</Column>
<Column name="ShowShippingAddress">True</Column>
<Column name="ShipToAddress1">ECOLE COMMUNALE PRIM.</Column>
<Column name="ShipToAddress2">MME BERNARDETTE</Column>
<Column name="ShipToAddress3">HEIRBAAN 15</Column>
<Column name="ShipToAddress4">9990</Column>
<Column name="ShipToAddress5">Belgique</Column>
<Column name="ShipToAddress6"></Column>
<Column name="ShipToAddress7"></Column>
<Column name="ShipToAddress8"></Column>
<Column name="PaymentTermsDescription">30 JOURS FIN DE MOIS</Column>
<Column name="PaymentTermsDescription_Lbl">Conditions de paiement</Column>
<Column name="PaymentMethodDescription"></Column>
<Column name="PaymentMethodDescription_Lbl">Payment Method</Column>
<Column name="DocumentCopyText">Confirmation vente</Column>
<Column name="BilltoCustumerNo">ABC.COMMUNALE.</Column>
<Column name="BilltoCustomerNo_Lbl">N° Client</Column>
<Column name="DocumentDate">22/02/21</Column>
<Column name="DocumentDate_Lbl">Date</Column>
<Column name="DueDate">31/03/21</Column>
<Column name="DueDate_Lbl">Date d'échéance</Column>
<Column name="DocumentNo">CC-21-00019</Column>
<Column name="DocumentNo_Lbl">N° document</Column>
<Column name="QuoteNo"></Column>
<Column name="QuoteNo_Lbl">N° devis</Column>
<Column name="PricesIncludingVAT">False</Column>
<Column name="PricesIncludingVAT_Lbl">Prix TTC</Column>
<Column name="PricesIncludingVATYesNo">Non</Column>
<Column name="SalesPerson_Lbl">Vendeur</Column>
<Column name="SalesPersonText_Lbl">Vendeur</Column>
<Column name="SelltoCustomerNo"></Column>
<Column name="SelltoCustomerNo_Lbl">N° donneur d'ordre</Column>
<Column name="VATRegistrationNo"></Column>
<Column name="VATRegistrationNo_Lbl">N° de société</Column>
<Column name="GlobalLocationNumber"></Column>
<Column name="GlobalLocationNumber_Lbl"></Column>
<Column name="SellToPhoneNo"></Column>
<Column name="LegalEntityType"> </Column>
<Column name="LegalEntityType_Lbl">Type partenaire</Column>
<Column name="Copy_Lbl">Copy</Column>
<Column name="EMail_Lbl">Email</Column>
<Column name="HomePage_Lbl">Website</Column>
<Column name="InvoiceDiscountBaseAmount_Lbl">Invoice Discount Base Amount</Column>
<Column name="InvoiceDiscountAmount_Lbl">Invoice Discount</Column>
<Column name="LineAmountAfterInvoiceDiscount_Lbl">Payment Discount on VAT</Column>
<Column name="LocalCurrency_Lbl">Local Currency</Column>
<Column name="ExchangeRateAsText"></Column>
<Column name="Page_Lbl">Page</Column>
<Column name="SalesInvoiceLineDiscount_Lbl">Ristourne %</Column>
<Column name="Invoice_Lbl">Confirmation vente</Column>
<Column name="Subtotal_Lbl">Sous-total</Column>
<Column name="Total_Lbl">Total</Column>
<Column name="VATAmount_Lbl">Montant TVA</Column>
<Column name="VATBase_Lbl">VAT Base</Column>
<Column name="VATAmountSpecification_Lbl">Montant TVA Specifié</Column>
<Column name="VATClauses_Lbl">VAT Clause</Column>
<Column name="VATIdentifier_Lbl">VAT Identifier</Column>
<Column name="VATPercentage_Lbl">VAT %</Column>
<Column name="VATClause_Lbl">Clause TVA</Column>
<Column name="ShowWorkDescription">False</Column>
<Column name="ShipToAddress_Lbl">Adresse de livraison</Column>
<Column name="ClientNumber">1000</Column>
<Column name="SalesPersonBlank_Lbl">Vendeur</Column>
<Column name="SaleAgentName">LMF</Column>
<Column name="SaleAgentEMail"></Column>
<Column name="SaleAgentPhone">0</Column>
<Column name="ExternalDocumentNoCaption">N° doc. externe</Column>
<Column name="CustomerNoCaption">N° donneur d'ordre</Column>
<Column name="ResponsibleCaption">Code vendeur</Column>
<Column name="ReferenceCaption">Votre référence</Column>
<Column name="Reference"></Column>
<Column name="SalesHeaderDocumentNo">CC-21-00019</Column>
<Column name="ExternalDocumentNo">BC:22 ARTICLE: 12322/25-02</Column>
<Column name="SalesHeaderSellToCustomerNo">ABC</Column>
<Column name="SalesHeaderSalesPersonCode">FLE</Column>
<Column name="CustomerContactCaption">Contact donneur d'ordre</Column>
<Column name="CustomerContactName">ABC FLE</Column>
<Column name="CustomerContactFirstName"></Column>
<Column name="CustomerContactMiddleName"></Column>
<Column name="CustomerGSMNoCaption">N° téléphone donneur d'ordre</Column>
<Column name="CustomerGSMNo"></Column>
<Column name="CustomerPhone"></Column>
<Column name="CustomerEMailCaption">E-mail</Column>
<Column name="CustomerEMail"></Column>
<Column name="CompanyIBAN"></Column>
<Column name="CompanySwift"></Column>
<Column name="DocumentTitle_Lbl">Confirmation vente</Column>
<Column name="Bank_Lbl">Compte bancaire</Column>
<Column name="IBAN_Lbl">N° compte international (IBAN)</Column>
<Column name="BICCode_Lbl">BIC</Column>
<Column name="Bank0">CPH</Column>
<Column name="IBAN0">BE92xxxxxxxxxx</Column>
<Column name="BIC0"></Column>
<Column name="Bank1"></Column>
<Column name="IBAN1"></Column>
<Column name="BIC1"></Column>
<Column name="Bank2"></Column>
<Column name="IBAN2"></Column>
<Column name="BIC2"></Column>
<Column name="Bank3"></Column>
<Column name="IBAN3"></Column>
<Column name="BIC3"></Column>
<Column name="ConditionsText"></Column>
<Column name="QuoteBeginLine"></Column>
<Column name="QuoteEndLine"></Column>
<Column name="HeadQuarterLbl">Siège social</Column>
<Column name="BilltoCustumerName">ABC9999 </Column>
<Column name="BilltoCustomerName_Lbl">Nom</Column>
<Column name="ContactLbl">Contact</Column>
<Column name="BillToName_Lbl">Adresse de facturation</Column>
<Column name="CustomerPicture"></Column>
</Columns>
<DataItems>
<DataItem name="Line">
<Columns>
<Column name="LineNo_Line">10000</Column>
<Column name="Description_Line">ARMOIRE AXEDIS -1970-1200-0420</Column>
<Column name="Description_Line_Lbl">Désignation</Column>
<Column name="ItemNo_Lbl">N° article</Column>
<Column name="VREF_Lbl">Votre n° article</Column>
<Column name="Qty_Lbl">Qté</Column>
<Column name="Price_Lbl">Price</Column>
<Column name="ItemPicture"></Column>
</Columns>
<DataItems>
<DataItem name="Item_Attribute_Values">
<Columns>
<Column name="Item_Attr_Name">Hauteur Produit</Column>
<Column name="Item_Attr_Name_CurrLang">Hauteur Produit</Column>
<Column name="Item_Attr_Value">1970</Column>
<Column name="Item_Attr_Value_CurrLang">1970</Column>
</Columns>
</DataItem>
<DataItem name="Item_Attribute_Values">
<Columns>
<Column name="Item_Attr_Name">Longueur Produit</Column>
<Column name="Item_Attr_Name_CurrLang">Longueur Produit</Column>
<Column name="Item_Attr_Value">1200</Column>
<Column name="Item_Attr_Value_CurrLang">1200</Column>
</Columns>
</DataItem>
<DataItem name="Item_Attribute_Values">
<Columns>
<Column name="Item_Attr_Name">Profondeur produit</Column>
<Column name="Item_Attr_Name_CurrLang">Profondeur produit</Column>
<Column name="Item_Attr_Value">420</Column>
<Column name="Item_Attr_Value_CurrLang">420</Column>
</Columns>
</DataItem>
</DataItems>
<DataItem name="VATAmountLine">
<Columns>
<Column name="InvoiceDiscountAmount_VATAmountLine" decimalformatter="#,##0.00">0</Column>
<Column name="InvoiceDiscountAmount_VATAmountLine_Lbl">Montant remise facture</Column>
<Column name="InvoiceDiscountBaseAmount_VATAmountLine" decimalformatter="#,##0.00">123,00</Column>
<Column name="InvoiceDiscountBaseAmount_VATAmountLine_Lbl">Montant base remise facture</Column>
<Column name="LineAmount_VatAmountLine" decimalformatter="#,##0.00">234,00</Column>
<Column name="LineAmount_VatAmountLine_Lbl">Montant ligne</Column>
<Column name="VATAmount_VatAmountLine" decimalformatter="#,##0.00">49,14</Column>
<Column name="VATAmount_VatAmountLine_Lbl">Montant TVA</Column>
<Column name="VATAmountLCY_VATAmountLine" decimalformatter="#,##0.00">49,14</Column>
<Column name="VATBase_VatAmountLine" decimalformatter="#,##0.00">234,00</Column>
<Column name="VATBase_VatAmountLine_Lbl">Base TVA</Column>
<Column name="VATBaseLCY_VATAmountLine" decimalformatter="#,##0.00">234,00</Column>
<Column name="VATBaseLCY_VATAmountLine_Lbl">VAT Base (LCY)</Column>
<Column name="VATIdentifier_VatAmountLine">M3</Column>
<Column name="VATIdentifier_VatAmountLine_Lbl">Identifiant TVA</Column>
<Column name="VATPct_VatAmountLine" decimalformatter="#,##0.#####">21</Column>
<Column name="VATPct_VatAmountLine_Lbl">% TVA</Column>
<Column name="NoOfVATIdentifiers">1</Column>
</Columns>
</DataItem>
<DataItem name="ReportTotalsLine">
<Columns>
<Column name="Description_ReportTotalsLine">Sous-total</Column>
<Column name="Amount_ReportTotalsLine" decimalformatter="#,##0.00">234,00</Column>
<Column name="AmountFormatted_ReportTotalsLine">234,00</Column>
<Column name="FontBold_ReportTotalsLine">True</Column>
<Column name="FontUnderline_ReportTotalsLine">False</Column>
</Columns>
</DataItem>
<DataItem name="ReportTotalsLine">
<Columns>
<Column name="Description_ReportTotalsLine">TVA 21%</Column>
<Column name="Amount_ReportTotalsLine" decimalformatter="#,##0.00">49,14</Column>
<Column name="AmountFormatted_ReportTotalsLine">49,14</Column>
<Column name="FontBold_ReportTotalsLine">False</Column>
<Column name="FontUnderline_ReportTotalsLine">True</Column>
</Columns>
</DataItem>
<DataItem name="LetterText">
<Columns>
<Column name="GreetingText">Hello</Column>
<Column name="BodyText">Thank you for your business. Your order confirmation is attached to this message.</Column>
<Column name="ClosingText">Sincerely</Column>
<Column name="PmtDiscText"></Column>
</Columns>
</DataItem>
<DataItem name="Totals">
<Columns>
<Column name="TotalNetAmount" decimalformatter="#,##0.00">234,00</Column>
<Column name="TotalVATBaseLCY" decimalformatter="#,##0.00">234,00</Column>
<Column name="TotalAmountIncludingVAT" decimalformatter="#,##0.00">283,14</Column>
<Column name="TotalVATAmount" decimalformatter="#,##0.00">49,14</Column>
<Column name="TotalVATAmountLCY" decimalformatter="#,##0.00">49,14</Column>
<Column name="TotalInvoiceDiscountAmount" decimalformatter="#,##0.00">0</Column>
<Column name="TotalPaymentDiscountOnVAT" decimalformatter="#,##0.00">49,14</Column>
<Column name="TotalVATAmountText">TVA 21%</Column>
<Column name="TotalExcludingVATText">Total EUR HT</Column>
<Column name="TotalIncludingVATText">Total EUR TTC</Column>
<Column name="TotalSubTotal" decimalformatter="#,##0.00">234,00</Column>
<Column name="TotalSubTotalMinusInvoiceDiscount" decimalformatter="#,##0.00">234,00</Column>
<Column name="TotalText">Total EUR</Column>
</Columns>
</DataItem>
</DataItems>
</DataItem>
</DataItems>
</ReportDataSet>

Liquibase: how to load data with CURRENT_TIMESTAMP?

I am trying to update my project, going from
<liquibase.version>3.5.5</liquibase.version>
<liquibase-hibernate5.version>3.6</liquibase-hibernate5.version>
to
<liquibase.version>3.9.0</liquibase.version>
<liquibase-hibernate5.version>3.8</liquibase-hibernate5.version>
and I'm having some troubles while loading data from CSV files, which contain some columns having the current timestamp as value.
E.g my CSV file:
id;name;created;modified
1;Book A;now();now()
2;Book B;now();now()
The Book table is created with:
<createTable tableName="book">
<column name="id" type="bigint" autoIncrement="${autoIncrement}">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(255)">
<constraints nullable="false"/>
</column>
<column name="created" type="timestamp">
<constraints nullable="false"/>
</column>
<column name="modified" type="timestamp">
<constraints nullable="false"/>
</column>
</createTable>
And the data is loaded with:
<property name="now" value="current_timestamp" dbms="postgresql"/>
<changeSet id="20180508144233-1" author="developer">
<loadData catalogName="public"
encoding="UTF-8"
file="config/liquibase/books.csv"
schemaName="public"
separator=";"
quotchar="'"
tableName="book">
</loadData>
</changeSet>
With the previous version of Liquibase it was working fine, however after the update I am getting the following error:
2020-06-26 16:49:57 [project-Executor-1] [ERROR] liquibase.changelog.ChangeSet - Change Set config/liquibase/changelog/20180508144233_added_books_data.xml::20180508144233-1::developer failed. Error: liquibase.exception.DateParseException: Improper value in 'NOW' value: now(). 'NOW' must be followed by + or -, then numeric offset, then units (h{our{s}}, m{inute{s}}, d{ay{s}}, or y{ears}
Hibernate: select answerweig0_.id as id1_1_, answerweig0_.likelihood as likeliho2_1_, answerweig0_.question_type as question3_1_, answerweig0_.weight as weight4_1_ from answer_weight answerweig0_
2020-06-26 16:49:57 [project-Executor-1] [ERROR] i.g.j.c.l.AsyncSpringLiquibase - Liquibase could not start correctly, your database is NOT ready: Migration failed for change set config/liquibase/changelog/20180508144233_added_books_data.xml::20180508144233-1::developer:
Reason: liquibase.exception.UnexpectedLiquibaseException: liquibase.exception.DateParseException: Improper value in 'NOW' value: now(). 'NOW' must be followed by + or -, then numeric offset, then units (h{our{s}}, m{inute{s}}, d{ay{s}}, or y{ears}
liquibase.exception.MigrationFailedException: Migration failed for change set config/liquibase/changelog/20180508144233_added_books_data.xml::20180508144233-1::developer:
Reason: liquibase.exception.UnexpectedLiquibaseException: liquibase.exception.DateParseException: Improper value in 'NOW' value: now(). 'NOW' must be followed by + or -, then numeric offset, then units (h{our{s}}, m{inute{s}}, d{ay{s}}, or y{ears}
at liquibase.changelog.ChangeSet.execute(ChangeSet.java:646)
at liquibase.changelog.visitor.UpdateVisitor.visit(UpdateVisitor.java:53)
at liquibase.changelog.ChangeLogIterator.run(ChangeLogIterator.java:83)
at liquibase.Liquibase.update(Liquibase.java:202)
at liquibase.Liquibase.update(Liquibase.java:179)
at liquibase.integration.spring.SpringLiquibase.performUpdate(SpringLiquibase.java:366)
at liquibase.integration.spring.SpringLiquibase.afterPropertiesSet(SpringLiquibase.java:314)
at org.springframework.boot.autoconfigure.liquibase.DataSourceClosingSpringLiquibase.afterPropertiesSet(DataSourceClosingSpringLiquibase.java:46)
at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.initDb(AsyncSpringLiquibase.java:118)
at io.github.jhipster.config.liquibase.AsyncSpringLiquibase.lambda$afterPropertiesSet$0(AsyncSpringLiquibase.java:93)
at io.github.jhipster.async.ExceptionHandlingAsyncTaskExecutor.lambda$createWrappedRunnable$1(ExceptionHandlingAsyncTaskExecutor.java:78)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
As a workaround, I was able to set the values for such columns by using a default value in the table creation changelog:
<createTable tableName="book">
<column name="id" type="bigint" autoIncrement="${autoIncrement}">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(255)">
<constraints nullable="false"/>
</column>
<column name="created" type="timestamp" defaultValueComputed="CURRENT_TIMESTAMP">
<constraints nullable="false"/>
</column>
<column name="modified" type="timestamp" defaultValueComputed="CURRENT_TIMESTAMP">
<constraints nullable="false"/>
</column>
</createTable>
and removing the corresponding columns from the CSV file:
id;name
1;Book A
2;Book B
However, I'm still looking for a way to keep the CURRENT_TIMESTAMP value in the CSV file.
Your workaround is pretty much correct. But depending on database you will have to add a way that your update_timestamp or modified timestamp will change based on every addition, subtraction or edit you have in this database row. Here is how it can be setup in PostgresSQL for example.
<changeSet id="{UNIQUE_ID}" author="{YOUR_NAME}">
<preConditions onFail="MARK_RAN">
<dbms type="postgresql"/>
</preConditions>
<createProcedure>
CREATE OR REPLACE FUNCTION refresh_updated_date_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_date = now();
RETURN NEW;
END;
$$ language 'plpgsql';
</createProcedure>
<rollback>
DROP FUNCTION IF EXISTS refresh_updated_date_column;
</rollback>
</changeSet>`
This will be an additional changeset that you will add after your original changeset of creating the table and adding the required columns.
You need to add CURRENT_TIMESTAMP in your csv file like:
"id","date_created"
"11236,CURRENT_TIMESTAMP
And your changeset like:
<column header="date_modified"
name="date_modified"
type="DATE"/>
Note: Im using liquibase version 4.2.0+

TSQL Parse XML with namespace

I'm trying to parse some xml that's stored in the database inside of stored procedure. The procedure should return 2 columns, id and value. I'm only part of the way through this, I'm stuck on the fact that I can't list even list the "Setting" nodes.
declare #PolicySettingsXml xml
set #PolicySettingsXml = '<?xml version="1.0" encoding="utf-8"?>
<Policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.myurl.com/app/Policies">
<Setting id="VendorInfo0">
<string>fsdfdsfds</string>
</Setting>
<Setting id="VendorInfo1">
<string />
</Setting>
<Setting id="VendorInfo2">
<string />
</Setting>
<Setting id="SendSurchargeAsSeparateTransaction">
<boolean>false</boolean>
</Setting>
<Setting id="VendorSurchargeInfo0">
<string />
</Setting>
<Setting id="VendorSurchargeInfo1">
<string />
</Setting>
<Setting id="VendorSurchargeInfo2">
<string />
</Setting>
</Policy>'
select T.c.query('string') as value, T.c.query('#id') as id from #PolicySettingsXml.nodes('/Policy/Setting') T(c)
I'm getting an error, "XQuery [query()]: Attribute may not appear outside of an element," I'd expect to see:
id | value
VendorInfo0 | fsdfdsfds
VendorInfo1 | <null>
VendorInfo2 | <null>
SendSurchargeAsSeparateTransaction | <null>
VendorSurchargeInfo1 | <null>
VendorSurchargeInfo2 | <null>
The first issue is related to syntax.
This:
from PSXML.x.nodes('/*:Policy/*:Setting') T(c);
should be:
from (VALUES(#PolicySettingsXml)) AS PSXML(x)
CROSS APPLY PSXML.x.nodes('/*:Policy/*:Setting') T(c);
For what you are doing you can use the value method for the id column.
select
id = T.c.value('(#id)[1]', 'varchar(100)'),
[value] = T.c.query('(*:string/text())[1]')
from (VALUES(#PolicySettingsXml)) AS PSXML(x)
CROSS APPLY PSXML.x.nodes('/*:Policy/*:Setting') T(c);
Note that I am cheating on the namespaces using the "all namespaces" syntax: * :Object. A google search for "sql server t-sql xml namespaces" will show you the way you're supposed to do it. I cheated due to time constraints.

Insert new data using Liquibase, postgreSQL and sequence

How do I make an insert for PostgreSQL using Liquibase if my ids are sequential. I try with the following:
<changeSet author="rparente" id="service-1.1-2019-01-09-01">
<insert tableName="tenant">
<column name="id"defaultValueSequenceNext="hibernate_sequence"/>
<column name="description" value="Prueba"/>
<column name="name" value="antel"/>
<column name="service_id" value="antel"/>
</insert>
</changeSet>
and I try with
<changeSet author="rparente" id="service-1.1-2019-01-09-01">
<insert tableName="tenant">
<column name="id" value="nextval('hibernate_sequence')"/>
<column name="description" value="Prueba"/>
<column name="name" value="antel"/>
<column name="service_id" value="antel"/>
</insert>
</changeSet>
The error is:
ERROR: null value in column "id" violates not-null constraint
I found the solution to insert data in Postgres with sequence (no default) ids
<changeSet author="author_name" id="service-1.1-2019-01-09-01">
<insert tableName="tenant">
<column name="id" valueSequenceNext="name_sequence"/>
<column name="description" value="TEST"/>
<column name="name" value="test"/>
<column name="service_id" value="testl"/>
<column name="status" value="ACTIVE"/>
</insert>
</changeSet>
Check out the ColumnConfig doc. You should be able to set a valueComputed property and in it call the Postgres function:
<column name="id" valueComputed="nextval('hibernate_sequence')"/>
As for me, I have to create a sequence first and then use it.
<changeSet>
<createSequence sequenceName="runtime_name_seq" dataType="bigint" incrementBy="1" maxValue="10000" minValue="1" startValue="1"/>
</changeSet>
<changeSet>
<createTable tableName="runtime_name">
<column name="id" type="INTEGER" defaultValueComputed="nextval('runtime_name_seq')">
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_runtime_name"/>
</column>
</createTable>
</changeSet>
This will create a SQL by Liquibase (v3.8.1 I am using)
CREATE TABLE public.runtime_name
(
index INTEGER DEFAULT nextval('runtime_name_seq') NOT NULL
)

OLAP/MDX - define calculated member, sum all time to date data

I would like to define "all time to date" calculated member in OLAP cube. I'm able to calculate YTD by using the following:
SUM(YTD([Time].[Month].CurrentMember), [Measures].[Suits])
How can I include all dates since the beginning of my data? My time dimension looks like:
<Dimension type="TimeDimension" visible="true" foreignKey="granularity" highCardinality="false" name="Time">
<Hierarchy name="Time" visible="true" hasAll="true" primaryKey="eom_date">
<Table name="v_months" schema="bizdata">
</Table>
<Level name="Year" visible="true" column="year_number" type="String" uniqueMembers="false" levelType="TimeYears" hideMemberIf="Never">
</Level>
<Level name="Quarter" visible="true" column="quarter_number" type="String" uniqueMembers="false" levelType="TimeQuarters" hideMemberIf="Never">
</Level>
<Level name="Month" visible="true" column="month_number" type="String" uniqueMembers="false" levelType="TimeMonths" hideMemberIf="Never">
</Level>
</Hierarchy>
</Dimension>
Not sure if relevant: I'm using mondrian olap server (running on tomcat), Saiku as frontend, postgres as database
I've tried a lot of combinations, but I can't figure it out.
Update: I've tried to use syntax suggested by Gonsalu:
<CalculatedMember name="YTD Suits" formatString="" formula="SUM(YTD([Time].[Month].CurrentMember), [Measures].[Suits])" dimension="Measures" visible="true">
</CalculatedMember>
<CalculatedMember name="PTD Suits" formatString="" formula="Sum({NULL:[Time].[Month].CurrentMember },[Measures].[Suits])" dimension="Measures" visible="true">
</CalculatedMember>
Using this I get the following error message when starting mondrian (note that YTD function works well without the second calculated member):
Caused by: mondrian.olap.MondrianException: Mondrian Error:Failed to parse query
'WITH
MEMBER [Measures].[Measures].[YTD Suits]
AS 'SUM(YTD([Time].[Month].CurrentMember), [Measures].[Suits])',
[$member_scope] = 'CUBE',
MEMBER_ORDINAL = 6
MEMBER [Measures].[Measures].[PTD Suits]
AS 'Sum({NULL:[Time].[Month].CurrentMember },[Measures].[Suits])',
[$member_scope] = 'CUBE',
MEMBER_ORDINAL = 7
SELECT FROM [Project Performance]'
Thank you for any ideas.
I haven't used Mondrian, but in SQL Server Analysis Services (SSAS), using the NULL member causes the range to go from one end of the level to the specified member.
In your case, the calculated member you're looking for might be something like this:
Sum( { NULL : [Time].[Month].CurrentMember }
, [Measures].[Suits]
)
You could also do a to the end of times calculated member using the NULL member on the other end, like so:
{ [Time].[Month].CurrentMember : NULL }
You can use PeriodsToDate function along with the allMember.
In your case it would be:
PeriodsToDate([Time.Time].[all_Time_member_name],[Time.Time].CurrentMember)