From bfeceed722306f95665f4424093da3e765a2395f Mon Sep 17 00:00:00 2001 From: elliVM <47@teragrep.com> Date: Thu, 14 Nov 2024 12:41:16 +0200 Subject: [PATCH 1/7] decrease earliest epoch value by 3 hours query XML --- .../pth10/ast/commands/logicalstatement/TimeStatement.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java index f143ced..11f5b20 100644 --- a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java +++ b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java @@ -194,7 +194,8 @@ private ElementNode timeQualifierEmitXml(DPLParser.TimeQualifierContext ctx) { startTime = tq.epoch(); } else if (tq.isEndTime()) { - endTime = tq.epoch(); + // TODO: this is a hack to remove 3 hours from earliest value for archive + endTime = tq.epoch() - (3 * 60 * 60 * 1000); } else { throw new UnsupportedOperationException("Unexpected token: " + node.getSymbol().getText()); From d4990011f96779b0bb2b22563bc109496768a4eb Mon Sep 17 00:00:00 2001 From: elliVM <47@teragrep.com> Date: Fri, 15 Nov 2024 11:41:31 +0200 Subject: [PATCH 2/7] fix: remove 3 hours from earliest and not latest --- .../pth10/ast/commands/logicalstatement/TimeStatement.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java index 11f5b20..80c5bf9 100644 --- a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java +++ b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java @@ -191,11 +191,10 @@ private ElementNode timeQualifierEmitXml(DPLParser.TimeQualifierContext ctx) { TimeQualifier tq = new TimeQualifier(value, catCtx.getTimeFormatString(), node.getSymbol().getType(), doc); if (tq.isStartTime()) { - startTime = tq.epoch(); + startTime = tq.epoch() - (3 * 60 * 60 * 1000); } else if (tq.isEndTime()) { - // TODO: this is a hack to remove 3 hours from earliest value for archive - endTime = tq.epoch() - (3 * 60 * 60 * 1000); + endTime = tq.epoch(); } else { throw new UnsupportedOperationException("Unexpected token: " + node.getSymbol().getText()); From 096b981b254d5b09f7c7124dfa95201a43ca11d8 Mon Sep 17 00:00:00 2001 From: elliVM <47@teragrep.com> Date: Fri, 15 Nov 2024 11:42:38 +0200 Subject: [PATCH 3/7] add TODO comment about hack --- .../pth10/ast/commands/logicalstatement/TimeStatement.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java index 80c5bf9..a32d205 100644 --- a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java +++ b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java @@ -191,6 +191,7 @@ private ElementNode timeQualifierEmitXml(DPLParser.TimeQualifierContext ctx) { TimeQualifier tq = new TimeQualifier(value, catCtx.getTimeFormatString(), node.getSymbol().getType(), doc); if (tq.isStartTime()) { + // TODO: this is a hack to decrease 3 horus from query start time to work with database timezone startTime = tq.epoch() - (3 * 60 * 60 * 1000); } else if (tq.isEndTime()) { From bc815f2170a56fd91106d4019498a0ad440ee0ee Mon Sep 17 00:00:00 2001 From: elliVM <47@teragrep.com> Date: Fri, 15 Nov 2024 12:53:03 +0200 Subject: [PATCH 4/7] use decorator to assign decreased epoch value --- .../logicalstatement/TimeStatement.java | 25 ++++-- .../pth10/ast/time/DecreasedEpochValue.java | 83 +++++++++++++++++++ .../pth10/ast/time/TimeQualifier.java | 2 +- .../ast/time/TimeQualifierInterface.java | 59 +++++++++++++ .../com/teragrep/pth10/TimeQualifierTest.java | 20 +++++ 5 files changed, 180 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java create mode 100644 src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java diff --git a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java index a32d205..e41d008 100644 --- a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java +++ b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java @@ -49,6 +49,8 @@ import com.teragrep.pth10.ast.bo.*; import com.teragrep.pth10.ast.bo.Token.Type; import com.teragrep.pth10.ast.commands.EmitMode; +import com.teragrep.pth10.ast.time.DecreasedEpochValue; +import com.teragrep.pth10.ast.time.TimeQualifierInterface; import com.teragrep.pth10.ast.time.TimeQualifier; import com.teragrep.pth_03.antlr.DPLParser; import com.teragrep.pth_03.antlr.DPLParserBaseVisitor; @@ -188,20 +190,27 @@ private ElementNode timeQualifierEmitXml(DPLParser.TimeQualifierContext ctx) { TerminalNode node = (TerminalNode) ctx.getChild(0); String value = ctx.getChild(1).getText(); - TimeQualifier tq = new TimeQualifier(value, catCtx.getTimeFormatString(), node.getSymbol().getType(), doc); - - if (tq.isStartTime()) { - // TODO: this is a hack to decrease 3 horus from query start time to work with database timezone - startTime = tq.epoch() - (3 * 60 * 60 * 1000); + final TimeQualifierInterface timeQualifierInterface = new TimeQualifier( + value, + catCtx.getTimeFormatString(), + node.getSymbol().getType(), + doc + ); + final ElementNode returnValue; + if (timeQualifierInterface.isStartTime()) { + long decreaseValue = 3 * 60 * 60 * 1000; + startTime = timeQualifierInterface.epoch() - decreaseValue; + returnValue = new ElementNode(new DecreasedEpochValue(timeQualifierInterface, decreaseValue).xmlElement()); } - else if (tq.isEndTime()) { - endTime = tq.epoch(); + else if (timeQualifierInterface.isEndTime()) { + endTime = timeQualifierInterface.epoch(); + returnValue = new ElementNode(timeQualifierInterface.xmlElement()); } else { throw new UnsupportedOperationException("Unexpected token: " + node.getSymbol().getText()); } - return new ElementNode(tq.xmlElement()); + return returnValue; } /** diff --git a/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java new file mode 100644 index 0000000..ccf50aa --- /dev/null +++ b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java @@ -0,0 +1,83 @@ +/* + * Teragrep Data Processing Language (DPL) translator for Apache Spark (pth_10) + * Copyright (C) 2019-2024 Suomen Kanuuna Oy + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * + * Additional permission under GNU Affero General Public License version 3 + * section 7 + * + * If you modify this Program, or any covered work, by linking or combining it + * with other code, such other code is not for that reason alone subject to any + * of the requirements of the GNU Affero GPL version 3 as long as this Program + * is the same Program as licensed from Suomen Kanuuna Oy without any additional + * modifications. + * + * Supplemented terms under GNU Affero General Public License version 3 + * section 7 + * + * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified + * versions must be marked as "Modified version of" The Program. + * + * Names of the licensors and authors may not be used for publicity purposes. + * + * No rights are granted for use of trade names, trademarks, or service marks + * which are in The Program if any. + * + * Licensee must indemnify licensors and authors for any liability that these + * contractual assumptions impose on licensors and authors. + * + * To the extent this program is licensed as part of the Commercial versions of + * Teragrep, the applicable Commercial License may apply to this file if you as + * a licensee so wish it. + */ +package com.teragrep.pth10.ast.time; + +import org.w3c.dom.Element; + +/** Decreases the amount from qualifier epoch value */ +public class DecreasedEpochValue implements TimeQualifierInterface { + + TimeQualifierInterface origin; + long decreaseEpochValue; + + public DecreasedEpochValue(TimeQualifierInterface origin, long decreaseEpochValue) { + this.origin = origin; + this.decreaseEpochValue = decreaseEpochValue; + } + + @Override + public Element xmlElement() { + final Element el = origin.xmlElement(); + final long newValue = Long.parseLong(el.getAttribute("value")) - decreaseEpochValue; + el.setAttribute("value", Long.toString(newValue)); + return el; + } + + @Override + public boolean isStartTime() { + return origin.isStartTime(); + } + + @Override + public boolean isEndTime() { + return origin.isEndTime(); + } + + @Override + public long epoch() { + return origin.epoch() - decreaseEpochValue; + } +} diff --git a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java index d16d71c..e0d2b3c 100644 --- a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java +++ b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java @@ -53,7 +53,7 @@ import java.util.Objects; -public final class TimeQualifier { +public final class TimeQualifier implements TimeQualifierInterface { private final int token; private final String value; diff --git a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java new file mode 100644 index 0000000..9389125 --- /dev/null +++ b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java @@ -0,0 +1,59 @@ +/* + * Teragrep Data Processing Language (DPL) translator for Apache Spark (pth_10) + * Copyright (C) 2019-2024 Suomen Kanuuna Oy + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * + * Additional permission under GNU Affero General Public License version 3 + * section 7 + * + * If you modify this Program, or any covered work, by linking or combining it + * with other code, such other code is not for that reason alone subject to any + * of the requirements of the GNU Affero GPL version 3 as long as this Program + * is the same Program as licensed from Suomen Kanuuna Oy without any additional + * modifications. + * + * Supplemented terms under GNU Affero General Public License version 3 + * section 7 + * + * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified + * versions must be marked as "Modified version of" The Program. + * + * Names of the licensors and authors may not be used for publicity purposes. + * + * No rights are granted for use of trade names, trademarks, or service marks + * which are in The Program if any. + * + * Licensee must indemnify licensors and authors for any liability that these + * contractual assumptions impose on licensors and authors. + * + * To the extent this program is licensed as part of the Commercial versions of + * Teragrep, the applicable Commercial License may apply to this file if you as + * a licensee so wish it. + */ +package com.teragrep.pth10.ast.time; + +import org.w3c.dom.Element; + +public interface TimeQualifierInterface { + + Element xmlElement(); + + boolean isStartTime(); + + boolean isEndTime(); + + long epoch(); +} diff --git a/src/test/java/com/teragrep/pth10/TimeQualifierTest.java b/src/test/java/com/teragrep/pth10/TimeQualifierTest.java index 82772d7..ab04272 100644 --- a/src/test/java/com/teragrep/pth10/TimeQualifierTest.java +++ b/src/test/java/com/teragrep/pth10/TimeQualifierTest.java @@ -45,7 +45,9 @@ */ package com.teragrep.pth10; +import com.teragrep.pth10.ast.time.DecreasedEpochValue; import com.teragrep.pth10.ast.time.TimeQualifier; +import com.teragrep.pth10.ast.time.TimeQualifierInterface; import com.teragrep.pth_03.antlr.DPLLexer; import org.apache.spark.sql.Column; import org.apache.spark.sql.functions; @@ -160,6 +162,24 @@ public void testEndtimeU() { Assertions.assertEquals(el.toString(), tq.xmlElement().toString()); } + @Test + public void testDecreaseDecorator() { + long decreaseAmount = 1000L; + final String value = "2024-31-10"; + final String timeformat = "%Y-%d-%m"; + final int earliestType = DPLLexer.EARLIEST; + final Document doc = Assertions + .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); + TimeQualifierInterface tq = new DecreasedEpochValue( + new TimeQualifier(value, timeformat, earliestType, doc), + decreaseAmount + ); + Element el = doc.createElement("earliest"); + el.setAttribute("operation", "GE"); + el.setAttribute("value", Long.toString(1730325600L - decreaseAmount)); + Assertions.assertEquals(el.toString(), tq.xmlElement().toString()); + } + @Test public void testInvalidToken() { final String value = "024-10-31:00:00:00"; From ad625525f2ead1efb13926852556be30313bdd6f Mon Sep 17 00:00:00 2001 From: elliVM <47@teragrep.com> Date: Mon, 18 Nov 2024 10:02:42 +0200 Subject: [PATCH 5/7] refactoring and update interface --- .../logicalstatement/TimeStatement.java | 26 +-- .../pth10/ast/time/DecreasedEpochValue.java | 59 ++++-- .../pth10/ast/time/TimeQualifier.java | 118 +----------- .../pth10/ast/time/TimeQualifierImpl.java | 168 ++++++++++++++++++ .../ast/time/TimeQualifierInterface.java | 59 ------ .../pth10/DecreasedEpochValueTest.java | 149 ++++++++++++++++ ...erTest.java => TimeQualifierImplTest.java} | 44 ++--- 7 files changed, 401 insertions(+), 222 deletions(-) create mode 100644 src/main/java/com/teragrep/pth10/ast/time/TimeQualifierImpl.java delete mode 100644 src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java create mode 100644 src/test/java/com/teragrep/pth10/DecreasedEpochValueTest.java rename src/test/java/com/teragrep/pth10/{TimeQualifierTest.java => TimeQualifierImplTest.java} (81%) diff --git a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java index e41d008..c088005 100644 --- a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java +++ b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java @@ -50,8 +50,8 @@ import com.teragrep.pth10.ast.bo.Token.Type; import com.teragrep.pth10.ast.commands.EmitMode; import com.teragrep.pth10.ast.time.DecreasedEpochValue; -import com.teragrep.pth10.ast.time.TimeQualifierInterface; import com.teragrep.pth10.ast.time.TimeQualifier; +import com.teragrep.pth10.ast.time.TimeQualifierImpl; import com.teragrep.pth_03.antlr.DPLParser; import com.teragrep.pth_03.antlr.DPLParserBaseVisitor; import com.teragrep.pth_03.shaded.org.antlr.v4.runtime.tree.TerminalNode; @@ -190,21 +190,22 @@ private ElementNode timeQualifierEmitXml(DPLParser.TimeQualifierContext ctx) { TerminalNode node = (TerminalNode) ctx.getChild(0); String value = ctx.getChild(1).getText(); - final TimeQualifierInterface timeQualifierInterface = new TimeQualifier( + final TimeQualifier timeQualifier = new TimeQualifierImpl( value, catCtx.getTimeFormatString(), node.getSymbol().getType(), doc ); final ElementNode returnValue; - if (timeQualifierInterface.isStartTime()) { - long decreaseValue = 3 * 60 * 60 * 1000; - startTime = timeQualifierInterface.epoch() - decreaseValue; - returnValue = new ElementNode(new DecreasedEpochValue(timeQualifierInterface, decreaseValue).xmlElement()); + if (timeQualifier.isStartTime()) { + final long decreaseValue = 3 * 60 * 60 * 1000; // decrease 3 hours from earliest + final TimeQualifier decreasedQualifier = new DecreasedEpochValue(timeQualifier, decreaseValue); + startTime = decreasedQualifier.epoch(); + returnValue = new ElementNode(decreasedQualifier.xmlElement()); } - else if (timeQualifierInterface.isEndTime()) { - endTime = timeQualifierInterface.epoch(); - returnValue = new ElementNode(timeQualifierInterface.xmlElement()); + else if (timeQualifier.isEndTime()) { + endTime = timeQualifier.epoch(); + returnValue = new ElementNode(timeQualifier.xmlElement()); } else { throw new UnsupportedOperationException("Unexpected token: " + node.getSymbol().getText()); @@ -225,7 +226,12 @@ private ColumnNode timeQualifierEmitCatalyst(DPLParser.TimeQualifierContext ctx) TerminalNode node = (TerminalNode) ctx.getChild(0); String value = ctx.getChild(1).getText(); - TimeQualifier tq = new TimeQualifier(value, catCtx.getTimeFormatString(), node.getSymbol().getType(), doc); + TimeQualifierImpl tq = new TimeQualifierImpl( + value, + catCtx.getTimeFormatString(), + node.getSymbol().getType(), + doc + ); if (tq.isStartTime()) { startTime = tq.epoch(); diff --git a/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java index ccf50aa..076d0f7 100644 --- a/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java +++ b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java @@ -45,25 +45,30 @@ */ package com.teragrep.pth10.ast.time; +import org.apache.spark.sql.Column; +import org.apache.spark.sql.functions; import org.w3c.dom.Element; +import java.util.Objects; + /** Decreases the amount from qualifier epoch value */ -public class DecreasedEpochValue implements TimeQualifierInterface { +public final class DecreasedEpochValue implements TimeQualifier { - TimeQualifierInterface origin; - long decreaseEpochValue; + private final TimeQualifier origin; + private final long decreaseAmount; - public DecreasedEpochValue(TimeQualifierInterface origin, long decreaseEpochValue) { + public DecreasedEpochValue(final TimeQualifier origin, final long decreaseAmount) { this.origin = origin; - this.decreaseEpochValue = decreaseEpochValue; + this.decreaseAmount = decreaseAmount; } @Override public Element xmlElement() { - final Element el = origin.xmlElement(); - final long newValue = Long.parseLong(el.getAttribute("value")) - decreaseEpochValue; - el.setAttribute("value", Long.toString(newValue)); - return el; + final long decreasedValue = origin.epoch() - decreaseAmount; + final Element element = origin.xmlElement(); + // set decreased value + element.setAttribute("value", Long.toString(decreasedValue)); + return element; } @Override @@ -78,6 +83,40 @@ public boolean isEndTime() { @Override public long epoch() { - return origin.epoch() - decreaseEpochValue; + return origin.epoch() - decreaseAmount; + } + + @Override + public Column column() { + final Column timeColumn = new Column("`_time`"); + final Column retrunColumn; + if (origin.isStartTime()) { + retrunColumn = timeColumn.geq(functions.from_unixtime(functions.lit(epoch()))); + } + else if (origin.isEndTime()) { + retrunColumn = timeColumn.lt(functions.from_unixtime(functions.lit(epoch()))); + } + else { + retrunColumn = origin.column(); + } + return retrunColumn; + } + + @Override + public boolean isUnixEpoch() { + return origin.isUnixEpoch(); + } + + @Override + public boolean equals(final Object o) { + if (o == null || getClass() != o.getClass()) + return false; + final DecreasedEpochValue cast = (DecreasedEpochValue) o; + return decreaseAmount == cast.decreaseAmount && Objects.equals(origin, cast.origin); + } + + @Override + public int hashCode() { + return Objects.hash(origin, decreaseAmount); } } diff --git a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java index e0d2b3c..f76ace8 100644 --- a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java +++ b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifier.java @@ -45,124 +45,20 @@ */ package com.teragrep.pth10.ast.time; -import com.teragrep.pth_03.antlr.DPLLexer; import org.apache.spark.sql.Column; -import org.apache.spark.sql.functions; -import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.util.Objects; +public interface TimeQualifier { -public final class TimeQualifier implements TimeQualifierInterface { + Element xmlElement(); - private final int token; - private final String value; - private final String timeformat; - private final Document doc; + boolean isStartTime(); - public TimeQualifier(final String value, final String timeformat, final int type, final Document doc) { - this.token = type; - this.value = value; - this.timeformat = timeformat; - this.doc = doc; - } + boolean isEndTime(); - public long epoch() { - if (isUnixEpoch()) { - try { - return Long.parseLong(value); - } - catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid unix epoch: <[" + value + "]>", e); - } - } - return new EpochTimestamp(value, timeformat).epoch(); - } + long epoch(); - public Column column() { - Column col = new Column("`_time`"); + Column column(); - switch (token) { - case DPLLexer.EARLIEST: - case DPLLexer.INDEX_EARLIEST: - case DPLLexer.STARTTIMEU: { - col = col.geq(functions.from_unixtime(functions.lit(epoch()))); - break; - } - case DPLLexer.LATEST: - case DPLLexer.INDEX_LATEST: - case DPLLexer.ENDTIMEU: { - col = col.lt(functions.from_unixtime(functions.lit(epoch()))); - break; - } - default: { - throw new RuntimeException("TimeQualifier <" + token + "> not implemented yet."); - } - } - - return col; - } - - public Element xmlElement() { - // Handle date calculations - Element el; - switch (token) { - case DPLLexer.EARLIEST: - case DPLLexer.STARTTIMEU: { - el = doc.createElement("earliest"); - el.setAttribute("operation", "GE"); - break; - } - case DPLLexer.INDEX_EARLIEST: { - el = doc.createElement("index_earliest"); - el.setAttribute("operation", "GE"); - break; - } - case DPLLexer.LATEST: - case DPLLexer.ENDTIMEU: { - el = doc.createElement("latest"); - el.setAttribute("operation", "LE"); - break; - } - case DPLLexer.INDEX_LATEST: { - el = doc.createElement("index_latest"); - el.setAttribute("operation", "LE"); - break; - } - default: { - throw new RuntimeException("TimeQualifier <" + token + "> not implemented yet."); - } - } - - el.setAttribute("value", Long.toString(epoch())); - return el; - } - - public boolean isStartTime() { - return token == DPLLexer.EARLIEST || token == DPLLexer.INDEX_EARLIEST || token == DPLLexer.STARTTIMEU; - } - - public boolean isEndTime() { - return token == DPLLexer.LATEST || token == DPLLexer.INDEX_LATEST || token == DPLLexer.ENDTIMEU; - } - - public boolean isUnixEpoch() { - return token == DPLLexer.STARTTIMEU || token == DPLLexer.ENDTIMEU; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - TimeQualifier that = (TimeQualifier) o; - return Objects.equals(token, that.token) && Objects.equals(value, that.value) - && Objects.equals(timeformat, that.timeformat) && Objects.equals(doc, that.doc); - } - - @Override - public int hashCode() { - return Objects.hash(token, value, timeformat, doc); - } + boolean isUnixEpoch(); } diff --git a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierImpl.java b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierImpl.java new file mode 100644 index 0000000..509b4fd --- /dev/null +++ b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierImpl.java @@ -0,0 +1,168 @@ +/* + * Teragrep Data Processing Language (DPL) translator for Apache Spark (pth_10) + * Copyright (C) 2019-2024 Suomen Kanuuna Oy + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * + * Additional permission under GNU Affero General Public License version 3 + * section 7 + * + * If you modify this Program, or any covered work, by linking or combining it + * with other code, such other code is not for that reason alone subject to any + * of the requirements of the GNU Affero GPL version 3 as long as this Program + * is the same Program as licensed from Suomen Kanuuna Oy without any additional + * modifications. + * + * Supplemented terms under GNU Affero General Public License version 3 + * section 7 + * + * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified + * versions must be marked as "Modified version of" The Program. + * + * Names of the licensors and authors may not be used for publicity purposes. + * + * No rights are granted for use of trade names, trademarks, or service marks + * which are in The Program if any. + * + * Licensee must indemnify licensors and authors for any liability that these + * contractual assumptions impose on licensors and authors. + * + * To the extent this program is licensed as part of the Commercial versions of + * Teragrep, the applicable Commercial License may apply to this file if you as + * a licensee so wish it. + */ +package com.teragrep.pth10.ast.time; + +import com.teragrep.pth_03.antlr.DPLLexer; +import org.apache.spark.sql.Column; +import org.apache.spark.sql.functions; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.Objects; + +public final class TimeQualifierImpl implements TimeQualifier { + + private final int token; + private final String value; + private final String timeformat; + private final Document doc; + + public TimeQualifierImpl(final String value, final String timeformat, final int type, final Document doc) { + this.token = type; + this.value = value; + this.timeformat = timeformat; + this.doc = doc; + } + + public long epoch() { + if (isUnixEpoch()) { + try { + return Long.parseLong(value); + } + catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid unix epoch: <[" + value + "]>", e); + } + } + return new EpochTimestamp(value, timeformat).epoch(); + } + + public Column column() { + Column col = new Column("`_time`"); + + switch (token) { + case DPLLexer.EARLIEST: + case DPLLexer.INDEX_EARLIEST: + case DPLLexer.STARTTIMEU: { + col = col.geq(functions.from_unixtime(functions.lit(epoch()))); + break; + } + case DPLLexer.LATEST: + case DPLLexer.INDEX_LATEST: + case DPLLexer.ENDTIMEU: { + col = col.lt(functions.from_unixtime(functions.lit(epoch()))); + break; + } + default: { + throw new RuntimeException("TimeQualifier <" + token + "> not implemented yet."); + } + } + + return col; + } + + public Element xmlElement() { + // Handle date calculations + Element el; + switch (token) { + case DPLLexer.EARLIEST: + case DPLLexer.STARTTIMEU: { + el = doc.createElement("earliest"); + el.setAttribute("operation", "GE"); + break; + } + case DPLLexer.INDEX_EARLIEST: { + el = doc.createElement("index_earliest"); + el.setAttribute("operation", "GE"); + break; + } + case DPLLexer.LATEST: + case DPLLexer.ENDTIMEU: { + el = doc.createElement("latest"); + el.setAttribute("operation", "LE"); + break; + } + case DPLLexer.INDEX_LATEST: { + el = doc.createElement("index_latest"); + el.setAttribute("operation", "LE"); + break; + } + default: { + throw new RuntimeException("TimeQualifier <" + token + "> not implemented yet."); + } + } + + el.setAttribute("value", Long.toString(epoch())); + return el; + } + + public boolean isStartTime() { + return token == DPLLexer.EARLIEST || token == DPLLexer.INDEX_EARLIEST || token == DPLLexer.STARTTIMEU; + } + + public boolean isEndTime() { + return token == DPLLexer.LATEST || token == DPLLexer.INDEX_LATEST || token == DPLLexer.ENDTIMEU; + } + + public boolean isUnixEpoch() { + return token == DPLLexer.STARTTIMEU || token == DPLLexer.ENDTIMEU; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + TimeQualifierImpl that = (TimeQualifierImpl) o; + return Objects.equals(token, that.token) && Objects.equals(value, that.value) + && Objects.equals(timeformat, that.timeformat) && Objects.equals(doc, that.doc); + } + + @Override + public int hashCode() { + return Objects.hash(token, value, timeformat, doc); + } +} diff --git a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java b/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java deleted file mode 100644 index 9389125..0000000 --- a/src/main/java/com/teragrep/pth10/ast/time/TimeQualifierInterface.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Teragrep Data Processing Language (DPL) translator for Apache Spark (pth_10) - * Copyright (C) 2019-2024 Suomen Kanuuna Oy - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - * - * Additional permission under GNU Affero General Public License version 3 - * section 7 - * - * If you modify this Program, or any covered work, by linking or combining it - * with other code, such other code is not for that reason alone subject to any - * of the requirements of the GNU Affero GPL version 3 as long as this Program - * is the same Program as licensed from Suomen Kanuuna Oy without any additional - * modifications. - * - * Supplemented terms under GNU Affero General Public License version 3 - * section 7 - * - * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified - * versions must be marked as "Modified version of" The Program. - * - * Names of the licensors and authors may not be used for publicity purposes. - * - * No rights are granted for use of trade names, trademarks, or service marks - * which are in The Program if any. - * - * Licensee must indemnify licensors and authors for any liability that these - * contractual assumptions impose on licensors and authors. - * - * To the extent this program is licensed as part of the Commercial versions of - * Teragrep, the applicable Commercial License may apply to this file if you as - * a licensee so wish it. - */ -package com.teragrep.pth10.ast.time; - -import org.w3c.dom.Element; - -public interface TimeQualifierInterface { - - Element xmlElement(); - - boolean isStartTime(); - - boolean isEndTime(); - - long epoch(); -} diff --git a/src/test/java/com/teragrep/pth10/DecreasedEpochValueTest.java b/src/test/java/com/teragrep/pth10/DecreasedEpochValueTest.java new file mode 100644 index 0000000..bd2147a --- /dev/null +++ b/src/test/java/com/teragrep/pth10/DecreasedEpochValueTest.java @@ -0,0 +1,149 @@ +/* + * Teragrep Data Processing Language (DPL) translator for Apache Spark (pth_10) + * Copyright (C) 2019-2024 Suomen Kanuuna Oy + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + * + * Additional permission under GNU Affero General Public License version 3 + * section 7 + * + * If you modify this Program, or any covered work, by linking or combining it + * with other code, such other code is not for that reason alone subject to any + * of the requirements of the GNU Affero GPL version 3 as long as this Program + * is the same Program as licensed from Suomen Kanuuna Oy without any additional + * modifications. + * + * Supplemented terms under GNU Affero General Public License version 3 + * section 7 + * + * Origin of the software must be attributed to Suomen Kanuuna Oy. Any modified + * versions must be marked as "Modified version of" The Program. + * + * Names of the licensors and authors may not be used for publicity purposes. + * + * No rights are granted for use of trade names, trademarks, or service marks + * which are in The Program if any. + * + * Licensee must indemnify licensors and authors for any liability that these + * contractual assumptions impose on licensors and authors. + * + * To the extent this program is licensed as part of the Commercial versions of + * Teragrep, the applicable Commercial License may apply to this file if you as + * a licensee so wish it. + */ +package com.teragrep.pth10; + +import com.teragrep.pth10.ast.time.DecreasedEpochValue; +import com.teragrep.pth10.ast.time.TimeQualifier; +import com.teragrep.pth10.ast.time.TimeQualifierImpl; +import com.teragrep.pth_03.antlr.DPLLexer; +import org.apache.spark.sql.Column; +import org.apache.spark.sql.functions; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilderFactory; + +public class DecreasedEpochValueTest { + + @Test + public void testDecreasedEpochValueDecorator() { + final long decreaseAmount = 1000L; + final String value = "2024-31-10"; + final String timeformat = "%Y-%d-%m"; + final int earliestType = DPLLexer.EARLIEST; + final Document doc = Assertions + .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); + final TimeQualifier timeQualifier = new DecreasedEpochValue( + new TimeQualifierImpl(value, timeformat, earliestType, doc), + decreaseAmount + ); + final long expectedEpoch = 1730325600L - decreaseAmount; + final Element expectedElement = doc.createElement("earliest"); + expectedElement.setAttribute("operation", "GE"); + expectedElement.setAttribute("value", Long.toString(expectedEpoch)); + Assertions.assertTrue(timeQualifier.isStartTime()); + Assertions.assertEquals(expectedElement.toString(), timeQualifier.xmlElement().toString()); + Assertions.assertEquals(expectedEpoch, timeQualifier.epoch()); + } + + @Test + public void testColOverride() { + final long decreaseAmount = 1000L; + final String value = "2024-31-10"; + final long valueAsEpoch = 1730325600L - decreaseAmount; + final String timeformat = "%Y-%d-%m"; + final int earliestType = DPLLexer.EARLIEST; + final Document doc = Assertions + .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); + + TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); + final TimeQualifier decreased = new DecreasedEpochValue(origin, decreaseAmount); + Column expectedCol = new Column("`_time`").geq(functions.from_unixtime(functions.lit(valueAsEpoch))); + Assertions.assertEquals(expectedCol, decreased.column()); + Assertions.assertNotEquals(expectedCol, origin.column()); + } + + @Test + public void testEquality() { + final long decreaseAmount = 1000L; + final String value = "2024-31-10"; + final String timeformat = "%Y-%d-%m"; + final int earliestType = DPLLexer.EARLIEST; + final Document doc = Assertions + .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); + + TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); + final TimeQualifier decreased1 = new DecreasedEpochValue(origin, decreaseAmount); + final TimeQualifier decreased2 = new DecreasedEpochValue(origin, decreaseAmount); + + Assertions.assertEquals(decreased1, decreased2); + } + + @Test + public void testNonEquality() { + final long decreaseAmount = 1000L; + final String value = "2024-31-10"; + final String timeformat = "%Y-%d-%m"; + final int earliestType = DPLLexer.EARLIEST; + final Document doc = Assertions + .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); + + TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); + final TimeQualifier decreased1 = new DecreasedEpochValue(origin, decreaseAmount); + final TimeQualifier decreased2 = new DecreasedEpochValue(origin, decreaseAmount - 1000); + + Assertions.assertNotEquals(decreased1, decreased2); + } + + @Test + public void testHashCode() { + final long decreaseAmount = 1000L; + final String value = "2024-31-10"; + final String timeformat = "%Y-%d-%m"; + final int earliestType = DPLLexer.EARLIEST; + final Document doc = Assertions + .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); + + TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); + final TimeQualifier decreased1 = new DecreasedEpochValue(origin, decreaseAmount); + final TimeQualifier decreased2 = new DecreasedEpochValue(origin, decreaseAmount); + final TimeQualifier decreasedNotEq = new DecreasedEpochValue(origin, decreaseAmount - 1000); + Assertions.assertEquals(decreased1.hashCode(), decreased2.hashCode()); + Assertions.assertNotEquals(decreased1.hashCode(), decreasedNotEq.hashCode()); + } +} diff --git a/src/test/java/com/teragrep/pth10/TimeQualifierTest.java b/src/test/java/com/teragrep/pth10/TimeQualifierImplTest.java similarity index 81% rename from src/test/java/com/teragrep/pth10/TimeQualifierTest.java rename to src/test/java/com/teragrep/pth10/TimeQualifierImplTest.java index ab04272..61c771e 100644 --- a/src/test/java/com/teragrep/pth10/TimeQualifierTest.java +++ b/src/test/java/com/teragrep/pth10/TimeQualifierImplTest.java @@ -45,9 +45,7 @@ */ package com.teragrep.pth10; -import com.teragrep.pth10.ast.time.DecreasedEpochValue; -import com.teragrep.pth10.ast.time.TimeQualifier; -import com.teragrep.pth10.ast.time.TimeQualifierInterface; +import com.teragrep.pth10.ast.time.TimeQualifierImpl; import com.teragrep.pth_03.antlr.DPLLexer; import org.apache.spark.sql.Column; import org.apache.spark.sql.functions; @@ -58,7 +56,7 @@ import javax.xml.parsers.DocumentBuilderFactory; -public class TimeQualifierTest { +public class TimeQualifierImplTest { @Test public void testEarliest() { @@ -67,7 +65,7 @@ public void testEarliest() { final int type = DPLLexer.EARLIEST; final Document doc = Assertions .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - TimeQualifier tq = new TimeQualifier(value, timeformat, type, doc); + TimeQualifierImpl tq = new TimeQualifierImpl(value, timeformat, type, doc); Column expected = new Column("`_time`").geq(functions.from_unixtime(functions.lit(1730325600L))); Element el = doc.createElement("earliest"); el.setAttribute("operation", "GE"); @@ -84,7 +82,7 @@ public void testLatest() { final int type = DPLLexer.LATEST; final Document doc = Assertions .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - TimeQualifier tq = new TimeQualifier(value, timeformat, type, doc); + TimeQualifierImpl tq = new TimeQualifierImpl(value, timeformat, type, doc); Column expected = new Column("`_time`").lt(functions.from_unixtime(functions.lit(1730325600L))); Element el = doc.createElement("latest"); el.setAttribute("operation", "LE"); @@ -101,7 +99,7 @@ public void testIndexEarliest() { final int type = DPLLexer.INDEX_EARLIEST; final Document doc = Assertions .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - TimeQualifier tq = new TimeQualifier(value, timeformat, type, doc); + TimeQualifierImpl tq = new TimeQualifierImpl(value, timeformat, type, doc); Column expected = new Column("`_time`").geq(functions.from_unixtime(functions.lit(1730325600L))); Element el = doc.createElement("index_earliest"); el.setAttribute("operation", "GE"); @@ -118,7 +116,7 @@ public void testIndexLatest() { final int type = DPLLexer.INDEX_LATEST; final Document doc = Assertions .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - TimeQualifier tq = new TimeQualifier(value, timeformat, type, doc); + TimeQualifierImpl tq = new TimeQualifierImpl(value, timeformat, type, doc); Column expected = new Column("`_time`").lt(functions.from_unixtime(functions.lit(1730325600L))); Element el = doc.createElement("index_latest"); el.setAttribute("operation", "LE"); @@ -135,7 +133,7 @@ public void testStarttimeU() { final int type = DPLLexer.STARTTIMEU; final Document doc = Assertions .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - TimeQualifier tq = new TimeQualifier(value, timeformat, type, doc); + TimeQualifierImpl tq = new TimeQualifierImpl(value, timeformat, type, doc); Column expected = new Column("`_time`").geq(functions.from_unixtime(functions.lit(1730325600L))); Element el = doc.createElement("earliest"); el.setAttribute("operation", "GE"); @@ -152,7 +150,7 @@ public void testEndtimeU() { final int type = DPLLexer.ENDTIMEU; final Document doc = Assertions .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - TimeQualifier tq = new TimeQualifier(value, timeformat, type, doc); + TimeQualifierImpl tq = new TimeQualifierImpl(value, timeformat, type, doc); Column expected = new Column("`_time`").lt(functions.from_unixtime(functions.lit(1730325600L))); Element el = doc.createElement("latest"); el.setAttribute("operation", "LE"); @@ -162,24 +160,6 @@ public void testEndtimeU() { Assertions.assertEquals(el.toString(), tq.xmlElement().toString()); } - @Test - public void testDecreaseDecorator() { - long decreaseAmount = 1000L; - final String value = "2024-31-10"; - final String timeformat = "%Y-%d-%m"; - final int earliestType = DPLLexer.EARLIEST; - final Document doc = Assertions - .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - TimeQualifierInterface tq = new DecreasedEpochValue( - new TimeQualifier(value, timeformat, earliestType, doc), - decreaseAmount - ); - Element el = doc.createElement("earliest"); - el.setAttribute("operation", "GE"); - el.setAttribute("value", Long.toString(1730325600L - decreaseAmount)); - Assertions.assertEquals(el.toString(), tq.xmlElement().toString()); - } - @Test public void testInvalidToken() { final String value = "024-10-31:00:00:00"; @@ -189,10 +169,10 @@ public void testInvalidToken() { .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); RuntimeException e = Assertions - .assertThrows(RuntimeException.class, () -> new TimeQualifier(value, timeformat, type, doc).column()); + .assertThrows(RuntimeException.class, () -> new TimeQualifierImpl(value, timeformat, type, doc).column()); Assertions.assertEquals("TimeQualifier <" + type + "> not implemented yet.", e.getMessage()); RuntimeException exml = Assertions - .assertThrows(RuntimeException.class, () -> new TimeQualifier(value, timeformat, type, doc).xmlElement()); + .assertThrows(RuntimeException.class, () -> new TimeQualifierImpl(value, timeformat, type, doc).xmlElement()); Assertions.assertEquals("TimeQualifier <" + type + "> not implemented yet.", exml.getMessage()); } @@ -205,7 +185,7 @@ public void testEquals() { .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); Assertions - .assertEquals(new TimeQualifier(value, timeformat, type, doc), new TimeQualifier(value, timeformat, type, doc)); + .assertEquals(new TimeQualifierImpl(value, timeformat, type, doc), new TimeQualifierImpl(value, timeformat, type, doc)); } @@ -219,7 +199,7 @@ public void testNotEquals() { .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); Assertions - .assertNotEquals(new TimeQualifier(value, timeformat, type, doc), new TimeQualifier(value2, timeformat, type, doc)); + .assertNotEquals(new TimeQualifierImpl(value, timeformat, type, doc), new TimeQualifierImpl(value2, timeformat, type, doc)); } } From 52fe2d6301e69055febea30af2bdbc63b11a9022 Mon Sep 17 00:00:00 2001 From: elliVM <47@teragrep.com> Date: Mon, 18 Nov 2024 15:04:44 +0200 Subject: [PATCH 6/7] fix typo --- .../teragrep/pth10/ast/time/DecreasedEpochValue.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java index 076d0f7..246777d 100644 --- a/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java +++ b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java @@ -89,17 +89,17 @@ public long epoch() { @Override public Column column() { final Column timeColumn = new Column("`_time`"); - final Column retrunColumn; + final Column rv; if (origin.isStartTime()) { - retrunColumn = timeColumn.geq(functions.from_unixtime(functions.lit(epoch()))); + rv = timeColumn.geq(functions.from_unixtime(functions.lit(epoch()))); } else if (origin.isEndTime()) { - retrunColumn = timeColumn.lt(functions.from_unixtime(functions.lit(epoch()))); + rv = timeColumn.lt(functions.from_unixtime(functions.lit(epoch()))); } else { - retrunColumn = origin.column(); + rv = origin.column(); } - return retrunColumn; + return rv; } @Override From 94ee229a0025118a7d9ed8be2587fe0edf9c27e9 Mon Sep 17 00:00:00 2001 From: elliVM <47@teragrep.com> Date: Wed, 20 Nov 2024 12:45:35 +0200 Subject: [PATCH 7/7] Rename class, only decrease value inside xml element, add comments, add EqualsVerifier and contract test --- pom.xml | 6 +++ .../logicalstatement/TimeStatement.java | 4 +- ...ava => DecreasedEpochXmlElementValue.java} | 27 ++++------ ...=> DecreasedEpochXmlElementValueTest.java} | 52 ++++++++----------- 4 files changed, 39 insertions(+), 50 deletions(-) rename src/main/java/com/teragrep/pth10/ast/time/{DecreasedEpochValue.java => DecreasedEpochXmlElementValue.java} (80%) rename src/test/java/com/teragrep/pth10/{DecreasedEpochValueTest.java => DecreasedEpochXmlElementValueTest.java} (73%) diff --git a/pom.xml b/pom.xml index e832e46..3ce9c1b 100644 --- a/pom.xml +++ b/pom.xml @@ -249,6 +249,12 @@ slf4j-api 2.0.16 + + nl.jqno.equalsverifier + equalsverifier + 3.17.3 + test + ${project.basedir}/target diff --git a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java index c088005..7039199 100644 --- a/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java +++ b/src/main/java/com/teragrep/pth10/ast/commands/logicalstatement/TimeStatement.java @@ -49,7 +49,7 @@ import com.teragrep.pth10.ast.bo.*; import com.teragrep.pth10.ast.bo.Token.Type; import com.teragrep.pth10.ast.commands.EmitMode; -import com.teragrep.pth10.ast.time.DecreasedEpochValue; +import com.teragrep.pth10.ast.time.DecreasedEpochXmlElementValue; import com.teragrep.pth10.ast.time.TimeQualifier; import com.teragrep.pth10.ast.time.TimeQualifierImpl; import com.teragrep.pth_03.antlr.DPLParser; @@ -199,7 +199,7 @@ private ElementNode timeQualifierEmitXml(DPLParser.TimeQualifierContext ctx) { final ElementNode returnValue; if (timeQualifier.isStartTime()) { final long decreaseValue = 3 * 60 * 60 * 1000; // decrease 3 hours from earliest - final TimeQualifier decreasedQualifier = new DecreasedEpochValue(timeQualifier, decreaseValue); + final TimeQualifier decreasedQualifier = new DecreasedEpochXmlElementValue(timeQualifier, decreaseValue); startTime = decreasedQualifier.epoch(); returnValue = new ElementNode(decreasedQualifier.xmlElement()); } diff --git a/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochXmlElementValue.java similarity index 80% rename from src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java rename to src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochXmlElementValue.java index 246777d..7bab5eb 100644 --- a/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochValue.java +++ b/src/main/java/com/teragrep/pth10/ast/time/DecreasedEpochXmlElementValue.java @@ -46,18 +46,20 @@ package com.teragrep.pth10.ast.time; import org.apache.spark.sql.Column; -import org.apache.spark.sql.functions; import org.w3c.dom.Element; import java.util.Objects; -/** Decreases the amount from qualifier epoch value */ -public final class DecreasedEpochValue implements TimeQualifier { +/** + * Decreases set amount from xmlElement() Element value tag that contains an epoch value. Used as a temporary workaround + * for pth_06 database schema. + */ +public final class DecreasedEpochXmlElementValue implements TimeQualifier { private final TimeQualifier origin; private final long decreaseAmount; - public DecreasedEpochValue(final TimeQualifier origin, final long decreaseAmount) { + public DecreasedEpochXmlElementValue(final TimeQualifier origin, final long decreaseAmount) { this.origin = origin; this.decreaseAmount = decreaseAmount; } @@ -83,23 +85,12 @@ public boolean isEndTime() { @Override public long epoch() { - return origin.epoch() - decreaseAmount; + return origin.epoch(); } @Override public Column column() { - final Column timeColumn = new Column("`_time`"); - final Column rv; - if (origin.isStartTime()) { - rv = timeColumn.geq(functions.from_unixtime(functions.lit(epoch()))); - } - else if (origin.isEndTime()) { - rv = timeColumn.lt(functions.from_unixtime(functions.lit(epoch()))); - } - else { - rv = origin.column(); - } - return rv; + return origin.column(); } @Override @@ -111,7 +102,7 @@ public boolean isUnixEpoch() { public boolean equals(final Object o) { if (o == null || getClass() != o.getClass()) return false; - final DecreasedEpochValue cast = (DecreasedEpochValue) o; + final DecreasedEpochXmlElementValue cast = (DecreasedEpochXmlElementValue) o; return decreaseAmount == cast.decreaseAmount && Objects.equals(origin, cast.origin); } diff --git a/src/test/java/com/teragrep/pth10/DecreasedEpochValueTest.java b/src/test/java/com/teragrep/pth10/DecreasedEpochXmlElementValueTest.java similarity index 73% rename from src/test/java/com/teragrep/pth10/DecreasedEpochValueTest.java rename to src/test/java/com/teragrep/pth10/DecreasedEpochXmlElementValueTest.java index bd2147a..bc9f6b5 100644 --- a/src/test/java/com/teragrep/pth10/DecreasedEpochValueTest.java +++ b/src/test/java/com/teragrep/pth10/DecreasedEpochXmlElementValueTest.java @@ -45,12 +45,11 @@ */ package com.teragrep.pth10; -import com.teragrep.pth10.ast.time.DecreasedEpochValue; +import com.teragrep.pth10.ast.time.DecreasedEpochXmlElementValue; import com.teragrep.pth10.ast.time.TimeQualifier; import com.teragrep.pth10.ast.time.TimeQualifierImpl; import com.teragrep.pth_03.antlr.DPLLexer; -import org.apache.spark.sql.Column; -import org.apache.spark.sql.functions; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.w3c.dom.Document; @@ -58,7 +57,7 @@ import javax.xml.parsers.DocumentBuilderFactory; -public class DecreasedEpochValueTest { +public class DecreasedEpochXmlElementValueTest { @Test public void testDecreasedEpochValueDecorator() { @@ -68,7 +67,7 @@ public void testDecreasedEpochValueDecorator() { final int earliestType = DPLLexer.EARLIEST; final Document doc = Assertions .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - final TimeQualifier timeQualifier = new DecreasedEpochValue( + final TimeQualifier timeQualifier = new DecreasedEpochXmlElementValue( new TimeQualifierImpl(value, timeformat, earliestType, doc), decreaseAmount ); @@ -78,24 +77,8 @@ public void testDecreasedEpochValueDecorator() { expectedElement.setAttribute("value", Long.toString(expectedEpoch)); Assertions.assertTrue(timeQualifier.isStartTime()); Assertions.assertEquals(expectedElement.toString(), timeQualifier.xmlElement().toString()); - Assertions.assertEquals(expectedEpoch, timeQualifier.epoch()); - } - - @Test - public void testColOverride() { - final long decreaseAmount = 1000L; - final String value = "2024-31-10"; - final long valueAsEpoch = 1730325600L - decreaseAmount; - final String timeformat = "%Y-%d-%m"; - final int earliestType = DPLLexer.EARLIEST; - final Document doc = Assertions - .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); - - TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); - final TimeQualifier decreased = new DecreasedEpochValue(origin, decreaseAmount); - Column expectedCol = new Column("`_time`").geq(functions.from_unixtime(functions.lit(valueAsEpoch))); - Assertions.assertEquals(expectedCol, decreased.column()); - Assertions.assertNotEquals(expectedCol, origin.column()); + // epoch() value should remain unchanged + Assertions.assertEquals(expectedEpoch + decreaseAmount, timeQualifier.epoch()); } @Test @@ -108,8 +91,8 @@ public void testEquality() { .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); - final TimeQualifier decreased1 = new DecreasedEpochValue(origin, decreaseAmount); - final TimeQualifier decreased2 = new DecreasedEpochValue(origin, decreaseAmount); + final TimeQualifier decreased1 = new DecreasedEpochXmlElementValue(origin, decreaseAmount); + final TimeQualifier decreased2 = new DecreasedEpochXmlElementValue(origin, decreaseAmount); Assertions.assertEquals(decreased1, decreased2); } @@ -124,8 +107,8 @@ public void testNonEquality() { .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); - final TimeQualifier decreased1 = new DecreasedEpochValue(origin, decreaseAmount); - final TimeQualifier decreased2 = new DecreasedEpochValue(origin, decreaseAmount - 1000); + final TimeQualifier decreased1 = new DecreasedEpochXmlElementValue(origin, decreaseAmount); + final TimeQualifier decreased2 = new DecreasedEpochXmlElementValue(origin, decreaseAmount - 1000); Assertions.assertNotEquals(decreased1, decreased2); } @@ -140,10 +123,19 @@ public void testHashCode() { .assertDoesNotThrow(() -> DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument()); TimeQualifierImpl origin = new TimeQualifierImpl(value, timeformat, earliestType, doc); - final TimeQualifier decreased1 = new DecreasedEpochValue(origin, decreaseAmount); - final TimeQualifier decreased2 = new DecreasedEpochValue(origin, decreaseAmount); - final TimeQualifier decreasedNotEq = new DecreasedEpochValue(origin, decreaseAmount - 1000); + final TimeQualifier decreased1 = new DecreasedEpochXmlElementValue(origin, decreaseAmount); + final TimeQualifier decreased2 = new DecreasedEpochXmlElementValue(origin, decreaseAmount); + final TimeQualifier decreasedNotEq = new DecreasedEpochXmlElementValue(origin, decreaseAmount - 1000); Assertions.assertEquals(decreased1.hashCode(), decreased2.hashCode()); Assertions.assertNotEquals(decreased1.hashCode(), decreasedNotEq.hashCode()); } + + @Test + public void testContract() { + EqualsVerifier + .forClass(DecreasedEpochXmlElementValue.class) + .withNonnullFields("origin") + .withNonnullFields("decreaseAmount") + .verify(); + } }