Pseudo-code for Getting the Table Expression
- Last Updated: May 12, 2026
- 5 minute read
- OpenAccess SDK
- Version 8.1
- Documentation
This example code shows how the IP can use the various API calls to get details of the Search Expression and Join Expression. The starting point is a call to dam_getTableSearchExp from the EXECUTE function of the IP.
{
int iTableNum;
DAM_HLOGEXP hSearchExp, hJoinExp;
int iJoinType;
int bPartialExp;
/* get the search expression and Join expression handles */
iTableNum = 0;
dam_getTableSearchExp(hstmt, &iTableNum, &hSearchExp, &iJoinType, &hJoinExp, &bPartialExp);
/* get filter conditions */
ip_print_logexp(hSearchExp);
/* check the Join type */
if (hJoinExp) {
if (iJoinType == SQL_JOIN_LEFT_OUTER) printf(" OUTER JOIN ");
if (iJoinType == SQL_JOIN_LEFT_INNER || iJoinType == SQL_JOIN_OLD_STYLE)
printf("INNER JOIN ");
/* get Join conditions */
ip_print_logexp(hJoinExp);
}
int ip_print_logexp(DAM_HLOGEXP hSearchExp)
{
int iType; /* AND, OR, NOT or CONDITION */
DAM_HLOGEXP hLeft, hRight;
DAM_HCOND hCond;
/* get and print the logical expression */
damex_describeLogicExp(hSearchExp,
&iType, /* AND, OR, NOT or CONDITION */
&hLeft,
&hRight,&hCond);
switch (iType) {
case SQL_EXP_COND:
ip_print_cond(hCond);
break;
case SQL_EXP_AND:
/* left-expression AND right-expression */
ip_print_logexp(hLeft);
printf( " AND ");
ip_print_logexp(hRight);
break;
case SQL_EXP_OR:
/* left-expression OR right-expression */
ip_print_logexp(hLeft);
printf( " OR ");
ip_print_logexp(hRight);
break;
case SQL_EXP_NOT:
/* NOT left-expression */
printf( " NOT ");
ip_print_logexp(hLeft);
break;
}
return DAM_SUCCESS;
}
int ip_print_cond(DAM_HCOND hCond)
{
int iType;
DAM_HVALEXP hLeft, hRight, hExtra;
damex_describeCond(hCond,
&iType, /* >, <, =, BETWEEN etc.*/
&hLeft,
&hRight,
&hExtra); /* used for BETWEEN */
/* EXISTS and UNIQUE predicates */
if (iType & (SQL_OP_EXISTS | SQL_OP_UNIQUE)) {
if (iType & SQL_OP_NOT) printf( " NOT ");
if (iType & SQL_OP_EXISTS) printf( " EXISTS ");
if (iType & SQL_OP_UNIQUE) printf( " UNIQUE ");
ip_print_valexp(hLeft);
}
/* conditional predicates */
if (iType & ( SQL_OP_SMALLER | SQL_OP_GREATER | SQL_OP_EQUAL)) {
ip_print_valexp(hLeft);
if (iType & SQL_OP_NOT) {
if (iType & SQL_OP_EQUAL) printf( " <> ");
}
else {
printf( " ");
if (iType & SQL_OP_SMALLER) printf( "<");
if (iType & SQL_OP_GREATER) printf( ">");
if (iType & SQL_OP_EQUAL) printf( "=");
printf( " ");
}
if (iType & (SQL_OP_QUANTIFIER_ALL | SQL_OP_QUANTIFIER_SOME | SQL_OP_QUANTIFIER_ANY) {
if (iType & SQL_OP_QUANTIFIER_ALL) printf( " ALL ");
if (iType & SQL_OP_QUANTIFIER_SOME) printf( " SOME ");
if (iType & SQL_OP_QUANTIFIER_ANY) printf( " ANY ");
}
ip_print_valexp(hRight);
} /* conditional predicate */
/* like predicate */
if (iType & SQL_OP_LIKE) {
ip_print_valexp(hLeft);
if (iType & SQL_OP_NOT) printf( " NOT ");
printf( " LIKE ");
ip_print_valexp(hRight);
if (hExtra) {
printf( " ESCAPE ");
ip_print_valexp(hExtra);
}
} /* like predicate */
/* Is NULL predicate */
if (iType & SQL_OP_ISNULL) {
ip_print_valexp(hLeft);
if (iType & SQL_OP_NOT)
printf( " IS NOT NULL ");
else
printf( " IS NULL ");
}
/* IN predicate */
if (iType & SQL_OP_IN) {
ip_print_valexp(hLeft);
if (iType & SQL_OP_NOT) printf( " NOT ");
printf( " IN (");
ip_print_valexp(hRight);
pintf( " )");
}
/* BETWEEN predicate */
if (iType & SQL_OP_BETWEEN) {
/* check if the between is a form of ( >= and < ) OR (> and <)
OR (> and <=)
*/
if ((iType & SQL_OP_BETWEEN_OPEN_LEFT) ||
(iType & SQL_OP_BETWEEN_OPEN_RIGHT)) {
/* format it as two conditions */
ip_print_valexp(hLeft);
if (iType & SQL_OP_BETWEEN_OPEN_LEFT)
printf( " > ");
else
printf( " >= ");
ip_print_valexp(hRight);
printf( " AND ");
ip_print_valexp(hLeft);
if (iType & SQL_OP_BETWEEN_OPEN_RIGHT)
printf( " < ");
else
printf( " <= ");
ip_print_valexp(hExtra);
}
else {
/* standard BETWEEN pattern */
ip_print_valexp(hLeft);
if (iType & SQL_OP_NOT) printf( " NOT ");
printf( " BETWEEN ");
ip_print_valexp(hRight);
printf( " AND ");
ip_print_valexp(hExtra);
}
} /* BETWEEN */
return DAM_SUCCESS;
}
int ip_print_valexp(DAM_HVALEXP hValExp)
{
int iType; /* literal value, column, +, -, *, / etc */
int iFuncType;
DAM_HVALEXP hLeftValExp;
DAM_HVALEXP hRightValExp;
DAM_HVAL hVal;
DAM_HSCALAR_VALEXP hScalarValExp;
damex_describeValExp(hValExp, &iType, /* literal value, column, +, -, *, / etc */
&iFuncType,
&hLeftValExp,
&hRightValExp,
&hVal,
&hScalarValExp
);
/* function type (SQL_F_COUNT, SQL_F_MIN etc will not occur in search expressions */
switch (iType) {
case SQL_VAL_EXP_VAL:
ip_print_val(hVal);
break;
case SQL_VAL_EXP_ADD:
case SQL_VAL_EXP_SUBTRACT:
ip_print_valexp(hLeftValExp);
if (iType == SQL_VAL_EXP_AND) printf( "+");
if (iType == SQL_VAL_EXP_SUBTRACT) printf( "-");
if (iType == SQL_VAL_EXP_MULTIPLE) printf( "*");
if (iType == SQL_VAL_EXP_DIVIDE) printf( "/");
ip_print_valexp(hRightValExp);
break;
case SQL_VAL_EXP_SCALAR:
ip_print_scalar_valexp(hScalarValExp);
break;
}
return DAM_SUCCESS;
}
int ip_print_scalar_valexp(DAM_HSCALAR_VALEXP hScalarValExp)
{
char sName[DAM_MAX_ID_LEN+1];
char sQualifierName[DAM_MAX_ID_LEN+1];
DAM_HVALEXP_LIST hValExpList;
damex_describeScalarValExpEx2(hScalarValExp, sQualifierName, sName,
&hValExpList);
printf( "%s", sQualifierName, sName);
printf( "( ");
if (hValExpList) ip_print_valexp_list(hValExpList);
printf( ") ");
return DAM_SUCCESS;
}
int ip_print_valexp_list(DAM_HVALEXP_LIST hValExpList)
{
DAM_HVALEXP hValExp;
int iFirst = TRUE;
hValExp = damex_getFirstValExp(hValExpList);
while (hValExp) {
if (!iFirst)
printf( ", ");
else
iFirst = FALSE;
ip_print_valexp(hValExp);
hValExp = damex_getNextValExp(hValExpList);
}
printf( " ");
return DAM_SUCCESS;
}
int ip_print_val(DAM_HQUERY hquery, DAM_HVAL hVal)
{
int iType; /* literal value, column */
int iXoType; /* type of literal value – INTEGER, CHAR etc */
void *pData;
DAM_HCOL hCol;
DAM_HQUERY hSubQuery;
damex_describeVal(hVal, &iType,
&iXoType,
&pData,
&hCol,
&hSubQuery);
switch (iType) {
case SQL_VAL_DATA_CHAIN:
break;
case SQL_VAL_NULL:
printf( "NULL"); break;
case SQL_VAL_QUERY: /* query */
ip_print_query_values(hSubQuery);
break;
case SQL_VAL_COL: /* value is the column value */
ip_print_col(hCol); break;
case SQL_VAL_INTERVAL:
break;
case SQL_VAL_LITERAL: /* value is a Xo Type literal */
ip_print_data(iXoType, pData);
break;
default:
printf( "Invalid Value Type:%d", iType); break;
}
return DAM_SUCCESS;
}
int ip_print_query_values(DAM_HQUERY hQuery)
{
int iRetCode;
int iXoType;
void *pVal;
int iValLen;
int bFoundVal = FALSE;
iRetCode = dam_getQueryFirstResultValue(hQuery, &iXoType, &pVal, &iValLen);
while (iRetCode == DAM_SUCCESS) {
if (bFoundVal)
printf(", ");
if (iValLen == XO_NULL_DATA)
printf( "NULL");
else
ip_print_data(iXoType, pVal);
bFoundVal = TRUE;
iRetCode = dam_getQueryNextResultValue(hQuery, &iXoType, &pVal, &iValLen);
}
/* when results are empty, we will use NULL value */
if (!bFoundVal)
printf("NULL");
if (iRetCode != DAM_NO_DATA_FOUND) return iRetCode;
return DAM_SUCCESS;
}
int ip_print_data(int iXoType, void *pData)
{
xo_tm *pxoTime;
switch (iXoType) {
case XO_TYPE_CHAR: /* pVal is a char literal */
case XO_TYPE_VARCHAR:
case XO_TYPE_NUMERIC:
case XO_TYPE_DECIMAL:
printf( "'%s'", (char *)pData);
break;
case XO_TYPE_INTEGER: /* pVal is a integer literal */
printf( "%ld", *(long *)pData);
break;
case XO_TYPE_SMALLINT: /* pVal is small integer literal */
printf( "%d", (int)(*(short *)pData));
break;
case XO_TYPE_FLOAT: /* pVal is a double literal */
case XO_TYPE_DOUBLE:
printf( "%Lf", *(double *)pData);
break;
case XO_TYPE_REAL: /* pVal is a float literal */
printf( "%f", *(float *)pData);
break;
case XO_TYPE_DATE:
pxoTime = (xo_tm *)pData;
printf( "{d '%d-%02d-%02d'}", pxoTime->tm_year,
pxoTime->tm_mon+1, pxoTime->tm_mday);
break;
case XO_TYPE_TIME:
pxoTime = (xo_tm *)pData;
printf( "{t '%02d:%02d:%02d'}", pxoTime->tm_hour,
pxoTime->tm_min, pxoTime->tm_sec);
break;
case XO_TYPE_TIMESTAMP:
pxoTime = (xo_tm *)pData;
if (pxoTime->tm_frac > 0) {
int frac;
frac = (int) (pxoTime->tm_frac * 0.000001);
printf( "{ts '%d-%02d-%02d %02d:%02d:%02d.%03d'}",
pxoTime->tm_year, pxoTime->tm_mon+1, pxoTime->tm_mday,
pxoTime->tm_hour, pxoTime->tm_min, pxoTime->tm_sec, frac);
}
else
printf( "{ts '%d-%02d-%02d %02d:%02d:%02d'}",
pxoTime->tm_year, pxoTime->tm_mon+1, pxoTime->tm_mday,
pxoTime->tm_hour, pxoTime->tm_min, pxoTime->tm_sec);
break;
default:
printf( "Invalid Xo Value Type:%d", iXoType);
break;
}
return DAM_SUCCESS;
}
int ip_print_col(DAM_HCOL hCol)
{
int iTableNum, iColNum;
char sColName[DAM_MAX_ID_LEN+1];
DAM_HSTMT hstmt = pStmtDA->dam_hstmt; /* we need to pass this variable as argument */
damex_describeCol(hCol,
&iTableNum,
&iColNum,
sColName, NULL, NULL, NULL, NULL);
/* check for correlated column and join columns */
if (damex_isCorrelatedCol(hCol) ||
(pStmtDA->iCurTableNum != DAM_NOT_SET && iTableNum != pStmtDA->iCurTableNum)) {
int iValLen;
void *pVal;
dam_getJoinColValue(hstmt, hCol, XO_TYPE_CHAR, &pVal, &iValLen);
if (iValLen == XO_NULL_DATA)
printf( " NULL ");
else
printf( " '%s' ", (char *)pVal);
}
else {
printf( "T%d.%s", iTableNum, sColName);
}
return DAM_SUCCESS;
}