SQLite Forum

columnName function
Login

columnName function

(1) By curmudgeon on 2020-03-18 14:25:30 [link] [source]

There's a static function in the sqlite3.c file called columnName. I know it's not part of the API but hoped by opening it up I'd be able to get the DB, table and name for the i'th column in a stmt. I can only get it to return a meaningful value for useType 0 & 1 though. Does anyone know why it always seems to return "0.0" for useType 2,3 & 4? That's the case even for simple stmts such as "select col from tbl" where col is a valid column name within table tbl. 

/*
** Convert the N-th element of pStmt->pColName[] into a string using
** xFunc() then return that string.  If N is out of range, return 0.
**
** There are up to 5 names for each column.  useType determines which
** name is returned.  Here are the names:
**
**    0      The column name as it should be displayed for output
**    1      The datatype name for the column
**    2      The name of the database that the column derives from
**    3      The name of the table that the column derives from
**    4      The name of the table column that the result column derives from
**
** If the result is not a simple column reference (if it is an expression
** or a constant) then useTypes 2, 3, and 4 return NULL.
*/
static const void *columnName(
  sqlite3_stmt *pStmt,     /* The statement */
  int N,                   /* Which column to get the name for */
  int useUtf16,            /* True to return the name as UTF16 */
  int useType              /* What type of name */
){
  const void *ret;
  Vdbe *p;
  int n;
  sqlite3 *db;
#ifdef SQLITE_ENABLE_API_ARMOR
  if( pStmt==0 ){
	(void)SQLITE_MISUSE_BKPT;
	return 0;
  }
#endif
  ret = 0;
  p = (Vdbe *)pStmt;
  db = p->db;
  assert( db!=0 );
  n = sqlite3_column_count(pStmt);
  if( N<n && N>=0 ){
	N += useType*n;
	sqlite3_mutex_enter(db->mutex);
	assert( db->mallocFailed==0 );
#ifndef SQLITE_OMIT_UTF16
	if( useUtf16 ){
	  ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
	}else
#endif
	{
	  ret = sqlite3_value_text((sqlite3_value*)&p->aColName[N]);
	}
	/* A malloc may have failed inside of the _text() call. If this
	** is the case, clear the mallocFailed flag and return NULL.
	*/
	if( db->mallocFailed ){
	  sqlite3OomClear(db);
	  ret = 0;
	}
	sqlite3_mutex_leave(db->mutex);
  }
  return ret;
}

(2.1) By Keith Medcalf (kmedcalf) on 2020-03-18 15:03:34 edited from 2.0 in reply to 1 [link] [source]

The SQLITE_ENABLE_COLUMN_METADATA symbol needs to be defined in order to collect this information when the statement is parsed.

It also enables the sqlite3_column_database_name, sqlite3_column_table_name, and sqlite3_column_origin_name APIs.

I presume that you did not have this symbol defined at compile time?  

And if you do have it defined, why not just use the intended API functions which do nothing more than return the results of calling the internal columnName function?

(3) By doug (doug9forester) on 2020-03-18 15:39:22 in reply to 2.1 [link] [source]

ALERT: Forum question: why do I see back slashes before every underscore in the email notification for this post?

The SQLITE\_ENABLE\_COLUMN\_METADATA symbol needs to be defined in order to collect this information when the statement is parsed.

It also enables the sqlite3\_column\_database_name, sqlite3\_column\_table\_name, and sqlite3\_column\_origin\_name APIs.

I presume that you did not have this symbol defined at compile time?  And if you do have it defined, why not just use the intended API functions?

(4) By Stephan Beal (stephan) on 2020-03-18 15:44:23 in reply to 3 [source]

why do I see back slashes before every underscore in the email notification for this post?

Because in markdown format underscores need to be escaped with a backslash, otherwise they're interpreted as italics. Alternately, words with underscores can be wrapped_in_backticks to keep the underscores from being interpreted as italics.

(5.2) By curmudgeon on 2020-03-18 15:51:48 edited from 5.1 in reply to 2.1 [link] [source]

Thanks once again Keith, working now.

Which API functions are you referring to? I'm aware of sqlite3_column_name and sqlite3_column_decltype api functions but I'm not aware of any that will return the DB / Tbl.

EDIT:

Sorry Keith. I just noticed the functions you mentioned are called through the api and they in turn call the columnName function.

(6) By Gunter Hick (gunter_hick) on 2020-03-18 15:54:26 in reply to 5.1 [link] [source]

The use cases 2, 3 and 4 are called by the API functions sqlite3_column_database_name, sqlite3_column_table_name, and sqlite3_column_origin_name respectively.

The OP was hacking the code instead of configuring the build.