SQLRETURN StatementHandle::sqlColumns(SQLCHAR *catalogName, SQLSMALLINT catalogNameLen, SQLCHAR *schemaName, SQLSMALLINT schemaNameLen, SQLCHAR *tableName, SQLSMALLINT tableNameLen, SQLCHAR *columnName, SQLSMALLINT columnNameLen) { _cursorColumns.clear(); _cursor.reset(); _resultSet.clear(); _rowIdx = -1; std::list<std::string> schemas; int rc = _connHandle->getDbNames(&schemas); if (0 != rc) { return SQL_ERROR; } std::string schemaNameStr; if (NULL != schemaName) { if (schemaNameLen == SQL_NTS) { schemaNameStr.assign((char *)schemaName); } else { schemaNameStr.assign((char *)schemaName, (int)schemaNameLen); } } std::string tableNameStr; if (NULL != tableName) { if (tableNameLen == SQL_NTS) { tableNameStr.assign((char *)tableName); } else { tableNameStr.assign((char *)tableName, (int)tableNameLen); } } // map from schema name to table names for (std::list<std::string>::const_iterator it = schemas.begin(); it != schemas.end(); ++it) { if (schemaNameStr.size() && *it != schemaNameStr) { continue; } std::list<std::string> tables; int rc = _connHandle->getCollectionNames(*it, &tables); if (0 != rc) { return SQL_ERROR; } for (std::list<std::string>::const_iterator tableIt = tables.begin(); tableIt != tables.end(); ++tableIt) { size_t periodIdx = tableIt->find('.'); size_t periodIdx2 = tableIt->find('.', periodIdx + 1); if (periodIdx2 != std::string::npos) { periodIdx2 = periodIdx2 - periodIdx - 1; } std::string tableName(*tableIt, periodIdx + 1, periodIdx2); if ("system" == tableName) { // skip mongodb internal tables continue; } if (tableNameStr.size() && tableName != tableNameStr) { continue; } std::auto_ptr<mongo::DBClientCursor> cursor = _connHandle->query(*tableIt); int columnNum = 1; while (cursor->more()) { mongo::BSONObj::iterator fieldIt = cursor->next().begin(); while(fieldIt.more()) { mongo::BSONElement elem = fieldIt.next(); SQLSMALLINT dataType = mapMongoToODBCDataType(elem.type()); _resultSet.push_back(std::list<Result>()); std::list<Result>& results = _resultSet.back(); results.push_back("NULL"); results.push_back(*it); results.push_back(tableName); results.push_back(elem.fieldName()); results.push_back(dataType); results.push_back(dataTypeName(dataType)); results.push_back(columnSize(dataType)); results.push_back(bufferLength(dataType)); results.push_back(decimalDigits(dataType)); results.push_back(numPercRadix(dataType)); results.push_back((SQLSMALLINT)SQL_NULLABLE); results.push_back(""); results.push_back("NULL"); results.push_back(mapODBCDataTypeToSQLDataType(dataType)); results.push_back(getDatetimeSubcode(dataType)); results.push_back(maxCharLen(dataType)); results.push_back(columnNum++); results.push_back("\"YES\""); } break; } } } return SQL_SUCCESS; }
// ============================================================================= // // Try to parse an expression symbol (i.e. an OPER_erator or OPER_erand or a colon) // from the lexer. // ExpressionSymbol* Expression::parseSymbol() { int pos = m_lexer->position(); ExpressionValue* op = null; if (m_lexer->next (TK_Colon)) return new ExpressionColon; // Check for OPER_erator for (const OperatorInfo& op : g_Operators) if (m_lexer->next (op.token)) return new ExpressionOperator ((ExpressionOperatorType) (&op - &g_Operators[0])); // Check sub-expression if (m_lexer->next (TK_ParenStart)) { Expression expr (m_parser, m_lexer, m_type); m_lexer->mustGetNext (TK_ParenEnd); return expr.getResult()->clone(); } op = new ExpressionValue (m_type); // Check function if (CommandInfo* comm = findCommandByName (m_lexer->peekNextString())) { m_lexer->skip(); if (m_type != TYPE_Unknown && comm->returnvalue != m_type) error ("%1 returns an incompatible data type", comm->name); op->setBuffer (m_parser->parseCommand (comm)); return op; } // Check for variables if (m_lexer->next (TK_DollarSign)) { m_lexer->mustGetNext (TK_Symbol); Variable* var = m_parser->findVariable (getTokenString()); if (var == null) error ("unknown variable %1", getTokenString()); if (var->type != m_type) error ("expression requires %1, variable $%2 is of type %3", dataTypeName (m_type), var->name, dataTypeName (var->type)); if (var->isarray) { m_lexer->mustGetNext (TK_BracketStart); Expression expr (m_parser, m_lexer, TYPE_Int); expr.getResult()->convertToBuffer(); DataBuffer* buf = expr.getResult()->buffer()->clone(); buf->writeDWord (DH_PushGlobalArray); buf->writeDWord (var->index); op->setBuffer (buf); m_lexer->mustGetNext (TK_BracketEnd); } elif (var->writelevel == WRITE_Constexpr) op->setValue (var->value); else {