From 040552fbeeb1ea74a794d0e2542cd8c4b509ba5c Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Wed, 17 Nov 2021 13:48:34 -0800
Subject: [PATCH 01/28] Added Tableau Connector to OpenSearch SQL

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../opensearch_sql_jdbc/META-INF/MANIFEST.MF  |   3 +
 .../opensearch_sql_jdbc/connection-fields.xml |  44 +++
 .../connection-metadata.xml                   |   6 +
 .../opensearch_sql_jdbc/connectionBuilder.js  |  28 ++
 .../connectionResolver.tdr                    |  26 ++
 .../opensearch_sql_jdbc/dialect.tdd           | 349 ++++++++++++++++++
 .../opensearch_sql_jdbc/manifest.xml          |  53 +++
 .../opensearch_sql_jdbc_dev.taco              | Bin 0 -> 5259 bytes
 8 files changed, 509 insertions(+)
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/META-INF/MANIFEST.MF
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-fields.xml
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-metadata.xml
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionBuilder.js
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionResolver.tdr
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
 create mode 100644 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/opensearch_sql_jdbc_dev.taco

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/META-INF/MANIFEST.MF b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..97a662d62c5
--- /dev/null
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Created-By: 13 (Oracle Corporation)
+
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-fields.xml b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-fields.xml
new file mode 100644
index 00000000000..54f5296f7e9
--- /dev/null
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-fields.xml
@@ -0,0 +1,44 @@
+<connection-fields>
+    <field name="authentication" label="Authentication" category="authentication" value-type="selection" default-value="auth-user-pass">
+        <selection-group>
+            <option value="auth-none" label="No authentication"/>
+            <option value="auth-user-pass" label="Username and Password"/>
+            <option value="auth-integrated" label="AWS_SIGV4"/>
+        </selection-group>
+    </field>
+    <field name="server" label="Server" value-type="string" category="endpoint" default-value="localhost">
+    </field>
+    <field name="port" label="Port" value-type="string" category="endpoint" default-value="9200">
+    </field>
+    <field name="username" label="Username" category="authentication" value-type="string">
+        <conditions>
+            <condition field="authentication" value="auth-user-pass"/>
+        </conditions>
+    </field>
+    <field name="password" label="Password" category="authentication" value-type="string" secure="true">
+        <conditions>
+            <condition field="authentication" value="auth-user-pass"/>
+        </conditions>
+    </field>
+    <field name="v-region" label="Region" category="authentication" value-type="string" optional="true">
+        <conditions>
+            <condition field="authentication" value="auth-integrated"/>
+        </conditions>
+    </field>
+    <field name="sslmode" label="Use SSL" value-type="boolean" category="general" default-value="require">
+        <boolean-options>
+            <false-value value=""/>
+            <true-value value="require"/>
+        </boolean-options>
+    </field>
+    <field name="v-trustSelfSigned" label="Trust Self-Signed Certificate" value-type="boolean" category="general" default-value="false">
+        <conditions>
+            <condition field="authentication" value="auth-user-pass"/>
+            <condition field="authentication" value="auth-none"/>
+        </conditions>
+        <boolean-options>
+            <false-value value="false"/>
+            <true-value value="true"/>
+        </boolean-options>
+    </field>
+</connection-fields>
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-metadata.xml b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-metadata.xml
new file mode 100644
index 00000000000..1b3432c3177
--- /dev/null
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connection-metadata.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<connection-metadata>
+  <database enabled='false' />
+  <schema enabled='false' />
+  <table enabled='true' label="Table" />
+</connection-metadata>
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionBuilder.js b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionBuilder.js
new file mode 100644
index 00000000000..1a16fddaec1
--- /dev/null
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionBuilder.js
@@ -0,0 +1,28 @@
+(function dsbuilder(attr){
+	var connStr = "jdbc:opensearch://";
+	// Set SSL value in connection string 
+	if (attr[connectionHelper.attributeSSLMode] == "require"){
+		connStr += "https://";
+	} else {
+		connStr += "http://";
+	}
+
+	// Set host information in connection string
+	connStr += attr[connectionHelper.attributeServer] + ":" + attr[connectionHelper.attributePort] + "?";
+
+	// Set authentication values in connection string
+	var authAttrValue = attr[connectionHelper.attributeAuthentication];
+	if (authAttrValue == "auth-none"){
+		connStr += "auth=NONE&trustSelfSigned=" + attr["v-trustSelfSigned"];
+	} else if (authAttrValue == "auth-integrated"){
+		connStr += "auth=AWS_SIGV4";
+		var region = attr["v-region"];
+		if (region){
+			connStr += "&Region=" + region;
+		}
+	} else { //if (authAttrValue == "auth-user-pass"){
+		connStr += "auth=BASIC&user=" + attr[connectionHelper.attributeUsername] + "&password=" + attr[connectionHelper.attributePassword] + "&trustSelfSigned=" + attr["v-trustSelfSigned"];
+	}
+
+	return [connStr];
+})
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionResolver.tdr b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionResolver.tdr
new file mode 100644
index 00000000000..c51adc002ec
--- /dev/null
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/connectionResolver.tdr
@@ -0,0 +1,26 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<tdr class='opensearch_jdbc'>
+  <connection-resolver>
+    <connection-builder>
+      <script file='connectionBuilder.js'/>
+    </connection-builder>
+    <connection-normalizer>
+      <required-attributes>
+        <default-attributes>
+          <default-attribute name='server'>localhost</default-attribute>
+          <default-attribute name='port'>9200</default-attribute>
+        </default-attributes>
+         <attribute-list>
+          <attr>server</attr>
+          <attr>port</attr>
+          <attr>authentication</attr>
+          <attr>username</attr>
+          <attr>password</attr>
+          <attr>sslmode</attr>
+          <attr>v-region</attr>
+          <attr>v-trustSelfSigned</attr>
+        </attribute-list>
+      </required-attributes>
+    </connection-normalizer>
+  </connection-resolver>
+</tdr>
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
new file mode 100644
index 00000000000..f33f42444e5
--- /dev/null
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="utf-8"?>
+<dialect name='OpenSearchSqlJdbcDialect'
+         class='opensearch_jdbc'
+         base='MySQL41UnicodeDriverDialect'
+         version='18.1'>   
+   <function-map>   
+        <function group='aggregate' name='STDEV' return-type='real'>
+            <formula>STDDEV_SAMP(%1)</formula>
+            <unagg-formula>NULL</unagg-formula>
+            <argument type='real' />
+        </function>
+        <function group='aggregate' name='VAR' return-type='real'>
+            <formula>VAR_SAMP(%1)</formula>
+            <unagg-formula>NULL</unagg-formula>
+            <argument type='real' />
+        </function>
+
+        <function group='cast' name='DATE' return-type='date'>
+            <formula>DATE_FORMAT(%1, &apos;%Y-%m-%d&apos;)</formula>
+            <argument type='str' />
+        </function>
+        <function group='cast' name='STR' return-type='str'>
+            <formula>DATE_FORMAT(%1, &apos;%Y-%m-%d %H:%i:%s&apos;)</formula>
+            <argument type='datetime' />
+        </function>
+        <function group='cast' name='DATETIME' return-type='datetime'>
+            <formula>CAST(%1 AS TIMESTAMP)</formula>
+            <argument type='str' />
+        </function>
+        <function group='cast' name='FLOAT' return-type='real'>
+            <!-- 693961 = TO_DAYS('1900-01-01'), since this represents the date of the Epoch. -->
+            <formula>TO_DAYS(%1) - 693961.0</formula>
+            <argument type='datetime' />
+        </function>
+
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(%1 AND NOT %2 OR NOT %1 AND %2)</formula>
+            <argument type='bool' />
+            <argument type='bool' />
+        </function>
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(%1 AND %2 = 0 OR NOT %1 AND %2 &lt;&gt; 0)</formula>
+            <argument type='bool' />
+            <argument type='int' />
+        </function>
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(%1 &lt;&gt; %2)</formula>
+            <argument type='real' />
+            <argument type='real' />
+        </function>
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(%1 = 0 AND %2 OR %1 &lt;&gt; 0 AND NOT %2)</formula>
+            <argument type='int' />
+            <argument type='bool' />
+        </function>
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(%1 &lt;&gt; %2)</formula>
+            <argument type='str' />
+            <argument type='str' />
+        </function>
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(%1 &lt;&gt; %2)</formula>
+            <argument type='datetime' />
+            <argument type='datetime' />
+        </function>
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(CAST(DATE_FORMAT(DATE(%1), '%Y-%m-%d 00:00:00') AS TIMESTAMP) &lt;&gt; %2)</formula>
+            <argument type='date' />
+            <argument type='datetime' />
+        </function>
+        <function group='operator' name='!=' return-type='bool'>
+            <formula>(%1 &lt;&gt; CAST(DATE_FORMAT(DATE(%2), '%Y-%m-%d 00:00:00') AS TIMESTAMP))</formula>
+            <argument type='datetime' />
+            <argument type='date' />
+        </function>
+        <function group='operator' name='+' return-type='datetime'>
+            <!-- 86400 as it represents seconds in a day -->
+            <formula>DATE_ADD(DATE_ADD(%1, INTERVAL FLOOR(%2) DAY), INTERVAL CAST(86400 * (%2 - FLOOR(%2)) AS INT) SECOND)</formula>
+            <argument type='datetime' />
+            <argument type='real' />
+        </function>
+        <function group='operator' name='-' return-type='int'>
+            <formula>(%1 * -1)</formula>
+            <argument type='int' />
+        </function>
+        <function group='operator' name='-' return-type='real'>
+            <formula>(%1 * -1)</formula>
+            <argument type='real' />
+        </function>
+        <function group='operator' name='-' return-type='datetime'>
+            <!-- 86400 as it represents seconds in a day -->
+            <formula>DATE_SUB(DATE_SUB(%1, INTERVAL FLOOR(%2) DAY), INTERVAL CAST(86400 * (%2 - FLOOR(%2)) AS INT) SECOND)</formula>
+            <argument type='datetime' />
+            <argument type='real' />
+        </function>
+        <function group='operator' name='/' return-type='real'>
+            <formula>CAST(%1 AS DOUBLE) / %2</formula>
+            <argument type='int' />
+            <argument type='int' />
+        </function>
+
+        <function group="numeric" name="COT" return-type="real">
+            <formula>CASE WHEN %1 = 0 THEN NULL ELSE COT(%1) END</formula>
+            <argument type="real" />
+        </function>
+        <function group='numeric' name='DIV' return-type='int'>
+            <formula>CASE WHEN %2 = 0 THEN NULL ELSE ( %1 / %2 ) END</formula>
+            <argument type='int' />
+            <argument type='int' />
+        </function>
+        <function group='numeric' name='DIV' return-type='real'>
+            <formula>CASE WHEN %2 = 0 THEN NULL ELSE ( %1 / %2 ) END</formula>
+            <argument type='real' />
+            <argument type='real' />
+        </function>
+        <function group="numeric" name="LN" return-type="real">
+            <formula>(CASE WHEN %1 &gt; 0 THEN LN(%1) ELSE NULL END)</formula>
+            <argument type="real" />
+        </function>
+        <function group="numeric" name="LOG" return-type="real">
+            <formula>CASE WHEN %1 &gt; 0 THEN LOG10(%1) ELSE NULL END</formula>
+            <argument type="real" />
+        </function>
+        <function group="numeric" name="LOG" return-type="real">
+            <formula>CASE WHEN %1 &gt; 0 AND %2 &gt; 0 AND %2 &lt;&gt; 1 THEN LOG(%2,%1) ELSE NULL END</formula>
+            <argument type="real" />
+            <argument type="real" />
+        </function>
+        <function group='numeric' name='MAX' return-type='int'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &gt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='int' />
+            <argument type='int' />
+        </function>
+        <function group='numeric' name='MAX' return-type='real'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &gt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='real' />
+            <argument type='real' />
+        </function>
+        <function group='numeric' name='MAX' return-type='datetime'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &gt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='datetime' />
+            <argument type='datetime' />
+        </function>
+        <function group='numeric' name='MIN' return-type='int'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &lt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='int' />
+            <argument type='int' />
+        </function>
+        <function group='numeric' name='MIN' return-type='real'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &lt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='real' />
+            <argument type='real' />
+        </function>
+        <function group='numeric' name='MIN' return-type='datetime'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &lt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='datetime' />
+            <argument type='datetime' />
+        </function>
+    
+        <function group='date' name='DAYOFYEAR' return-type='int'>
+            <formula>DAY_OF_YEAR(%1)</formula>
+            <argument type='date' />
+        </function>
+        <function group='date' name='DAYOFMONTH' return-type='int'>
+            <formula>DAY_OF_MONTH(%1)</formula>
+            <argument type='date' />
+        </function>
+        <function group='date' name='DAYOFWEEK' return-type='int'>
+            <formula>DAY_OF_WEEK(%1)</formula>
+            <argument type='date' />
+        </function>
+
+        <function group='string' name='MID' return-type='int'>
+            <formula>SUBSTR(%1,%2)</formula>
+            <argument type='str' />
+            <argument type='int' />
+        </function>
+        <function group='string' name='MID' return-type='int'>
+            <formula>SUBSTR(%1,CAST(%2 as int))</formula>
+            <argument type='str' />
+            <argument type='real' />
+        </function>
+        <function group='string' name='MID' return-type='int'>
+            <formula>SUBSTR(%1,%2,%3)</formula>
+            <argument type='str' />
+            <argument type='int' />
+            <argument type='int' />
+        </function>
+        <function group='string' name='MID' return-type='int'>
+            <formula>SUBSTR(%1,CAST(%2 as int),%3)</formula>
+            <argument type='str' />
+            <argument type='real' />
+            <argument type='int' />
+        </function>
+        <function group='string' name='MID' return-type='int'>
+            <formula>SUBSTR(%1,%2,CAST(%3 as int))</formula>
+            <argument type='str' />
+            <argument type='int' />
+            <argument type='real' />
+        </function>
+        <function group='string' name='MID' return-type='int'>
+            <formula>SUBSTR(%1,CAST(%2 as int),CAST(%3 as int))</formula>
+            <argument type='str' />
+            <argument type='real' />
+            <argument type='real' />
+        </function>
+
+        <function group='string' name='FIND' return-type='int'>
+<!--        The formula was simplified, because OS returns valid results even if the argument is NULL or <1 -->
+<!--        <formula>(CASE WHEN ISNULL(%3) THEN NULL WHEN %3 &gt;= 1 THEN LOCATE(%2,%1,CAST(%3 as int)) ELSE LOCATE(%2,%1,1) END)</formula>-->
+            <formula>LOCATE(%2,%1,CAST(%3 as int))</formula>
+            <argument type='str' />
+            <argument type='str' />
+            <argument type='real' />
+        </function>
+        <function group='string' name='FIND' return-type='int'>
+            <formula>LOCATE(%2,%1,%3)</formula>
+            <argument type='str' />
+            <argument type='str' />
+            <argument type='int' />
+        </function>
+
+        <date-function name='DATEDIFF' return-type='int'>
+            <formula part='year'>(YEAR(%3) - YEAR(%2))</formula>
+            <formula part='quarter'>((YEAR(%3) - YEAR(%2)) * 4 + (QUARTER(%3) - QUARTER(%2)))</formula>
+            <formula part='month'>((YEAR(%3) - YEAR(%2)) * 12 + (MONTH(%3) - MONTH(%2)))</formula>
+            <formula part='dayofyear'>(TO_DAYS(%3) - TO_DAYS(%2))</formula>
+            <formula part='day'>(TO_DAYS(%3) - TO_DAYS(%2))</formula>
+            <formula part='weekday'>(TO_DAYS(%3) - TO_DAYS(%2))</formula>
+            <formula part='week'>FLOOR(((TO_DAYS(%3) - (DAYOFWEEK(%3) - 1)) - (TO_DAYS(%2) - (DAYOFWEEK(%2) - 1)))/7)</formula>
+            <!-- 3600 as it represents seconds in an hour -->
+            <formula part='hour'>((TO_DAYS(%3) - TO_DAYS(%2)) * 24 + FLOOR(TIME_TO_SEC(%3) / 3600) - FLOOR(TIME_TO_SEC(%2) / 3600))</formula>
+            <!-- 1440 as it represents minutes in a day -->
+            <formula part='minute'>((TO_DAYS(%3) - TO_DAYS(%2)) * 1440 + FLOOR(TIME_TO_SEC(%3) / 60) - FLOOR(TIME_TO_SEC(%2) / 60))</formula>
+            <!-- 86400 as represents seconds in a day -->
+            <formula part='second'>((TO_DAYS(%3) - TO_DAYS(%2)) * 86400 + (TIME_TO_SEC(%3) - TIME_TO_SEC(%2)))</formula>
+            <argument type='localstr' />
+            <argument type='datetime' />
+            <argument type='datetime' />
+        </date-function>
+        <date-function name='DATEDIFF' return-type='int'>
+            <formula part='week'>FLOOR((( TO_DAYS(%3) - ((7 + DAYOFWEEK(%3) - 2) % 7)) - (TO_DAYS(%2) - ((7 + DAYOFWEEK(%2) - 2) % 7) ) )/7)</formula>
+            <argument type='localstr' />
+            <argument type='datetime' />
+            <argument type='datetime' />
+            <argument type='localstr' />
+        </date-function>
+        <date-function name='DATENAME' return-type='str'>
+            <formula part='year'>YEAR(%2)</formula>
+            <formula part='quarter'>QUARTER(%2)</formula>
+            <formula part='month'>MONTH(%2)</formula>
+            <formula part='dayofyear'>DAYOFYEAR(%2)</formula>
+            <formula part='day'>DAYOFMONTH(%2)</formula>
+            <formula part='weekday'>DAYNAME(%2)</formula>
+            <formula part='week'>FLOOR((7 + DAYOFYEAR(%2) - 1 + DAYOFWEEK(DATE_FORMAT(%2, '%Y-01-01 00:00:00')) - 1) / 7)</formula>
+            <formula part='hour'>HOUR(%2)</formula>
+            <formula part='minute'>MINUTE(%2)</formula>
+            <formula part='second'>SECOND(%2)</formula>
+            <argument type='localstr' />
+            <argument type='datetime' />
+        </date-function>
+        <date-function name='DATENAME' return-type='str'>
+            <formula part='week'>FLOOR((7 + DAYOFYEAR(%2) - 1 + ((7 + DAYOFWEEK(DATE_FORMAT(%2, '%Y-01-01 00:00:00')) - 2) % 7) ) / 7)</formula>
+            <argument type='localstr' />
+            <argument type='datetime' />
+            <argument type='localstr' />
+       </date-function>
+       <date-function name='DATETRUNC' return-type='datetime'>
+            <formula part='year'>DATE_FORMAT( %2, &apos;%Y-01-01 00:00:00&apos; )</formula>
+            <formula part='quarter'>CONCAT(DATE_FORMAT(%2, '%Y-'), CONCAT(CAST((3*(QUARTER(%2)-1)+1) AS STRING), '-01 00:00:00'))</formula>
+            <formula part='month'>DATE_FORMAT( %2, &apos;%Y-%m-01 00:00:00&apos; )</formula>
+            <formula part='dayofyear'>DATE_FORMAT( %2, &apos;%Y-%m-%d 00:00:00&apos; )</formula>
+            <formula part='day'>DATE_FORMAT( %2, &apos;%Y-%m-%d 00:00:00&apos; )</formula>
+            <formula part='weekday'>DATE_FORMAT( %2, &apos;%Y-%m-%d 00:00:00&apos; )</formula>
+            <formula part='week'>FROM_DAYS( TO_DAYS(%2) - (DAYOFWEEK(%2) - 1))</formula>
+            <formula part='hour'>DATE_FORMAT( %2, &apos;%Y-%m-%d %H:00:00&apos; )</formula>
+            <formula part='minute'>DATE_FORMAT( %2, &apos;%Y-%m-%d %H:%i:00&apos; )</formula>
+            <formula part='second'>DATE_FORMAT( %2, &apos;%Y-%m-%d %H:%i:%s&apos; )</formula>
+            <argument type='localstr' />
+            <argument type='datetime' />
+        </date-function>
+        <date-function name='DATETRUNC' return-type='datetime'>
+            <formula part='week'>FROM_DAYS( TO_DAYS(%2) - ((7 + DAYOFWEEK(%2) - 2) % 7) )</formula>
+            <argument type='localstr' />
+            <argument type='datetime' />
+            <argument type='localstr' />
+        </date-function>
+
+        <remove-function name='FINDNTH'>
+            <argument type='str' />
+            <argument type='str' />
+            <argument type='real' />        
+        </remove-function>
+
+        <remove-function name='DATEPARSE'>
+            <argument type='localstr' />
+            <argument type='str' />
+        </remove-function>
+        <remove-function name='ISDATE'>
+            <argument type='str' />
+        </remove-function>
+
+        <remove-function name='USEC_TO_TIMESTAMP'>
+            <argument type='int' />
+        </remove-function>
+
+        <remove-function name='TIMESTAMP_TO_USEC'>
+            <argument type='datetime' />
+        </remove-function>
+
+        <remove-function name='MAX'>
+            <argument type='str' />
+        </remove-function>
+        <remove-function name='MAX'>
+            <argument type='str' />
+            <argument type='str' />
+        </remove-function>
+
+        <remove-function name='SPACE'>
+            <argument type='int' />
+        </remove-function>
+
+        <remove-function name='MIN'>
+            <argument type='str' />
+        </remove-function>
+        <remove-function name='MIN'>
+            <argument type='str' />
+            <argument type='str' />
+        </remove-function>
+   </function-map>
+</dialect>
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
new file mode 100644
index 00000000000..20c99b96be0
--- /dev/null
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
@@ -0,0 +1,53 @@
+<?xml version='1.0' encoding='utf-8' ?>
+
+<connector-plugin class='opensearch_jdbc' superclass='jdbc' plugin-version='1.1.0.0' name='OpenSearch' version='18.1' min-version-tableau='2021.1'>
+  <vendor-information>
+      <company name="OpenSearch for ES"/>
+      <support-link url="https://github.com/opensearch-project/sql"/>
+  </vendor-information>
+  <connection-customization class="opensearch_jdbc" enabled="true" version="10.0">
+    <vendor name="OpenSearch JDBC"/>
+    <driver name="SQL"/>
+    <customizations>
+      <customization name="CAP_CREATE_TEMP_TABLES" value="no"/>
+      <customization name="CAP_SUPPRESS_DISCOVERY_QUERIES" value="yes" />
+      <customization name="CAP_SELECT_INTO" value="no"/>
+      <customization name="CAP_SELECT_TOP_INTO" value="no"/>
+      <customization name="CAP_QUERY_BOOLEXPR_TO_INTEXPR" value="yes"/>
+      <customization name="CAP_QUERY_GROUP_BY_ALIAS" value="yes"/>
+      <customization name="CAP_QUERY_GROUP_BY_BOOL" value="yes"/>
+      <customization name="CAP_QUERY_GROUP_BY_DEGREE" value="no"/>
+      <customization name="CAP_QUERY_SORT_BY" value="yes"/>
+      <customization name="CAP_QUERY_SUBQUERIES" value="yes"/>
+      <customization name="CAP_QUERY_TOP_N" value="no"/>
+      <customization name="CAP_QUERY_SUPPORT_EMPTY_GROUPBY" value="no"/>
+      <customization name="CAP_QUERY_WHERE_FALSE_METADATA" value="yes"/>
+      <customization name="CAP_QUERY_SUBQUERIES_WITH_TOP" value="yes"/>
+      <customization name="CAP_SUPPORTS_SPLIT_FROM_LEFT" value="yes"/>
+      <customization name="CAP_SUPPORTS_SPLIT_FROM_RIGHT" value="yes"/>
+      <customization name="CAP_QUERY_ALLOW_PARTIAL_AGGREGATION" value="no"/>
+      <customization name="CAP_QUERY_TIME_REQUIRES_CAST" value="yes"/>
+      <customization name="CAP_JDBC_METADATA_USE_RESULTSET_FOR_TABLE" value="yes"/>
+      <customization name="CAP_JDBC_METADATA_GET_INDEX_INFO" value="no"/>
+      <customization name="CAP_JDBC_METADATA_IGNORE_NULLABILITY" value="yes"/>
+      <customization name="CAP_JDBC_METADATA_READ_FOREIGNKEYS" value="no"/>
+      <customization name="CAP_JDBC_METADATA_READ_PRIMARYKEYS" value="no"/>
+      <customization name="CAP_JDBC_SUPPRESS_ENUMERATE_DATABASES" value="yes"/>
+      <customization name="CAP_JDBC_SUPPRESS_ENUMERATE_SCHEMAS" value="yes"/>
+      <!-- OpenSearch SQL can't proceed queries longer than ~1.5k. This setting could help to avoid this limitation. It limits the max length of the string, not of the query. -->
+      <customization name="CAP_JDBC_MAX_STRING_LENGTH_MEDIUM" value="yes"/>
+      <customization name="CAP_CONNECT_STORED_PROCEDURE" value="no"/>
+      <customization name="CAP_SUPPORTS_UNION" value="no"/>
+      <!-- 
+      CAP_SUPPRESS_GET_SERVER_TIME will fix the error while creating extract in tableau.
+      This can be removed when OpenSearch supports query without FROM clause.
+      For smore details: https://community.tableau.com/message/1092123?et=watches.email.thread#1092123
+      -->
+      <customization name="CAP_SUPPRESS_GET_SERVER_TIME" value="yes"/>
+    </customizations>
+  </connection-customization>
+  <connection-fields file="connection-fields.xml" />
+  <connection-metadata file='connection-metadata.xml'/>
+  <connection-resolver file="connectionResolver.tdr"/>
+  <dialect file='dialect.tdd'/>
+</connector-plugin>
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/opensearch_sql_jdbc_dev.taco b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/opensearch_sql_jdbc_dev.taco
new file mode 100644
index 0000000000000000000000000000000000000000..590a4ba3885a92283c35fbc65b7785be5b64837b
GIT binary patch

