org.apache.hive.hplsql.Meta Maven / Gradle / Ivy
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hive.hplsql;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import org.antlr.v4.runtime.ParserRuleContext;
/**
* Metadata
*/
public class Meta {
HashMap> dataTypes = new HashMap>();
Exec exec;
boolean trace = false;
boolean info = false;
Meta(Exec e) {
exec = e;
trace = exec.getTrace();
info = exec.getInfo();
}
/**
* Get the data type of column (column name is qualified i.e. schema.table.column)
*/
String getDataType(ParserRuleContext ctx, String conn, String column) {
String type = null;
HashMap map = dataTypes.get(conn);
if (map == null) {
map = new HashMap();
dataTypes.put(conn, map);
}
ArrayList twoparts = splitIdentifierToTwoParts(column);
if (twoparts != null) {
String tab = twoparts.get(0);
String col = twoparts.get(1).toUpperCase();
Row row = map.get(tab);
if (row != null) {
type = row.getType(col);
}
else {
row = readColumns(ctx, conn, tab, map);
if (row != null) {
type = row.getType(col);
}
}
}
return type;
}
/**
* Get data types for all columns of the table
*/
Row getRowDataType(ParserRuleContext ctx, String conn, String table) {
HashMap map = dataTypes.get(conn);
if (map == null) {
map = new HashMap();
dataTypes.put(conn, map);
}
Row row = map.get(table);
if (row == null) {
row = readColumns(ctx, conn, table, map);
}
return row;
}
/**
* Read the column data from the database and cache it
*/
Row readColumns(ParserRuleContext ctx, String conn, String table, HashMap map) {
Row row = null;
Conn.Type connType = exec.getConnectionType(conn);
if (connType == Conn.Type.HIVE) {
String sql = "DESCRIBE " + table;
Query query = new Query(sql);
exec.executeQuery(ctx, query, conn);
if (!query.error()) {
ResultSet rs = query.getResultSet();
try {
while (rs.next()) {
String col = rs.getString(1);
String typ = rs.getString(2);
if (row == null) {
row = new Row();
}
row.addColumn(col.toUpperCase(), typ);
}
map.put(table, row);
}
catch (Exception e) {}
}
exec.closeQuery(query, conn);
}
else {
Query query = exec.prepareQuery(ctx, "SELECT * FROM " + table, conn);
if (!query.error()) {
try {
PreparedStatement stmt = query.getPreparedStatement();
ResultSetMetaData rm = stmt.getMetaData();
int cols = rm.getColumnCount();
for (int i = 1; i <= cols; i++) {
String col = rm.getColumnName(i);
String typ = rm.getColumnTypeName(i);
if (row == null) {
row = new Row();
}
row.addColumn(col.toUpperCase(), typ);
}
map.put(table, row);
}
catch (Exception e) {}
}
exec.closeQuery(query, conn);
}
return row;
}
/**
* Normalize identifier for a database object (convert "" [] to `` i.e.)
*/
public String normalizeObjectIdentifier(String name) {
ArrayList parts = splitIdentifier(name);
if (parts != null) { // more then one part exist
StringBuilder norm = new StringBuilder();
int size = parts.size();
boolean appended = false;
for (int i = 0; i < size; i++) {
if (i == size - 2) { // schema name
String schema = getTargetSchemaName(parts.get(i));
if (schema != null) {
norm.append(schema);
appended = true;
}
} else {
norm.append(normalizeIdentifierPart(parts.get(i)));
appended = true;
}
if (i + 1 < parts.size() && appended) {
norm.append(".");
}
}
return norm.toString();
}
return normalizeIdentifierPart(name);
}
/**
* Get the schema name to be used in the final executed SQL
*/
String getTargetSchemaName(String name) {
if (name.equalsIgnoreCase("dbo") || name.equalsIgnoreCase("[dbo]")) {
return null;
}
return normalizeIdentifierPart(name);
}
/**
* Normalize identifier (single part) - convert "" [] to `` i.e.
*/
public String normalizeIdentifierPart(String name) {
char start = name.charAt(0);
char end = name.charAt(name.length() - 1);
if ((start == '[' && end == ']') || (start == '"' && end == '"')) {
return '`' + name.substring(1, name.length() - 1) + '`';
}
return name;
}
/**
* Split qualified object to 2 parts: schema.tab.col -> schema.tab|col; tab.col -> tab|col
*/
public ArrayList splitIdentifierToTwoParts(String name) {
ArrayList parts = splitIdentifier(name);
ArrayList twoparts = null;
if (parts != null) {
StringBuilder id = new StringBuilder();
int i = 0;
for (; i < parts.size() - 1; i++) {
id.append(parts.get(i));
if (i + 1 < parts.size() - 1) {
id.append(".");
}
}
twoparts = new ArrayList();
twoparts.add(id.toString());
id.setLength(0);
id.append(parts.get(i));
twoparts.add(id.toString());
}
return twoparts;
}
/**
* Split identifier to parts (schema, table, colum name etc.)
* @return null if identifier contains single part
*/
public ArrayList splitIdentifier(String name) {
ArrayList parts = null;
int start = 0;
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
char del = '\0';
if (c == '`' || c == '"') {
del = c;
}
else if (c == '[') {
del = ']';
}
if (del != '\0') {
for (int j = i + 1; i < name.length(); j++) {
i++;
if (name.charAt(j) == del) {
break;
}
}
continue;
}
if (c == '.') {
if (parts == null) {
parts = new ArrayList();
}
parts.add(name.substring(start, i));
start = i + 1;
}
}
if (parts != null) {
parts.add(name.substring(start));
}
return parts;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy