- // Pseudo-code for Getting the Table Expression
- // 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];
- DAM_HVALEXP_LIST hValExpList;
- damex_describeScalarValExp(hScalarValExp, sName, &hValExpList);
- printf( "%s", 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;
- }