From 952ff012124d97244e1404b82976122adec4289b Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Thu, 18 Nov 2021 09:37:41 -0800
Subject: [PATCH 02/28] Added CEILING and FLOOR functions

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../src/TableauConnector/opensearch_sql_jdbc/dialect.tdd  | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index f33f42444e5..73cc10a08cb 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -174,6 +174,14 @@
             <argument type='datetime' />
             <argument type='datetime' />
         </function>
+        <function group='numeric' name='CEILING' return-type='int'>
+            <formula>CEIL(%1)</formula>
+            <argument type='real' />
+        </function>
+        <function group='numeric' name='FLOOR' return-type='int'>
+            <formula>FLOOR(%1)</formula>
+            <argument type='real' />
+        </function>
     
         <function group='date' name='DAYOFYEAR' return-type='int'>
             <formula>DAY_OF_YEAR(%1)</formula>

From 580e1affc3440bb10dfca6813b8ebe1b943b2bee Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Thu, 18 Nov 2021 10:52:07 -0800
Subject: [PATCH 03/28] Added IFNULL function

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../src/TableauConnector/opensearch_sql_jdbc/dialect.tdd    | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 73cc10a08cb..ebf73c7eff4 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -33,6 +33,12 @@
             <argument type='datetime' />
         </function>
 
