Skip to content

Commit c72ae18

Browse files
committed
Add LogDate to the JOIN condition
LogDate is part of Partitioned Primary Index of both tables, so it needs to be part of the JOIN condition.
1 parent 4c8dfd6 commit c72ae18

File tree

3 files changed

+240
-8
lines changed

3 files changed

+240
-8
lines changed

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/teradata/TeradataLogsConnector.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ public enum TeradataLogsConnectorProperty implements ConnectorProperty {
6767
LOG_DATE_COLUMN(
6868
"log-date-column",
6969
"The name of the column of type DATE to include in the WHERE clause when dumping"
70-
+ " query log tables (see --query-log-alternates for query log table names).",
70+
+ " query log tables. The column must exist in both tables."
71+
+ " See --query-log-alternates for query log table names.",
7172
/* defaultValue= */ null);
7273

7374
private final String name;

dumper/app/src/main/java/com/google/edwmigration/dumper/application/dumper/connector/teradata/TeradataLogsJdbcTask.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,12 @@ private String getSql(@Nonnull JdbcHandle handle) {
190190
// "QueryID is a system-wide unique field; you can use QueryID
191191
// to join DBQL tables ... without needing ProcID as an additional join field."
192192
// (https://docs.teradata.com/reader/B7Lgdw6r3719WUyiCSJcgw/YIKoBz~QQgv2Aw5dF339kA)
193-
buf.append(" LEFT OUTER JOIN ").append(queryTable).append(" ST ON L.QueryID=ST.QueryID");
193+
buf.append(" LEFT OUTER JOIN ").append(queryTable).append(" ST ON (L.QueryID=ST.QueryID");
194+
195+
if (logDateColumn != null) {
196+
buf.append(" AND L.").append(logDateColumn).append("=ST.").append(logDateColumn);
197+
}
198+
buf.append(')');
194199

195200
// Notwithstanding the above: could this offer improved perf due to use of indices?:
196201
// http://elsasoft.com/samples/teradata/Teradata.127.0.0.1.DBC/table_DBQLSqlTbl.htm
@@ -209,15 +214,12 @@ private String getSql(@Nonnull JdbcHandle handle) {
209214
SQL_FORMAT.format(interval.getStart()), SQL_FORMAT.format(interval.getEndExclusive())));
210215

211216
if (logDateColumn != null) {
212-
String date = "CAST('" + SQL_DATE_FORMAT.format(interval.getStart()) + "' AS DATE)";
213217
buf.append(" AND L.")
214218
.append(logDateColumn)
215219
.append(" = ")
216-
.append(date)
217-
.append(" AND ST.")
218-
.append(logDateColumn)
219-
.append(" = ")
220-
.append(date);
220+
.append("CAST('")
221+
.append(SQL_DATE_FORMAT.format(interval.getStart()))
222+
.append("' AS DATE)");
221223
}
222224

223225
for (String condition : conditions) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
* Copyright 2022-2023 Google LLC
3+
* Copyright 2013-2021 CompilerWorks
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.google.edwmigration.dumper.application.dumper.connector.teradata;
18+
19+
import static java.util.Collections.emptyList;
20+
import static org.junit.Assert.assertEquals;
21+
22+
import com.google.common.collect.ImmutableList;
23+
import com.google.edwmigration.dumper.application.dumper.connector.ZonedInterval;
24+
import com.google.edwmigration.dumper.application.dumper.connector.teradata.AbstractTeradataConnector.SharedState;
25+
import java.time.Instant;
26+
import java.time.ZoneId;
27+
import java.time.ZonedDateTime;
28+
import org.junit.Test;
29+
import org.junit.runner.RunWith;
30+
import org.junit.runners.JUnit4;
31+
32+
@RunWith(JUnit4.class)
33+
public class TeradataAssessmentLogsJdbcTaskTest {
34+
35+
private SharedState queryLogsState = new SharedState();
36+
private ZonedInterval interval =
37+
new ZonedInterval(
38+
ZonedDateTime.of(2023, 3, 4, 16, 0, 0, 0, ZoneId.systemDefault()),
39+
ZonedDateTime.of(2023, 3, 4, 17, 0, 0, 0, ZoneId.systemDefault()));
40+
41+
@Test
42+
public void getSql_success() {
43+
TeradataAssessmentLogsJdbcTask jdbcTask =
44+
new TeradataAssessmentLogsJdbcTask(
45+
"result.csv",
46+
queryLogsState,
47+
"SampleQueryTable",
48+
"SampleSqlTable",
49+
/* conditions= */ emptyList(),
50+
interval,
51+
/* logDateColumn= */ null,
52+
/* orderBy */ emptyList());
53+
54+
String query = jdbcTask.getSql(s -> true, new String[] {"L.QueryID", "ST.QueryID"});
55+
56+
assertEqualsIgnoringWhitespace(
57+
"SELECT L.QueryID, ST.QueryID"
58+
+ " FROM SampleQueryTable L LEFT OUTER JOIN SampleSqlTable ST ON (L.QueryID=ST.QueryID)"
59+
+ " WHERE L.ErrorCode=0 AND"
60+
+ " L.StartTime >= CAST('2023-03-04T16:00:00Z' AS TIMESTAMP) AND"
61+
+ " L.StartTime < CAST('2023-03-04T17:00:00Z' AS TIMESTAMP)",
62+
query);
63+
}
64+
65+
@Test
66+
public void getSql_noSecondTable() {
67+
TeradataAssessmentLogsJdbcTask jdbcTask =
68+
new TeradataAssessmentLogsJdbcTask(
69+
"result.csv",
70+
queryLogsState,
71+
"SampleQueryTable",
72+
"SampleSqlTable",
73+
/* conditions= */ emptyList(),
74+
interval,
75+
/* logDateColumn= */ null,
76+
/* orderBy= */ emptyList());
77+
78+
String query = jdbcTask.getSql(s -> true, new String[] {"L.QueryID"});
79+
80+
assertEqualsIgnoringWhitespace(
81+
"SELECT L.QueryID"
82+
+ " FROM SampleQueryTable L"
83+
+ " WHERE L.ErrorCode=0 AND"
84+
+ " L.StartTime >= CAST('2023-03-04T16:00:00Z' AS TIMESTAMP) AND"
85+
+ " L.StartTime < CAST('2023-03-04T17:00:00Z' AS TIMESTAMP)",
86+
query);
87+
}
88+
89+
@Test
90+
public void getSql_noSecondTableWithLogDateColumn() {
91+
TeradataAssessmentLogsJdbcTask jdbcTask =
92+
new TeradataAssessmentLogsJdbcTask(
93+
"result.csv",
94+
queryLogsState,
95+
"SampleQueryTable",
96+
"SampleSqlTable",
97+
/* conditions= */ emptyList(),
98+
interval,
99+
"SampleLogDate", /* orderBy */
100+
emptyList());
101+
102+
String query = jdbcTask.getSql(s -> true, new String[] {"L.QueryID"});
103+
104+
assertEqualsIgnoringWhitespace(
105+
"SELECT L.QueryID"
106+
+ " FROM SampleQueryTable L"
107+
+ " WHERE L.ErrorCode=0 AND"
108+
+ " L.StartTime >= CAST('2023-03-04T16:00:00Z' AS TIMESTAMP) AND"
109+
+ " L.StartTime < CAST('2023-03-04T17:00:00Z' AS TIMESTAMP) AND"
110+
+ " L.SampleLogDate = CAST('2023-03-04Z' AS DATE)",
111+
query);
112+
}
113+
114+
@Test
115+
public void getSql_noSecondTableWithCondition() {
116+
TeradataAssessmentLogsJdbcTask jdbcTask =
117+
new TeradataAssessmentLogsJdbcTask(
118+
"result.csv",
119+
queryLogsState,
120+
"SampleQueryTable",
121+
"SampleSqlTable",
122+
/* conditions= */ ImmutableList.of("L.QueryID=7"),
123+
interval,
124+
/* logDateColumn= */ null,
125+
/* orderBy= */ emptyList());
126+
127+
String query = jdbcTask.getSql(s -> true, new String[] {"L.QueryID"});
128+
129+
assertEqualsIgnoringWhitespace(
130+
"SELECT L.QueryID"
131+
+ " FROM SampleQueryTable L"
132+
+ " WHERE L.ErrorCode=0 AND"
133+
+ " L.StartTime >= CAST('2023-03-04T16:00:00Z' AS TIMESTAMP) AND"
134+
+ " L.StartTime < CAST('2023-03-04T17:00:00Z' AS TIMESTAMP) AND L.QueryID=7",
135+
query);
136+
}
137+
138+
@Test
139+
public void getSql_noSecondTableWithOrderBy() {
140+
TeradataAssessmentLogsJdbcTask jdbcTask =
141+
new TeradataAssessmentLogsJdbcTask(
142+
"result.csv",
143+
queryLogsState,
144+
"SampleQueryTable",
145+
"SampleSqlTable",
146+
/* conditions= */ emptyList(),
147+
interval,
148+
/* logDateColumn= */ null,
149+
/* orderBy= */ ImmutableList.of("L.QueryID", "L.QueryText"));
150+
151+
String query = jdbcTask.getSql(s -> true, new String[] {"L.QueryID"});
152+
153+
assertEqualsIgnoringWhitespace(
154+
"SELECT L.QueryID"
155+
+ " FROM SampleQueryTable L"
156+
+ " WHERE L.ErrorCode=0 AND"
157+
+ " L.StartTime >= CAST('2023-03-04T16:00:00Z' AS TIMESTAMP) AND"
158+
+ " L.StartTime < CAST('2023-03-04T17:00:00Z' AS TIMESTAMP)"
159+
+ " ORDER BY L.QueryID, L.QueryText",
160+
query);
161+
}
162+
163+
@Test
164+
public void getSql_withLogDateColumn() {
165+
TeradataAssessmentLogsJdbcTask jdbcTask =
166+
new TeradataAssessmentLogsJdbcTask(
167+
"result.csv",
168+
queryLogsState,
169+
"SampleQueryTable",
170+
"SampleSqlTable",
171+
/* conditions= */ emptyList(),
172+
interval,
173+
"SampleLogDate", /* orderBy */
174+
emptyList());
175+
176+
String query = jdbcTask.getSql(s -> true, new String[] {"L.QueryID", "ST.QueryID"});
177+
178+
assertEqualsIgnoringWhitespace(
179+
"SELECT L.QueryID, ST.QueryID"
180+
+ " FROM SampleQueryTable L LEFT OUTER JOIN SampleSqlTable ST"
181+
+ " ON (L.QueryID=ST.QueryID AND L.SampleLogDate=ST.SampleLogDate)"
182+
+ " WHERE L.ErrorCode=0 AND"
183+
+ " L.StartTime >= CAST('2023-03-04T16:00:00Z' AS TIMESTAMP) AND"
184+
+ " L.StartTime < CAST('2023-03-04T17:00:00Z' AS TIMESTAMP) AND"
185+
+ " L.SampleLogDate = CAST('2023-03-04Z' AS DATE)",
186+
query);
187+
}
188+
189+
@Test
190+
public void getSql_fullQuery() {
191+
TeradataAssessmentLogsJdbcTask jdbcTask =
192+
new TeradataAssessmentLogsJdbcTask(
193+
"result.csv",
194+
queryLogsState,
195+
"SampleQueryTable",
196+
"SampleSqlTable",
197+
ImmutableList.of("QueryID=7", "QueryText LIKE '%abc%'"),
198+
interval,
199+
"SampleLogDate",
200+
ImmutableList.of("ST.QueryID", "ST.RowNo"));
201+
202+
String query =
203+
jdbcTask.getSql(s -> true, new String[] {"L.QueryID", "L.QueryText", "ST.QueryID"});
204+
205+
assertEqualsIgnoringWhitespace(
206+
"SELECT L.QueryID, L.QueryText, ST.QueryID"
207+
+ " FROM SampleQueryTable L LEFT OUTER JOIN SampleSqlTable ST"
208+
+ " ON (L.QueryID=ST.QueryID AND L.SampleLogDate=ST.SampleLogDate)"
209+
+ " WHERE L.ErrorCode=0 AND"
210+
+ " L.StartTime >= CAST('2023-03-04T16:00:00Z' AS TIMESTAMP) AND"
211+
+ " L.StartTime < CAST('2023-03-04T17:00:00Z' AS TIMESTAMP) AND"
212+
+ " L.SampleLogDate = CAST('2023-03-04Z' AS DATE) AND"
213+
+ " QueryID=7 AND QueryText LIKE '%abc%'"
214+
+ " ORDER BY ST.QueryID, ST.RowNo",
215+
query);
216+
}
217+
218+
private static void assertEqualsIgnoringWhitespace(String expected, String actual) {
219+
assertEquals(squashWhitespace(expected), squashWhitespace(actual));
220+
}
221+
222+
private static String squashWhitespace(String s) {
223+
return s.replaceFirst("^\\s+", "").replaceFirst("\\s+$", "").replaceAll("\\s+", " ");
224+
}
225+
226+
private static ZonedDateTime createUTCZonedDateTime(long epochSecond) {
227+
return ZonedDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault());
228+
}
229+
}

0 commit comments

Comments
 (0)