public LiteralParseNode literal(String value, String sqlTypeName) throws SQLException { PDataType expectedType = sqlTypeName == null ? null : PDataType.fromSqlTypeName(SchemaUtil.normalizeIdentifier(sqlTypeName)); if (expectedType == null || !expectedType.isCoercibleTo(PTimestamp.INSTANCE)) { throw TypeMismatchException.newException(expectedType, PTimestamp.INSTANCE); } Object typedValue = expectedType.toObject(value); return new LiteralParseNode(typedValue); }
/** * Get list of ColumnInfos that contain Column Name and its associated PDataType for an import. * The supplied list of columns can be null -- if it is non-null, it represents a user-supplied * list of columns to be imported. * * @param conn Phoenix connection from which metadata will be read * @param tableName Phoenix table name whose columns are to be checked. Can include a schema name * @param columns user-supplied list of import columns, can be null * @param strict if true, an exception will be thrown if unknown columns are supplied */ public static List<ColumnInfo> generateColumnInfo( Connection conn, String tableName, List<String> columns, boolean strict) throws SQLException { Map<String, Integer> columnNameToTypeMap = Maps.newLinkedHashMap(); Set<String> ambiguousColumnNames = new HashSet<String>(); Map<String, Integer> fullColumnNameToTypeMap = Maps.newLinkedHashMap(); DatabaseMetaData dbmd = conn.getMetaData(); int unfoundColumnCount = 0; // TODO: escape wildcard characters here because we don't want that // behavior here String escapedTableName = StringUtil.escapeLike(tableName); String[] schemaAndTable = escapedTableName.split("\\."); ResultSet rs = null; try { rs = dbmd.getColumns( null, (schemaAndTable.length == 1 ? "" : schemaAndTable[0]), (schemaAndTable.length == 1 ? escapedTableName : schemaAndTable[1]), null); while (rs.next()) { String colName = rs.getString(QueryUtil.COLUMN_NAME_POSITION); String colFam = rs.getString(QueryUtil.COLUMN_FAMILY_POSITION); // use family qualifier, if available, otherwise, use column name String fullColumn = (colFam == null ? colName : String.format("%s.%s", colFam, colName)); String sqlTypeName = rs.getString(QueryUtil.DATA_TYPE_NAME_POSITION); // allow for both bare and family qualified names. if (columnNameToTypeMap.keySet().contains(colName)) { ambiguousColumnNames.add(colName); } columnNameToTypeMap.put(colName, PDataType.fromSqlTypeName(sqlTypeName).getSqlType()); fullColumnNameToTypeMap.put( fullColumn, PDataType.fromSqlTypeName(sqlTypeName).getSqlType()); } if (columnNameToTypeMap.isEmpty()) { throw new IllegalArgumentException("Table " + tableName + " not found"); } } finally { if (rs != null) { rs.close(); } } List<ColumnInfo> columnInfoList = Lists.newArrayList(); Set<String> unresolvedColumnNames = new TreeSet<String>(); if (columns == null) { // use family qualified names by default, if no columns are specified. for (Map.Entry<String, Integer> entry : fullColumnNameToTypeMap.entrySet()) { columnInfoList.add(new ColumnInfo(entry.getKey(), entry.getValue())); } } else { // Leave "null" as indication to skip b/c it doesn't exist for (int i = 0; i < columns.size(); i++) { String columnName = columns.get(i).trim(); Integer sqlType = null; if (fullColumnNameToTypeMap.containsKey(columnName)) { sqlType = fullColumnNameToTypeMap.get(columnName); } else if (columnNameToTypeMap.containsKey(columnName)) { if (ambiguousColumnNames.contains(columnName)) { unresolvedColumnNames.add(columnName); } // fall back to bare column name. sqlType = columnNameToTypeMap.get(columnName); } if (unresolvedColumnNames.size() > 0) { StringBuilder exceptionMessage = new StringBuilder(); boolean first = true; exceptionMessage.append( "Unable to resolve these column names to a single column family:\n"); for (String col : unresolvedColumnNames) { if (first) first = false; else exceptionMessage.append(","); exceptionMessage.append(col); } exceptionMessage.append("\nAvailable columns with column families:\n"); first = true; for (String col : fullColumnNameToTypeMap.keySet()) { if (first) first = false; else exceptionMessage.append(","); exceptionMessage.append(col); } throw new SQLException(exceptionMessage.toString()); } if (sqlType == null) { if (strict) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.COLUMN_NOT_FOUND) .setColumnName(columnName) .setTableName(tableName) .build() .buildException(); } unfoundColumnCount++; } else { columnInfoList.add(new ColumnInfo(columnName, sqlType)); } } if (unfoundColumnCount == columns.size()) { throw new SQLExceptionInfo.Builder(SQLExceptionCode.COLUMN_NOT_FOUND) .setColumnName(Arrays.toString(columns.toArray(new String[0]))) .setTableName(tableName) .build() .buildException(); } } return columnInfoList; }