+        <function group='logical' name='IFNULL' return-type='datetime'>
+            <formula>CASE WHEN ISNULL(%1) THEN CAST(DATE_FORMAT(%2, &apos;%Y-%m-%d 00:00:00&apos;) AS TIMESTAMP) ELSE %1 END</formula>
+            <argument type='datetime' />
+            <argument type='date' />
+        </function>
+
         <function group='operator' name='!=' return-type='bool'>
             <formula>(%1 AND NOT %2 OR NOT %1 AND %2)</formula>
             <argument type='bool' />

From a4d2c0c7e6207ea9f7e0557aded792470db1ff83 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Thu, 18 Nov 2021 15:17:11 -0800
Subject: [PATCH 04/28] Added Kyle's fix for ADDDATE and SUBDATE with resulting
 00:00:00 being unexpectedly null

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../org/opensearch/jdbc/types/TimestampType.java    | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
index 3ae9463ea41..3f80eff0c71 100644
--- a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
+++ b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
@@ -8,6 +8,7 @@
 
 import java.sql.SQLException;
 import java.sql.Timestamp;
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.Calendar;
 import java.util.Map;
@@ -78,13 +79,17 @@ else if (value.charAt(23) == '+' || value.charAt(23) == '-') {
                 }
             }
 
-            if (calendar == null) {
-                return Timestamp.valueOf(value);
+            final Timestamp ts;
+            if (value.length() < 11) {
+                ts = Timestamp.valueOf(LocalDate.parse(value).atStartOfDay());
             } else {
-                Timestamp ts = Timestamp.valueOf(value);
-                return localDateTimeToTimestamp(ts.toLocalDateTime(), calendar);
+                ts = Timestamp.valueOf(value);
             }
 
+            if (calendar == null) {
+                return ts;
+            }
+            return localDateTimeToTimestamp(ts.toLocalDateTime(), calendar);
         } catch (IllegalArgumentException iae) {
             throw stringConversionException(value, iae);
         }

From 10aba05b3d0949e0cb7c6d9f93445a6383a0151c Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Thu, 18 Nov 2021 15:41:08 -0800
Subject: [PATCH 05/28] Added MIN and MAX for two string arguments

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../opensearch_sql_jdbc/dialect.tdd           | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index ebf73c7eff4..406a639dbb2 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -156,6 +156,14 @@
             <argument type='datetime' />
             <argument type='datetime' />
         </function>
+        <function group='numeric' name='MAX' return-type='str'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &gt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='str' />
+            <argument type='str' />
+        </function>
         <function group='numeric' name='MIN' return-type='int'>
             <formula>CASE WHEN ISNULL(%1) THEN NULL
                 WHEN ISNULL(%2) THEN NULL
@@ -180,6 +188,14 @@
             <argument type='datetime' />
             <argument type='datetime' />
         </function>
+        <function group='numeric' name='MIN' return-type='str'>
+            <formula>CASE WHEN ISNULL(%1) THEN NULL
+                WHEN ISNULL(%2) THEN NULL
+	            WHEN %1 &lt; %2 THEN %1
+                ELSE %2 END</formula>
+            <argument type='str' />
+            <argument type='str' />
+        </function>
         <function group='numeric' name='CEILING' return-type='int'>
             <formula>CEIL(%1)</formula>
             <argument type='real' />
@@ -340,24 +356,8 @@
             <argument type='datetime' />
         </remove-function>
 
-        <remove-function name='MAX'>
-            <argument type='str' />
-        </remove-function>
-        <remove-function name='MAX'>
-            <argument type='str' />
-            <argument type='str' />
-        </remove-function>
-
         <remove-function name='SPACE'>
             <argument type='int' />
         </remove-function>
-
-        <remove-function name='MIN'>
-            <argument type='str' />
-        </remove-function>
-        <remove-function name='MIN'>
-            <argument type='str' />
-            <argument type='str' />
-        </remove-function>
    </function-map>
 </dialect>

From fa32866aa98a673c86f5d682a3a711f1db204e27 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Thu, 18 Nov 2021 19:40:24 -0800
Subject: [PATCH 06/28] Fixed return type for MID function redefenitions, part
 of AOS-202

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 .../TableauConnector/opensearch_sql_jdbc/dialect.tdd | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 73cc10a08cb..2b20aa37c8e 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -196,35 +196,35 @@
             <argument type='date' />
         </function>
 
-        <function group='string' name='MID' return-type='int'>
+        <function group='string' name='MID' return-type='str'>
             <formula>SUBSTR(%1,%2)</formula>
             <argument type='str' />
             <argument type='int' />
         </function>
-        <function group='string' name='MID' return-type='int'>
+        <function group='string' name='MID' return-type='str'>
             <formula>SUBSTR(%1,CAST(%2 as int))</formula>
             <argument type='str' />
             <argument type='real' />
         </function>
-        <function group='string' name='MID' return-type='int'>
+        <function group='string' name='MID' return-type='str'>
             <formula>SUBSTR(%1,%2,%3)</formula>
             <argument type='str' />
             <argument type='int' />
             <argument type='int' />
         </function>
-        <function group='string' name='MID' return-type='int'>
+        <function group='string' name='MID' return-type='str'>
             <formula>SUBSTR(%1,CAST(%2 as int),%3)</formula>
             <argument type='str' />
             <argument type='real' />
             <argument type='int' />
         </function>
-        <function group='string' name='MID' return-type='int'>
+        <function group='string' name='MID' return-type='str'>
             <formula>SUBSTR(%1,%2,CAST(%3 as int))</formula>
             <argument type='str' />
             <argument type='int' />
             <argument type='real' />
         </function>
-        <function group='string' name='MID' return-type='int'>
+        <function group='string' name='MID' return-type='str'>
             <formula>SUBSTR(%1,CAST(%2 as int),CAST(%3 as int))</formula>
             <argument type='str' />
             <argument type='real' />

From b852f9d4ce0f511edf270909cc76ea2f725885eb Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Fri, 19 Nov 2021 11:39:55 -0800
Subject: [PATCH 07/28] Added CAST functions to convert to int or string as
 part of AOS-202

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 .../opensearch_sql_jdbc/dialect.tdd           | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 73cc10a08cb..81708f3d050 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -32,6 +32,30 @@
             <formula>TO_DAYS(%1) - 693961.0</formula>
             <argument type='datetime' />
         </function>
+        <function group='cast' name='STR' return-type='str'>
+            <formula>CAST(%1 as string)</formula>
+            <argument type='real' />
+        </function>
+        <function group='cast' name='STR' return-type='str'>
+            <formula>CAST(%1 as string)</formula>
+            <argument type='int' />
+        </function>
+        <function group='cast' name='STR' return-type='str'>
+            <formula>CAST(%1 as string)</formula>
+            <argument type='date' />
+        </function>
+        <function group='cast' name='STR' return-type='str'>
+            <formula>CAST(%1 as string)</formula>
+            <argument type='bool' />
+        </function>
+        <function group='cast' name='INT' return-type='int'>
+            <formula>CAST(%1 as int)</formula>
+            <argument type='real' />
+        </function>
+        <function group='cast' name='INT' return-type='int'>
+            <formula>CAST(%1 as int)</formula>
+            <argument type='bool' />
+        </function>
 
         <function group='operator' name='!=' return-type='bool'>
             <formula>(%1 AND NOT %2 OR NOT %1 AND %2)</formula>

From 65437b203f9bcd246083959445f03aaf08d5fe7c Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Fri, 19 Nov 2021 17:29:38 -0800
Subject: [PATCH 08/28] Added HEXBINX and HEXBINY functions from the templace
 without any modifications

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 .../TableauConnector/opensearch_sql_jdbc/dialect.tdd | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 73cc10a08cb..1ca6fe71826 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -182,7 +182,17 @@
             <formula>FLOOR(%1)</formula>
             <argument type='real' />
         </function>
-    
+        <function group='numeric' name='HEXBINX' return-type='real'>
+            <formula>(((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) - (CASE WHEN ((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) &gt; 0.0) THEN 3.0 ELSE 0.0 END)) + (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))</formula>
+            <argument type='real' />
+            <argument type='real' />
+        </function>
+        <function group='numeric' name='HEXBINY' return-type='real'>
+            <formula>CAST( (((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) - (CASE WHEN ((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) &gt; 0.0) THEN SQRT(3.0) ELSE 0.0 END)) + (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0))) AS NUMERIC(18,3) )</formula>
+            <argument type='real' />
+            <argument type='real' />
+        </function>
+
         <function group='date' name='DAYOFYEAR' return-type='int'>
             <formula>DAY_OF_YEAR(%1)</formula>
             <argument type='date' />

From 2e50a43b339f4b0f92feea29e162047ebdcfca36 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Fri, 19 Nov 2021 17:35:22 -0800
Subject: [PATCH 09/28] Fixed cast to use the OSSQL type

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 1ca6fe71826..599664b3901 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -183,12 +183,12 @@
             <argument type='real' />
         </function>
         <function group='numeric' name='HEXBINX' return-type='real'>
-            <formula>(((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) - (CASE WHEN ((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) &gt; 0.0) THEN 3.0 ELSE 0.0 END)) + (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))</formula>
+            <formula>(((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) - (CASE WHEN ((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) &gt; 0.0) THEN 3.0 ELSE 0.0 END)) + (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))</formula>
             <argument type='real' />
             <argument type='real' />
         </function>
         <function group='numeric' name='HEXBINY' return-type='real'>
-            <formula>CAST( (((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) - (CASE WHEN ((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS NUMERIC(18, 0) ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) &gt; 0.0) THEN SQRT(3.0) ELSE 0.0 END)) + (CAST( ( (%2) / SQRT(3.0) ) AS NUMERIC(18, 0) ) * SQRT(3.0))) AS NUMERIC(18,3) )</formula>
+            <formula>CAST( (((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) - (CASE WHEN ((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) &gt; 0.0) THEN SQRT(3.0) ELSE 0.0 END)) + (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0))) AS NUMERIC(18,3) )</formula>
             <argument type='real' />
             <argument type='real' />
         </function>

From 177d132ef0a5a3a7f291faa61e1626925c482163 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Fri, 19 Nov 2021 17:37:09 -0800
Subject: [PATCH 10/28] Added parenthesis to avoid
 opensearch-project/sql/issues/293

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 599664b3901..107b0fcfed4 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -183,12 +183,12 @@
             <argument type='real' />
         </function>
         <function group='numeric' name='HEXBINX' return-type='real'>
-            <formula>(((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) - (CASE WHEN ((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN 1.5 ELSE 0.0 END) &gt; 0.0) THEN 3.0 ELSE 0.0 END)) + (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))</formula>
+            <formula>(((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0)) &gt; 0.0 THEN 1.5 ELSE 0.0 END) - (CASE WHEN ((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0)) &gt; 0.0 THEN 1.5 ELSE 0.0 END) &gt; 0.0) THEN 3.0 ELSE 0.0 END)) + (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))</formula>
             <argument type='real' />
             <argument type='real' />
         </function>
         <function group='numeric' name='HEXBINY' return-type='real'>
-            <formula>CAST( (((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) - (CASE WHEN ((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) &gt; 0.0) THEN SQRT(3.0) ELSE 0.0 END)) + (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0))) AS NUMERIC(18,3) )</formula>
+            <formula>ROUND( (((CASE WHEN (ABS((%2) - (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (ROUND( ( (%1) / 3.0 ), 0 ) * 3.0))) - 1.0)) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) - (CASE WHEN ((%2) - (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0)) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (ROUND( ( (%1) / 3.0 ), 0 ) * 3.0))) - 1.0)) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) &gt; 0.0) THEN SQRT(3.0) ELSE 0.0 END)) + (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0))), 3)</formula>
             <argument type='real' />
             <argument type='real' />
         </function>

From f212e35b7acb025421073b6f3117490a015e1838 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Mon, 22 Nov 2021 12:18:51 -0800
Subject: [PATCH 11/28] Modified Timestamp conversion formula

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 406a639dbb2..e85feb33ab1 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -34,7 +34,7 @@
         </function>
 
         <function group='logical' name='IFNULL' return-type='datetime'>
-            <formula>CASE WHEN ISNULL(%1) THEN CAST(DATE_FORMAT(%2, &apos;%Y-%m-%d 00:00:00&apos;) AS TIMESTAMP) ELSE %1 END</formula>
+            <formula>CASE WHEN ISNULL(%1) THEN SUBDATE(TIMESTAMP(%2), INTERVAL HOUR(TIMESTAMP(%2)) HOUR) ELSE %1 END</formula>
             <argument type='datetime' />
             <argument type='date' />
         </function>

From 385a41bb6d9d54b85524b5d4c0ea20393962c5f3 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Tue, 23 Nov 2021 11:10:37 -0800
Subject: [PATCH 12/28] Added comment to TimestampType

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../src/main/java/org/opensearch/jdbc/types/TimestampType.java   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
index 3f80eff0c71..4dcd94ae74f 100644
--- a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
+++ b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
@@ -80,6 +80,7 @@ else if (value.charAt(23) == '+' || value.charAt(23) == '-') {
             }
 
             final Timestamp ts;
+            // 11 to check if the value is in yyyy-MM-dd format
             if (value.length() < 11) {
                 ts = Timestamp.valueOf(LocalDate.parse(value).atStartOfDay());
             } else {

From 26dbb7e6bd0bb781429a34256d4613f1efd49902 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Tue, 23 Nov 2021 15:40:39 -0800
Subject: [PATCH 13/28] Updated Company Name accroding to the customer's
 request

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
index 20c99b96be0..45bacf0ac85 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
@@ -2,7 +2,7 @@
 
 <connector-plugin class='opensearch_jdbc' superclass='jdbc' plugin-version='1.1.0.0' name='OpenSearch' version='18.1' min-version-tableau='2021.1'>
   <vendor-information>
-      <company name="OpenSearch for ES"/>
+      <company name="OpenSearch Project"/>
       <support-link url="https://github.com/opensearch-project/sql"/>
   </vendor-information>
   <connection-customization class="opensearch_jdbc" enabled="true" version="10.0">

From 4c63b64e3988dfe6a61a43c844a93d92b7286037 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Wed, 24 Nov 2021 11:41:12 -0800
Subject: [PATCH 14/28] Updated Vendor Name as well

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
index 45bacf0ac85..55c64830b97 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
@@ -6,7 +6,7 @@
       <support-link url="https://github.com/opensearch-project/sql"/>
   </vendor-information>
   <connection-customization class="opensearch_jdbc" enabled="true" version="10.0">
-    <vendor name="OpenSearch JDBC"/>
+    <vendor name="OpenSearch Project"/>
     <driver name="SQL"/>
     <customizations>
       <customization name="CAP_CREATE_TEMP_TABLES" value="no"/>

From 3f3fa1f85f10e643c2e73afb4d2ce7e98491b2d2 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Tue, 30 Nov 2021 18:32:09 -0800
Subject: [PATCH 15/28] Added few small changes to simplify connector
 developing and debugging

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 .../src/PowerBIConnector/SqlOdbcPBIConnector.mproj   |  2 ++
 sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq | 12 ++++++++----
 .../PowerBIConnector/SqlOdbcPBIConnector.query.pq    |  5 ++---
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.mproj b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.mproj
index b2b177c461f..53dff961de6 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.mproj
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.mproj
@@ -98,6 +98,8 @@
             archiveOut.CreateEntryFromFile(fullPath, filename, CompressionLevel.Optimal);
         }
     }
+
+    File.Copy(OutputFile, Path.Combine(Environment.GetEnvironmentVariable("USERPROFILE"), @"Documents\Power BI Desktop\Custom Connectors", Path.GetFileName(OutputFile)), true);
 ]]></Code>
     </Task>
   </UsingTask>
diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
index ba10c39e494..0a4bbf09eb4 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
@@ -106,8 +106,8 @@ SqlOdbcPBIConnectorImpl = (Server as text) as table =>
             SupportsOdbcTimestampLiterals = true
         ]),
 
-        OdbcDatasource = Odbc.DataSource(ConnectionString & CredentialConnectionString & EncryptedConnectionString, [
-            // Do not view the tables grouped by their schema names.
+        OdbcOptions = [
+             // Do not view the tables grouped by their schema names.
             HierarchicalNavigation = false,
             // Prevents execution of native SQL statements. Extensions should set this to true.
             HideNativeQuery = true,
@@ -129,7 +129,11 @@ SqlOdbcPBIConnectorImpl = (Server as text) as table =>
 
             // Connection string properties used for encrypted connections.
             CredentialConnectionString = EncryptedConnectionString
-        ])
+        ],
+
+        FullConnectionString = Diagnostics.LogValue("Connection String", ConnectionString & CredentialConnectionString & EncryptedConnectionString),
+
+        OdbcDatasource = Odbc.DataSource(FullConnectionString, OdbcOptions)
     in
         OdbcDatasource;
 
@@ -206,7 +210,7 @@ SqlOdbcPBIConnector.Publish = [
     LearnMoreUrl = "https://www.opensearch.org/",
     
     // Disabling direct query due to limited SQL query support
-    SupportsDirectQuery = false,
+    SupportsDirectQuery = true,
 
     SourceImage = SqlOdbcPBIConnector.Icons,
     SourceTypeImage = SqlOdbcPBIConnector.Icons
diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
index bde4c98a34e..51fe5f5aae8 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
@@ -4,15 +4,14 @@ section SqlOdbcPBIConnector.UnitTests;
 shared MyExtension.UnitTest =
 [
     // Common variables for all tests
-    Host = "localhost",
-    Port = 9200,
+    Host = "localhost:9200"
 
     facts =
     {        
         Fact("Connection Test",  
              7,                                    
              let
-                Source = SqlOdbcPBIConnector.Contents(Host,Port),
+                Source = SqlOdbcPBIConnector.Contents(Host),
                 no_of_columns = Table.ColumnCount(Source)
              in
                 no_of_columns                

From 6f046dc5f19676460f9b61e230f7ef38da4b5ae6 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Tue, 30 Nov 2021 18:36:22 -0800
Subject: [PATCH 16/28] Typo fix

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
index 51fe5f5aae8..8ffb05f1fd0 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
@@ -4,7 +4,7 @@ section SqlOdbcPBIConnector.UnitTests;
 shared MyExtension.UnitTest =
 [
     // Common variables for all tests
-    Host = "localhost:9200"
+    Host = "localhost:9200",
 
     facts =
     {        

From f529282674497de7a6cb1261fe5a4e229bece63f Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Tue, 30 Nov 2021 20:43:05 -0800
Subject: [PATCH 17/28] Added a simple test from TDVT: case bool0 from test
 calcs_data (an expression test) Some mofidication were made in the test
 framework to make the output more readable

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 .../SqlOdbcPBIConnector.query.pq              | 23 ++++++++++++++-----
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
index bde4c98a34e..8352609f650 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
@@ -4,18 +4,27 @@ section SqlOdbcPBIConnector.UnitTests;
 shared MyExtension.UnitTest =
 [
     // Common variables for all tests
-    Host = "localhost",
-    Port = 9200,
+    Host = "localhost:9200",
 
     facts =
     {        
         Fact("Connection Test",  
              7,                                    
              let
-                Source = SqlOdbcPBIConnector.Contents(Host,Port),
+                Source = SqlOdbcPBIConnector.Contents(Host),
                 no_of_columns = Table.ColumnCount(Source)
              in
                 no_of_columns                
+        ),
+        Fact("calcs_data:bool0",
+            #table(type table [bool0 = logical],
+                { {null}, {false}, {true} }),
+            let
+                Source = SqlOdbcPBIConnector.Contents("localhost:9200"),
+                calcs_null_null = Source{[Item="calcs",Schema=null,Catalog=null]}[Data],
+                grouped = Table.Group(calcs_null_null, {"bool0"}, {})
+            in
+                grouped
         )
     },
 
@@ -33,11 +42,13 @@ Fact = (_subject as text, _expected, _actual) as record =>
     resultOp = if result = "Success ✓" then " = " else " <> ",
     addendumEvalAttempt = if attempt[HasError] then @ValueToText(attempt[Error]) else "",
     addendumEvalExpected = try @ValueToText(safeExpected) otherwise "...",
-    addendumEvalActual = try @ValueToText (safeActual) otherwise "...",
+    addendumEvalActual = try @ValueToText(safeActual) otherwise "...",
+    ShortenedAddendumEvalExpected = if Text.Length(addendumEvalExpected) > 20 then Text.Range(addendumEvalExpected, 0, 20) & "..." else addendumEvalExpected,
+    ShortenedAddendumEvalActual = if Text.Length(addendumEvalActual) > 20 then Text.Range(addendumEvalActual, 0, 20) & "..." else addendumEvalActual,
     fact =
-    [   Result = result &" "& addendumEvalAttempt,
+    [   Result = result & " " & addendumEvalAttempt,
         Notes =_subject,
-        Details = " ("& addendumEvalExpected & resultOp & addendumEvalActual &")"
+        Details = ShortenedAddendumEvalExpected & resultOp & ShortenedAddendumEvalActual
     ]
 ][fact];
 

From b21535742f322bbab11f898c6da7ec1dcf53d82a Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Fri, 3 Dec 2021 16:53:19 -0800
Subject: [PATCH 18/28] Modified the driver to recognize its support for
 conversion of types

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../PowerBIConnector/SqlOdbcPBIConnector.pq   |  2 +-
 .../SqlOdbcPBIConnector.query.pq              | 27 ++++++++++--
 sql-odbc/src/sqlodbc/info.c                   | 42 +++++++++++++++----
 3 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
index ba10c39e494..23655caefb7 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
@@ -206,7 +206,7 @@ SqlOdbcPBIConnector.Publish = [
     LearnMoreUrl = "https://www.opensearch.org/",
     
     // Disabling direct query due to limited SQL query support
-    SupportsDirectQuery = false,
+    SupportsDirectQuery = true,
 
     SourceImage = SqlOdbcPBIConnector.Icons,
     SourceTypeImage = SqlOdbcPBIConnector.Icons
diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
index bde4c98a34e..df4e0163c56 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
@@ -16,6 +16,23 @@ shared MyExtension.UnitTest =
                 no_of_columns = Table.ColumnCount(Source)
              in
                 no_of_columns                
+        ),
+        Fact("calcs_data:bool0",
+            #table(type table [bool0 = logical],
+                { {null}, {false}, {true} }),
+            let
+                Source = SqlOdbcPBIConnector.Contents("localhost:9200"),
+                calcs_null_null = Source{[Item="calcs",Schema=null,Catalog=null]}[Data],
+                grouped = Table.Group(calcs_null_null, {"bool0"}, {})
+            in
+                grouped
+        ),
+         Fact("Integer test",  
+             {1,null,null,null,7,3,8,null,null,8,4,10,null,4,11,4,8},              
+             let 
+                calcs = Source{[Item="calcs",Schema=null,Catalog=null]}[Data]
+             in
+                Table.SelectColumns(calcs, "int0")        
         )
     },
 
@@ -33,11 +50,13 @@ Fact = (_subject as text, _expected, _actual) as record =>
     resultOp = if result = "Success ✓" then " = " else " <> ",
     addendumEvalAttempt = if attempt[HasError] then @ValueToText(attempt[Error]) else "",
     addendumEvalExpected = try @ValueToText(safeExpected) otherwise "...",
-    addendumEvalActual = try @ValueToText (safeActual) otherwise "...",
+    addendumEvalActual = try @ValueToText(safeActual) otherwise "...",
+    ShortenedAddendumEvalExpected = if Text.Length(addendumEvalExpected) > 20 then Text.Range(addendumEvalExpected, 0, 20) & "..." else addendumEvalExpected,
+    ShortenedAddendumEvalActual = if Text.Length(addendumEvalActual) > 20 then Text.Range(addendumEvalActual, 0, 20) & "..." else addendumEvalActual,
     fact =
-    [   Result = result &" "& addendumEvalAttempt,
+    [   Result = result & " " & addendumEvalAttempt,
         Notes =_subject,
-        Details = " ("& addendumEvalExpected & resultOp & addendumEvalActual &")"
+        Details = ShortenedAddendumEvalExpected & resultOp & ShortenedAddendumEvalActual
     ]
 ][fact];
 
@@ -307,4 +326,4 @@ ValueToText = (value, optional depth) =>
                            if x is type         then try Serialize.Type(x) otherwise "null /*serialize failed*/"          else 
                            "[#_unable_to_serialize_#]"                     
     in
-        try Serialize(value) otherwise "<serialization failed>";
+        try Serialize(value) otherwise "<serialization failed>";
\ No newline at end of file
diff --git a/sql-odbc/src/sqlodbc/info.c b/sql-odbc/src/sqlodbc/info.c
index fc859a0d9eb..f23d3a17e1f 100644
--- a/sql-odbc/src/sqlodbc/info.c
+++ b/sql-odbc/src/sqlodbc/info.c
@@ -104,20 +104,14 @@ RETCODE SQL_API OPENSEARCHAPI_GetInfo(HDBC hdbc, SQLUSMALLINT fInfoType,
             break;
 
         case SQL_CONVERT_GUID:
-        case SQL_CONVERT_INTEGER:
         case SQL_CONVERT_SMALLINT:
         case SQL_CONVERT_TINYINT:
-        case SQL_CONVERT_BIT:
         case SQL_CONVERT_VARCHAR:
-        case SQL_CONVERT_BIGINT:
         case SQL_CONVERT_DECIMAL:
-        case SQL_CONVERT_DOUBLE:
         case SQL_CONVERT_FLOAT:
         case SQL_CONVERT_NUMERIC:
-        case SQL_CONVERT_REAL:
         case SQL_CONVERT_DATE:
         case SQL_CONVERT_TIME:
-        case SQL_CONVERT_TIMESTAMP:
         case SQL_CONVERT_BINARY:
         case SQL_CONVERT_LONGVARBINARY:
         case SQL_CONVERT_VARBINARY: /* ODBC 1.0 */
@@ -126,12 +120,46 @@ RETCODE SQL_API OPENSEARCHAPI_GetInfo(HDBC hdbc, SQLUSMALLINT fInfoType,
 #ifdef UNICODE_SUPPORT
         case SQL_CONVERT_WCHAR:
         case SQL_CONVERT_WLONGVARCHAR:
-        case SQL_CONVERT_WVARCHAR:
 #endif /* UNICODE_SUPPORT */
             len = sizeof(SQLUINTEGER);
             value = 0; /* CONVERT is unavailable */
             break;
 
+        case SQL_CONVERT_INTEGER: /* ODBC 1.0 */
+            len = sizeof(SQLUINTEGER);
+            value = SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            break;
+
+        case SQL_CONVERT_BIT: /* ODBC 1.0 */
+            len = sizeof(SQLUINTEGER);
+            value = SQL_CVT_INTEGER | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            break;
+
+        case SQL_CONVERT_WVARCHAR: /* ODBC 1.0 */
+            len = sizeof(SQLUINTEGER);
+            value = SQL_CVT_INTEGER | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            break;
+
+        case SQL_CONVERT_DOUBLE: /* ODBC 1.0 */
+            len = sizeof(SQLUINTEGER);
+            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            break;
+
+        case SQL_CONVERT_BIGINT: /* ODBC 1.0 */
+            len = sizeof(SQLUINTEGER);
+            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_REAL;
+            break;
+
+        case SQL_CONVERT_REAL: /* ODBC 1.0 */
+            len = sizeof(SQLUINTEGER);
+            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT;
+            break;
+
+        case SQL_CONVERT_TIMESTAMP: /* ODBC 1.0 */
+            len = sizeof(SQLUINTEGER);
+            value = SQL_CVT_WVARCHAR;
+            break;
+
         case SQL_CONVERT_FUNCTIONS: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
             value = SQL_FN_CVT_CAST;

From b4f3e91840a3fbe7f5ee02ed34d9643a472e6edd Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Fri, 3 Dec 2021 16:59:04 -0800
Subject: [PATCH 19/28] Removed changes from a different branch

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../SqlOdbcPBIConnector.query.pq              | 27 +++----------------
 1 file changed, 4 insertions(+), 23 deletions(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
index df4e0163c56..192d3df7030 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
@@ -16,23 +16,6 @@ shared MyExtension.UnitTest =
                 no_of_columns = Table.ColumnCount(Source)
              in
                 no_of_columns                
-        ),
-        Fact("calcs_data:bool0",
-            #table(type table [bool0 = logical],
-                { {null}, {false}, {true} }),
-            let
-                Source = SqlOdbcPBIConnector.Contents("localhost:9200"),
-                calcs_null_null = Source{[Item="calcs",Schema=null,Catalog=null]}[Data],
-                grouped = Table.Group(calcs_null_null, {"bool0"}, {})
-            in
-                grouped
-        ),
-         Fact("Integer test",  
-             {1,null,null,null,7,3,8,null,null,8,4,10,null,4,11,4,8},              
-             let 
-                calcs = Source{[Item="calcs",Schema=null,Catalog=null]}[Data]
-             in
-                Table.SelectColumns(calcs, "int0")        
         )
     },
 
@@ -50,13 +33,11 @@ Fact = (_subject as text, _expected, _actual) as record =>
     resultOp = if result = "Success ✓" then " = " else " <> ",
     addendumEvalAttempt = if attempt[HasError] then @ValueToText(attempt[Error]) else "",
     addendumEvalExpected = try @ValueToText(safeExpected) otherwise "...",
-    addendumEvalActual = try @ValueToText(safeActual) otherwise "...",
-    ShortenedAddendumEvalExpected = if Text.Length(addendumEvalExpected) > 20 then Text.Range(addendumEvalExpected, 0, 20) & "..." else addendumEvalExpected,
-    ShortenedAddendumEvalActual = if Text.Length(addendumEvalActual) > 20 then Text.Range(addendumEvalActual, 0, 20) & "..." else addendumEvalActual,
+    addendumEvalActual = try @ValueToText (safeActual) otherwise "...",
     fact =
-    [   Result = result & " " & addendumEvalAttempt,
+    [   Result = result &" "& addendumEvalAttempt,
         Notes =_subject,
-        Details = ShortenedAddendumEvalExpected & resultOp & ShortenedAddendumEvalActual
+        Details = Details = " ("& addendumEvalExpected & resultOp & addendumEvalActual &")"
     ]
 ][fact];
 
@@ -326,4 +307,4 @@ ValueToText = (value, optional depth) =>
                            if x is type         then try Serialize.Type(x) otherwise "null /*serialize failed*/"          else 
                            "[#_unable_to_serialize_#]"                     
     in
-        try Serialize(value) otherwise "<serialization failed>";
\ No newline at end of file
+        try Serialize(value) otherwise "<serialization failed>";

From 431e01abfe66b5911b0b0b133bcbe6fda701014f Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Fri, 3 Dec 2021 17:00:05 -0800
Subject: [PATCH 20/28] Removed changes from a different branch

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
index 192d3df7030..bde4c98a34e 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
@@ -37,7 +37,7 @@ Fact = (_subject as text, _expected, _actual) as record =>
     fact =
     [   Result = result &" "& addendumEvalAttempt,
         Notes =_subject,
-        Details = Details = " ("& addendumEvalExpected & resultOp & addendumEvalActual &")"
+        Details = " ("& addendumEvalExpected & resultOp & addendumEvalActual &")"
     ]
 ][fact];
 

From e8dafaaddc1ee13c3bf12d29f7aae12e3488de8e Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Mon, 6 Dec 2021 11:37:28 -0800
Subject: [PATCH 21/28] Made the connector convert keyword columns to string
 columns

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../src/PowerBIConnector/SqlOdbcPBIConnector.pq     | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
index 23655caefb7..8edd090d657 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
@@ -69,12 +69,21 @@ SqlOdbcPBIConnectorImpl = (Server as text) as table =>
         SQLGetTypeInfo = (types) => 
             if (EnableTraceOutput <> true) then types else
             let
+                // SELECT CAST(1 AS KEYWORD) does not work for OpenSearch
+                // SELECT CAST(1 AS STRING) works for OpenSearch
+                FixTypeName = (typeName) =>
+                    if typeName = "keyword" then "string"
+                    else typeName,
+
                 // Outputting the entire table might be too large, and result in the value being truncated.
                 // We can output a row at a time instead with Table.TransformRows()
                 rows = Table.TransformRows(types, each Diagnostics.LogValue("SQLGetTypeInfo " & _[TYPE_NAME], _)),
-                toTable = Table.FromRecords(rows)
+                toTable = Table.FromRecords(rows),
+
+                // Override the type name of columns
+                modifiedColumns = Table.TransformColumns(toTable, {{"TYPE_NAME", FixTypeName}})
             in
-                Value.ReplaceType(toTable, Value.Type(types)),
+                Value.ReplaceType(modifiedColumns, Value.Type(types)),
 
         // SQLColumns is a function handler that receives the results of an ODBC call to SQLColumns().
         SQLColumns = (catalogName, schemaName, tableName, columnName, source) =>

From a22afaca79df2be232847201d3c7f339e918d3c7 Mon Sep 17 00:00:00 2001
From: Yury Fridlyand <yuryf@bitquilltech.com>
Date: Tue, 7 Dec 2021 12:01:26 -0800
Subject: [PATCH 22/28] Fix requested by PR review

Signed-off-by: Yury Fridlyand <yuryf@bitquilltech.com>
---
 sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
index 8352609f650..e2254d231af 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.query.pq
@@ -20,7 +20,7 @@ shared MyExtension.UnitTest =
             #table(type table [bool0 = logical],
                 { {null}, {false}, {true} }),
             let
-                Source = SqlOdbcPBIConnector.Contents("localhost:9200"),
+                Source = SqlOdbcPBIConnector.Contents(Host),
                 calcs_null_null = Source{[Item="calcs",Schema=null,Catalog=null]}[Data],
                 grouped = Table.Group(calcs_null_null, {"bool0"}, {})
             in

From 4a97b6c352672f0cae2ee276792c2b293e91aea3 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Tue, 7 Dec 2021 15:08:39 -0800
Subject: [PATCH 23/28] Modified integration tests to reflect support for
 conversion types

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../ITODBCInfo/test_odbc_info.cpp             | 21 ++++++++++++-------
 sql-odbc/src/sqlodbc/info.c                   | 14 ++++++-------
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
index b19660f7e53..f54333fcb83 100644
--- a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
+++ b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
@@ -208,20 +208,26 @@ TEST_SQL_GET_INFO_STRING(SQLCatalogName, SQL_CATALOG_NAME, L"N");
 // Conversion //
 ////////////////
 
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertInteger, SQL_CONVERT_INTEGER, 0);
+// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertInteger, SQL_CONVERT_INTEGER, 8409288);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertSmallint, SQL_CONVERT_SMALLINT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTinyint, SQL_CONVERT_TINYINT, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBit, SQL_CONVERT_BIT, 0);
+// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBit, SQL_CONVERT_BIT, 8409288);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertVarchar, SQL_CONVERT_VARCHAR, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBigint, SQL_CONVERT_BIGINT, 0);
+// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBigint, SQL_CONVERT_BIGINT, 8409288);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDecimal, SQL_CONVERT_DECIMAL, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDouble, SQL_CONVERT_DOUBLE, 0);
+// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDouble, SQL_CONVERT_DOUBLE, 8409288);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertFloat, SQL_CONVERT_FLOAT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertNumeric, SQL_CONVERT_NUMERIC, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertReal, SQL_CONVERT_REAL, 0);
+// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertReal, SQL_CONVERT_REAL, 8409288);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDate, SQL_CONVERT_DATE, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTime, SQL_CONVERT_TIME, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTimestamp, SQL_CONVERT_TIMESTAMP, 0);
+// 8519680 = 0x00820000 = SQL_CVT_TIMESTAMP | SQL_CVT_WVARCHAR
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTimestamp, SQL_CONVERT_TIMESTAMP, 8519680);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBinary, SQL_CONVERT_BINARY, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertLongvarbinary, SQL_CONVERT_LONGVARBINARY,
                             0);
@@ -231,7 +237,8 @@ TEST_SQL_GET_INFO_UINT_MASK(SQLConvertLongVarchar, SQL_CONVERT_LONGVARCHAR, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWChar, SQL_CONVERT_WCHAR, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWLongVarchar, SQL_CONVERT_WLONGVARCHAR,
                             0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWVarchar, SQL_CONVERT_WVARCHAR, 0);
+// 8405192 = 0x008040C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWVarchar, SQL_CONVERT_WVARCHAR, 8405192);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertGuid, SQL_CONVERT_GUID, 0);
 
 //////////////////////
diff --git a/sql-odbc/src/sqlodbc/info.c b/sql-odbc/src/sqlodbc/info.c
index f23d3a17e1f..1f7295502c2 100644
--- a/sql-odbc/src/sqlodbc/info.c
+++ b/sql-odbc/src/sqlodbc/info.c
@@ -127,37 +127,37 @@ RETCODE SQL_API OPENSEARCHAPI_GetInfo(HDBC hdbc, SQLUSMALLINT fInfoType,
 
         case SQL_CONVERT_INTEGER: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
             break;
 
         case SQL_CONVERT_BIT: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_INTEGER | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            value = SQL_CVT_BIT | SQL_CVT_INTEGER | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
             break;
 
         case SQL_CONVERT_WVARCHAR: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_INTEGER | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            value = SQL_CVT_WVARCHAR | SQL_CVT_INTEGER | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
             break;
 
         case SQL_CONVERT_DOUBLE: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_BIGINT | SQL_CVT_REAL;
+            value = SQL_CVT_DOUBLE | SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_BIGINT | SQL_CVT_REAL;
             break;
 
         case SQL_CONVERT_BIGINT: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_REAL;
+            value = SQL_CVT_BIGINT | SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_REAL;
             break;
 
         case SQL_CONVERT_REAL: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT;
+            value = SQL_CVT_REAL | SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT;
             break;
 
         case SQL_CONVERT_TIMESTAMP: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_WVARCHAR;
+            value = SQL_CVT_TIMESTAMP | SQL_CVT_WVARCHAR;
             break;
 
         case SQL_CONVERT_FUNCTIONS: /* ODBC 1.0 */

From f295608190729f0afb94bfbad96ca83453d78bda Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Tue, 7 Dec 2021 15:16:07 -0800
Subject: [PATCH 24/28] Removed connector changes

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../src/PowerBIConnector/SqlOdbcPBIConnector.pq   | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
index 8edd090d657..ba10c39e494 100644
--- a/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
+++ b/sql-odbc/src/PowerBIConnector/SqlOdbcPBIConnector.pq
@@ -69,21 +69,12 @@ SqlOdbcPBIConnectorImpl = (Server as text) as table =>
         SQLGetTypeInfo = (types) => 
             if (EnableTraceOutput <> true) then types else
             let
-                // SELECT CAST(1 AS KEYWORD) does not work for OpenSearch
-                // SELECT CAST(1 AS STRING) works for OpenSearch
-                FixTypeName = (typeName) =>
-                    if typeName = "keyword" then "string"
-                    else typeName,
-
                 // Outputting the entire table might be too large, and result in the value being truncated.
                 // We can output a row at a time instead with Table.TransformRows()
                 rows = Table.TransformRows(types, each Diagnostics.LogValue("SQLGetTypeInfo " & _[TYPE_NAME], _)),
-                toTable = Table.FromRecords(rows),
-
-                // Override the type name of columns
-                modifiedColumns = Table.TransformColumns(toTable, {{"TYPE_NAME", FixTypeName}})
+                toTable = Table.FromRecords(rows)
             in
-                Value.ReplaceType(modifiedColumns, Value.Type(types)),
+                Value.ReplaceType(toTable, Value.Type(types)),
 
         // SQLColumns is a function handler that receives the results of an ODBC call to SQLColumns().
         SQLColumns = (catalogName, schemaName, tableName, columnName, source) =>
@@ -215,7 +206,7 @@ SqlOdbcPBIConnector.Publish = [
     LearnMoreUrl = "https://www.opensearch.org/",
     
     // Disabling direct query due to limited SQL query support
-    SupportsDirectQuery = true,
+    SupportsDirectQuery = false,
 
     SourceImage = SqlOdbcPBIConnector.Icons,
     SourceTypeImage = SqlOdbcPBIConnector.Icons

From 284376ee2e7f84592b88b06c94eb6d9791aa4d00 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Wed, 8 Dec 2021 11:34:40 -0800
Subject: [PATCH 25/28] Change values to bitmasks

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../ITODBCInfo/test_odbc_info.cpp             | 21 +++++++------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
index f54333fcb83..69b3b4a48a8 100644
--- a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
+++ b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
@@ -208,26 +208,20 @@ TEST_SQL_GET_INFO_STRING(SQLCatalogName, SQL_CATALOG_NAME, L"N");
 // Conversion //
 ////////////////
 
-// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertInteger, SQL_CONVERT_INTEGER, 8409288);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertInteger, SQL_CONVERT_INTEGER, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertSmallint, SQL_CONVERT_SMALLINT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTinyint, SQL_CONVERT_TINYINT, 0);
-// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBit, SQL_CONVERT_BIT, 8409288);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBit, SQL_CONVERT_BIT, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertVarchar, SQL_CONVERT_VARCHAR, 0);
-// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBigint, SQL_CONVERT_BIGINT, 8409288);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBigint, SQL_CONVERT_BIGINT, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDecimal, SQL_CONVERT_DECIMAL, 0);
-// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDouble, SQL_CONVERT_DOUBLE, 8409288);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDouble, SQL_CONVERT_DOUBLE, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertFloat, SQL_CONVERT_FLOAT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertNumeric, SQL_CONVERT_NUMERIC, 0);
-// 8409288 = 0x008050C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertReal, SQL_CONVERT_REAL, 8409288);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertReal, SQL_CONVERT_REAL, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDate, SQL_CONVERT_DATE, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTime, SQL_CONVERT_TIME, 0);
-// 8519680 = 0x00820000 = SQL_CVT_TIMESTAMP | SQL_CVT_WVARCHAR
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTimestamp, SQL_CONVERT_TIMESTAMP, 8519680);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTimestamp, SQL_CONVERT_TIMESTAMP, SQL_CVT_TIMESTAMP | SQL_CVT_WVARCHAR);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBinary, SQL_CONVERT_BINARY, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertLongvarbinary, SQL_CONVERT_LONGVARBINARY,
                             0);
@@ -237,8 +231,7 @@ TEST_SQL_GET_INFO_UINT_MASK(SQLConvertLongVarchar, SQL_CONVERT_LONGVARCHAR, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWChar, SQL_CONVERT_WCHAR, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWLongVarchar, SQL_CONVERT_WLONGVARCHAR,
                             0);
-// 8405192 = 0x008040C8 = SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWVarchar, SQL_CONVERT_WVARCHAR, 8405192);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWVarchar, SQL_CONVERT_WVARCHAR, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertGuid, SQL_CONVERT_GUID, 0);
 
 //////////////////////

From 2736d1c2458fc376684802efe705f02a821f4a36 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Thu, 9 Dec 2021 14:36:15 -0800
Subject: [PATCH 26/28] Remove changes from irrelevant commits

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../opensearch_sql_jdbc/dialect.tdd           | 96 +++++--------------
 .../opensearch_sql_jdbc/manifest.xml          |  6 +-
 .../opensearch/jdbc/types/TimestampType.java  | 16 +---
 .../ITODBCInfo/test_odbc_info.cpp             | 16 ++--
 sql-odbc/src/sqlodbc/info.c                   | 44 ++-------
 5 files changed, 48 insertions(+), 130 deletions(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index f410db3e2c1..2105ac7fd21 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -32,36 +32,6 @@
             <formula>TO_DAYS(%1) - 693961.0</formula>
             <argument type='datetime' />
         </function>
-        <function group='cast' name='STR' return-type='str'>
-            <formula>CAST(%1 as string)</formula>
-            <argument type='real' />
-        </function>
-        <function group='cast' name='STR' return-type='str'>
-            <formula>CAST(%1 as string)</formula>
-            <argument type='int' />
-        </function>
-        <function group='cast' name='STR' return-type='str'>
-            <formula>CAST(%1 as string)</formula>
-            <argument type='date' />
-        </function>
-        <function group='cast' name='STR' return-type='str'>
-            <formula>CAST(%1 as string)</formula>
-            <argument type='bool' />
-        </function>
-        <function group='cast' name='INT' return-type='int'>
-            <formula>CAST(%1 as int)</formula>
-            <argument type='real' />
-        </function>
-        <function group='cast' name='INT' return-type='int'>
-            <formula>CAST(%1 as int)</formula>
-            <argument type='bool' />
-        </function>
-
-        <function group='logical' name='IFNULL' return-type='datetime'>
-            <formula>CASE WHEN ISNULL(%1) THEN SUBDATE(TIMESTAMP(%2), INTERVAL HOUR(TIMESTAMP(%2)) HOUR) ELSE %1 END</formula>
-            <argument type='datetime' />
-            <argument type='date' />
-        </function>
 
         <function group='operator' name='!=' return-type='bool'>
             <formula>(%1 AND NOT %2 OR NOT %1 AND %2)</formula>
@@ -180,14 +150,6 @@
             <argument type='datetime' />
             <argument type='datetime' />
         </function>
-        <function group='numeric' name='MAX' return-type='str'>
-            <formula>CASE WHEN ISNULL(%1) THEN NULL
-                WHEN ISNULL(%2) THEN NULL
-	            WHEN %1 &gt; %2 THEN %1
-                ELSE %2 END</formula>
-            <argument type='str' />
-            <argument type='str' />
-        </function>
         <function group='numeric' name='MIN' return-type='int'>
             <formula>CASE WHEN ISNULL(%1) THEN NULL
                 WHEN ISNULL(%2) THEN NULL
@@ -212,33 +174,7 @@
             <argument type='datetime' />
             <argument type='datetime' />
         </function>
-        <function group='numeric' name='MIN' return-type='str'>
-            <formula>CASE WHEN ISNULL(%1) THEN NULL
-                WHEN ISNULL(%2) THEN NULL
-	            WHEN %1 &lt; %2 THEN %1
-                ELSE %2 END</formula>
-            <argument type='str' />
-            <argument type='str' />
-        </function>
-        <function group='numeric' name='CEILING' return-type='int'>
-            <formula>CEIL(%1)</formula>
-            <argument type='real' />
-        </function>
-        <function group='numeric' name='FLOOR' return-type='int'>
-            <formula>FLOOR(%1)</formula>
-            <argument type='real' />
-        </function>
-        <function group='numeric' name='HEXBINX' return-type='real'>
-            <formula>(((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0)) &gt; 0.0 THEN 1.5 ELSE 0.0 END) - (CASE WHEN ((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (CAST( ( (%2) / SQRT(3.0) ) AS INT ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))) - 1.0)) &gt; 0.0 THEN 1.5 ELSE 0.0 END) &gt; 0.0) THEN 3.0 ELSE 0.0 END)) + (CAST( ( (%1) / 3.0 ) AS INT ) * 3.0))</formula>
-            <argument type='real' />
-            <argument type='real' />
-        </function>
-        <function group='numeric' name='HEXBINY' return-type='real'>
-            <formula>ROUND( (((CASE WHEN (ABS((%2) - (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (ROUND( ( (%1) / 3.0 ), 0 ) * 3.0))) - 1.0)) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) - (CASE WHEN ((%2) - (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0)) &lt; 0.0) AND ((CASE WHEN (ABS((%2) - (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0)))) + (SQRT(3.0) * ((ABS((%1) - (ROUND( ( (%1) / 3.0 ), 0 ) * 3.0))) - 1.0)) &gt; 0.0 THEN SQRT(3.0) / 2.0 ELSE 0.0 END) &gt; 0.0) THEN SQRT(3.0) ELSE 0.0 END)) + (ROUND( ( (%2) / SQRT(3.0) ), 0 ) * SQRT(3.0))), 3)</formula>
-            <argument type='real' />
-            <argument type='real' />
-        </function>
-
+    
         <function group='date' name='DAYOFYEAR' return-type='int'>
             <formula>DAY_OF_YEAR(%1)</formula>
             <argument type='date' />
@@ -252,35 +188,35 @@
             <argument type='date' />
         </function>
 
-        <function group='string' name='MID' return-type='str'>
+        <function group='string' name='MID' return-type='int'>
             <formula>SUBSTR(%1,%2)</formula>
             <argument type='str' />
             <argument type='int' />
         </function>
-        <function group='string' name='MID' return-type='str'>
+        <function group='string' name='MID' return-type='int'>
             <formula>SUBSTR(%1,CAST(%2 as int))</formula>
             <argument type='str' />
             <argument type='real' />
         </function>
-        <function group='string' name='MID' return-type='str'>
+        <function group='string' name='MID' return-type='int'>
             <formula>SUBSTR(%1,%2,%3)</formula>
             <argument type='str' />
             <argument type='int' />
             <argument type='int' />
         </function>
-        <function group='string' name='MID' return-type='str'>
+        <function group='string' name='MID' return-type='int'>
             <formula>SUBSTR(%1,CAST(%2 as int),%3)</formula>
             <argument type='str' />
             <argument type='real' />
             <argument type='int' />
         </function>
-        <function group='string' name='MID' return-type='str'>
+        <function group='string' name='MID' return-type='int'>
             <formula>SUBSTR(%1,%2,CAST(%3 as int))</formula>
             <argument type='str' />
             <argument type='int' />
             <argument type='real' />
         </function>
-        <function group='string' name='MID' return-type='str'>
+        <function group='string' name='MID' return-type='int'>
             <formula>SUBSTR(%1,CAST(%2 as int),CAST(%3 as int))</formula>
             <argument type='str' />
             <argument type='real' />
@@ -390,8 +326,24 @@
             <argument type='datetime' />
         </remove-function>
 
+        <remove-function name='MAX'>
+            <argument type='str' />
+        </remove-function>
+        <remove-function name='MAX'>
+            <argument type='str' />
+            <argument type='str' />
+        </remove-function>
+
         <remove-function name='SPACE'>
             <argument type='int' />
         </remove-function>
+
+        <remove-function name='MIN'>
+            <argument type='str' />
+        </remove-function>
+        <remove-function name='MIN'>
+            <argument type='str' />
+            <argument type='str' />
+        </remove-function>
    </function-map>
-</dialect>
+</dialect>
\ No newline at end of file
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
index 55c64830b97..c0df5ebb288 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
@@ -2,11 +2,11 @@
 
 <connector-plugin class='opensearch_jdbc' superclass='jdbc' plugin-version='1.1.0.0' name='OpenSearch' version='18.1' min-version-tableau='2021.1'>
   <vendor-information>
-      <company name="OpenSearch Project"/>
+      <company name="OpenSearch for ES"/>
       <support-link url="https://github.com/opensearch-project/sql"/>
   </vendor-information>
   <connection-customization class="opensearch_jdbc" enabled="true" version="10.0">
-    <vendor name="OpenSearch Project"/>
+    <vendor name="OpenSearch JDBC"/>
     <driver name="SQL"/>
     <customizations>
       <customization name="CAP_CREATE_TEMP_TABLES" value="no"/>
@@ -50,4 +50,4 @@
   <connection-metadata file='connection-metadata.xml'/>
   <connection-resolver file="connectionResolver.tdr"/>
   <dialect file='dialect.tdd'/>
-</connector-plugin>
+</connector-plugin>
\ No newline at end of file
diff --git a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
index 4dcd94ae74f..459d2d07d96 100644
--- a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
+++ b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
@@ -8,7 +8,6 @@
 
 import java.sql.SQLException;
 import java.sql.Timestamp;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.Calendar;
 import java.util.Map;
@@ -79,18 +78,13 @@ else if (value.charAt(23) == '+' || value.charAt(23) == '-') {
                 }
             }
 
-            final Timestamp ts;
-            // 11 to check if the value is in yyyy-MM-dd format
-            if (value.length() < 11) {
-                ts = Timestamp.valueOf(LocalDate.parse(value).atStartOfDay());
+            if (calendar == null) {
+                return Timestamp.valueOf(value);
             } else {
-                ts = Timestamp.valueOf(value);
+                Timestamp ts = Timestamp.valueOf(value);
+                return localDateTimeToTimestamp(ts.toLocalDateTime(), calendar);
             }
 
-            if (calendar == null) {
-                return ts;
-            }
-            return localDateTimeToTimestamp(ts.toLocalDateTime(), calendar);
         } catch (IllegalArgumentException iae) {
             throw stringConversionException(value, iae);
         }
@@ -105,4 +99,4 @@ public String getTypeName() {
         return "Timestamp";
     }
 
-}
+}
\ No newline at end of file
diff --git a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
index 69b3b4a48a8..5568494303b 100644
--- a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
+++ b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
@@ -208,20 +208,20 @@ TEST_SQL_GET_INFO_STRING(SQLCatalogName, SQL_CATALOG_NAME, L"N");
 // Conversion //
 ////////////////
 
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertInteger, SQL_CONVERT_INTEGER, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertInteger, SQL_CONVERT_INTEGER, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertSmallint, SQL_CONVERT_SMALLINT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTinyint, SQL_CONVERT_TINYINT, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBit, SQL_CONVERT_BIT, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBit, SQL_CONVERT_BIT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertVarchar, SQL_CONVERT_VARCHAR, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBigint, SQL_CONVERT_BIGINT, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBigint, SQL_CONVERT_BIGINT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDecimal, SQL_CONVERT_DECIMAL, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDouble, SQL_CONVERT_DOUBLE, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDouble, SQL_CONVERT_DOUBLE, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertFloat, SQL_CONVERT_FLOAT, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertNumeric, SQL_CONVERT_NUMERIC, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertReal, SQL_CONVERT_REAL, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIT | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertReal, SQL_CONVERT_REAL, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertDate, SQL_CONVERT_DATE, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTime, SQL_CONVERT_TIME, 0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTimestamp, SQL_CONVERT_TIMESTAMP, SQL_CVT_TIMESTAMP | SQL_CVT_WVARCHAR);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertTimestamp, SQL_CONVERT_TIMESTAMP, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertBinary, SQL_CONVERT_BINARY, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertLongvarbinary, SQL_CONVERT_LONGVARBINARY,
                             0);
@@ -231,7 +231,7 @@ TEST_SQL_GET_INFO_UINT_MASK(SQLConvertLongVarchar, SQL_CONVERT_LONGVARCHAR, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWChar, SQL_CONVERT_WCHAR, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWLongVarchar, SQL_CONVERT_WLONGVARCHAR,
                             0);
-TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWVarchar, SQL_CONVERT_WVARCHAR, SQL_CVT_INTEGER | SQL_CVT_REAL | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_WVARCHAR);
+TEST_SQL_GET_INFO_UINT_MASK(SQLConvertWVarchar, SQL_CONVERT_WVARCHAR, 0);
 TEST_SQL_GET_INFO_UINT_MASK(SQLConvertGuid, SQL_CONVERT_GUID, 0);
 
 //////////////////////
@@ -303,4 +303,4 @@ int main(int argc, char** argv) {
     system("leaks itodbc_info > leaks_itodbc_info");
 #endif
     return failures;
-}
+}
\ No newline at end of file
diff --git a/sql-odbc/src/sqlodbc/info.c b/sql-odbc/src/sqlodbc/info.c
index 1f7295502c2..13fdd2fef90 100644
--- a/sql-odbc/src/sqlodbc/info.c
+++ b/sql-odbc/src/sqlodbc/info.c
@@ -104,14 +104,20 @@ RETCODE SQL_API OPENSEARCHAPI_GetInfo(HDBC hdbc, SQLUSMALLINT fInfoType,
             break;
 
         case SQL_CONVERT_GUID:
+        case SQL_CONVERT_INTEGER:
         case SQL_CONVERT_SMALLINT:
         case SQL_CONVERT_TINYINT:
+        case SQL_CONVERT_BIT:
         case SQL_CONVERT_VARCHAR:
+        case SQL_CONVERT_BIGINT:
         case SQL_CONVERT_DECIMAL:
+        case SQL_CONVERT_DOUBLE:
         case SQL_CONVERT_FLOAT:
         case SQL_CONVERT_NUMERIC:
+        case SQL_CONVERT_REAL:
         case SQL_CONVERT_DATE:
         case SQL_CONVERT_TIME:
+        case SQL_CONVERT_TIMESTAMP:
         case SQL_CONVERT_BINARY:
         case SQL_CONVERT_LONGVARBINARY:
         case SQL_CONVERT_VARBINARY: /* ODBC 1.0 */
@@ -120,46 +126,12 @@ RETCODE SQL_API OPENSEARCHAPI_GetInfo(HDBC hdbc, SQLUSMALLINT fInfoType,
 #ifdef UNICODE_SUPPORT
         case SQL_CONVERT_WCHAR:
         case SQL_CONVERT_WLONGVARCHAR:
+        case SQL_CONVERT_WVARCHAR:
 #endif /* UNICODE_SUPPORT */
             len = sizeof(SQLUINTEGER);
             value = 0; /* CONVERT is unavailable */
             break;
 
-        case SQL_CONVERT_INTEGER: /* ODBC 1.0 */
-            len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
-            break;
-
-        case SQL_CONVERT_BIT: /* ODBC 1.0 */
-            len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_BIT | SQL_CVT_INTEGER | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
-            break;
-
-        case SQL_CONVERT_WVARCHAR: /* ODBC 1.0 */
-            len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_WVARCHAR | SQL_CVT_INTEGER | SQL_CVT_DOUBLE | SQL_CVT_BIGINT | SQL_CVT_REAL;
-            break;
-
-        case SQL_CONVERT_DOUBLE: /* ODBC 1.0 */
-            len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_DOUBLE | SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_BIGINT | SQL_CVT_REAL;
-            break;
-
-        case SQL_CONVERT_BIGINT: /* ODBC 1.0 */
-            len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_BIGINT | SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_REAL;
-            break;
-
-        case SQL_CONVERT_REAL: /* ODBC 1.0 */
-            len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_REAL | SQL_CVT_INTEGER | SQL_CVT_BIT | SQL_CVT_WVARCHAR | SQL_CVT_DOUBLE | SQL_CVT_BIGINT;
-            break;
-
-        case SQL_CONVERT_TIMESTAMP: /* ODBC 1.0 */
-            len = sizeof(SQLUINTEGER);
-            value = SQL_CVT_TIMESTAMP | SQL_CVT_WVARCHAR;
-            break;
-
         case SQL_CONVERT_FUNCTIONS: /* ODBC 1.0 */
             len = sizeof(SQLUINTEGER);
             value = SQL_FN_CVT_CAST;
@@ -1903,4 +1875,4 @@ RETCODE SQL_API OPENSEARCHAPI_TablePrivileges(HSTMT hstmt,
     SC_set_current_col(stmt, -1);
 
     return SQL_SUCCESS;
-}
+}
\ No newline at end of file

From 858bd646168f0331fc5383a82ff3952f996409c6 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Thu, 9 Dec 2021 14:38:48 -0800
Subject: [PATCH 27/28] Remove changes from irrelevant commits

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd   | 2 +-
 sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml  | 2 +-
 .../src/main/java/org/opensearch/jdbc/types/TimestampType.java  | 2 +-
 sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp     | 2 +-
 sql-odbc/src/sqlodbc/info.c                                     | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
index 2105ac7fd21..f33f42444e5 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/dialect.tdd
@@ -346,4 +346,4 @@
             <argument type='str' />
         </remove-function>
    </function-map>
-</dialect>
\ No newline at end of file
+</dialect>
diff --git a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
index c0df5ebb288..20c99b96be0 100644
--- a/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
+++ b/sql-jdbc/src/TableauConnector/opensearch_sql_jdbc/manifest.xml
@@ -50,4 +50,4 @@
   <connection-metadata file='connection-metadata.xml'/>
   <connection-resolver file="connectionResolver.tdr"/>
   <dialect file='dialect.tdd'/>
-</connector-plugin>
\ No newline at end of file
+</connector-plugin>
diff --git a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
index 459d2d07d96..3ae9463ea41 100644
--- a/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
+++ b/sql-jdbc/src/main/java/org/opensearch/jdbc/types/TimestampType.java
@@ -99,4 +99,4 @@ public String getTypeName() {
         return "Timestamp";
     }
 
-}
\ No newline at end of file
+}
diff --git a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
index 5568494303b..b19660f7e53 100644
--- a/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
+++ b/sql-odbc/src/IntegrationTests/ITODBCInfo/test_odbc_info.cpp
@@ -303,4 +303,4 @@ int main(int argc, char** argv) {
     system("leaks itodbc_info > leaks_itodbc_info");
 #endif
     return failures;
-}
\ No newline at end of file
+}
diff --git a/sql-odbc/src/sqlodbc/info.c b/sql-odbc/src/sqlodbc/info.c
index 13fdd2fef90..fc859a0d9eb 100644
--- a/sql-odbc/src/sqlodbc/info.c
+++ b/sql-odbc/src/sqlodbc/info.c
@@ -1875,4 +1875,4 @@ RETCODE SQL_API OPENSEARCHAPI_TablePrivileges(HSTMT hstmt,
     SC_set_current_col(stmt, -1);
 
     return SQL_SUCCESS;
-}
\ No newline at end of file
+}

From 28abae993b098671a641161749201c9e71a9f4a9 Mon Sep 17 00:00:00 2001
From: Guian Gumpac <guiang@bitquilltech.com>
Date: Thu, 9 Dec 2021 14:46:15 -0800
Subject: [PATCH 28/28] Updated the mez file

Signed-off-by: Guian Gumpac <guiang@bitquilltech.com>
---
 .../bin/Release/SqlOdbcPBIConnector.mez       | Bin 32630 -> 32552 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/sql-odbc/src/PowerBIConnector/bin/Release/SqlOdbcPBIConnector.mez b/sql-odbc/src/PowerBIConnector/bin/Release/SqlOdbcPBIConnector.mez
index 2dc7d88dde04658da32a33a8317e41baa9617b97..e830c80222de41818481267af836205326976f47 100644
GIT binary patch
