/* ** The first parameter (pDef) is a function implementation. The ** second parameter (pExpr) is the first argument to this function. ** If pExpr is a column in a virtual table, then let the virtual ** table implementation have an opportunity to overload the function. ** ** This routine is used to allow virtual table implementations to ** overload MATCH, LIKE, GLOB, and REGEXP operators. ** ** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ static FuncDef sqlite3VtabOverloadFunction( sqlite3 db, /* Database connection for reporting malloc problems */ FuncDef pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr pExpr /* First argument to the function */ ) { Table pTab; sqlite3_vtab pVtab; sqlite3_module pMod; dxFunc xFunc = null;//void (*xFunc)(sqlite3_context*,int,sqlite3_value*) = 0; object pArg = null; FuncDef pNew; int rc = 0; string zLowerName; string z; /* Check to see the left operand is a column in a virtual table */ if (NEVER(pExpr == null)) { return(pDef); } if (pExpr.op != TK_COLUMN) { return(pDef); } pTab = pExpr.pTab; if (NEVER(pTab == null)) { return(pDef); } if ((pTab.tabFlags & TF_Virtual) == 0) { return(pDef); } pVtab = sqlite3GetVTable(db, pTab).pVtab; Debug.Assert(pVtab != null); Debug.Assert(pVtab.pModule != null); pMod = (sqlite3_module)pVtab.pModule; if (pMod.xFindFunction == null) { return(pDef); } /* Call the xFindFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ zLowerName = pDef.zName;//sqlite3DbStrDup(db, pDef.zName); if (zLowerName != null) { //for(z=(unsigned char)zLowerName; *z; z++){ // *z = sqlite3UpperToLower[*z]; //} rc = pMod.xFindFunction(pVtab, nArg, zLowerName.ToLowerInvariant(), ref xFunc, ref pArg); sqlite3DbFree(db, ref zLowerName); } if (rc == 0) { return(pDef); } /* Create a new ephemeral function definition for the overloaded ** function */ //sqlite3DbMallocZero(db, sizeof(*pNew) // + sqlite3Strlen30(pDef.zName) + 1); //if ( pNew == null ) //{ // return pDef; //} pNew = pDef.Copy(); pNew.zName = pDef.zName; //pNew.zName = (char )&pNew[1]; //memcpy(pNew.zName, pDef.zName, sqlite3Strlen30(pDef.zName)+1); pNew.xFunc = xFunc; pNew.pUserData = pArg; pNew.flags |= SQLITE_FUNC_EPHEM; return(pNew); }
/* ** The first parameter (pDef) is a function implementation. The ** second parameter (pExpr) is the first argument to this function. ** If pExpr is a column in a virtual table, then let the virtual ** table implementation have an opportunity to overload the function. ** ** This routine is used to allow virtual table implementations to ** overload MATCH, LIKE, GLOB, and REGEXP operators. ** ** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ static FuncDef sqlite3VtabOverloadFunction( sqlite3 db, /* Database connection for reporting malloc problems */ FuncDef pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr pExpr /* First argument to the function */ ) { Table pTab; sqlite3_vtab pVtab; sqlite3_module pMod; dxFunc xFunc = null;//void (*xFunc)(sqlite3_context*,int,sqlite3_value*) = 0; object pArg = null; FuncDef pNew; int rc = 0; string zLowerName; string z; /* Check to see the left operand is a column in a virtual table */ if ( NEVER( pExpr == null ) ) return pDef; if ( pExpr.op != TK_COLUMN ) return pDef; pTab = pExpr.pTab; if ( NEVER( pTab == null ) ) return pDef; if ( ( pTab.tabFlags & TF_Virtual ) == 0 ) return pDef; pVtab = sqlite3GetVTable( db, pTab ).pVtab; Debug.Assert( pVtab != null ); Debug.Assert( pVtab.pModule != null ); pMod = (sqlite3_module)pVtab.pModule; if ( pMod.xFindFunction == null ) return pDef; /* Call the xFindFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ zLowerName = pDef.zName;//sqlite3DbStrDup(db, pDef.zName); if ( zLowerName != null ) { //for(z=(unsigned char)zLowerName; *z; z++){ // *z = sqlite3UpperToLower[*z]; //} rc = pMod.xFindFunction( pVtab, nArg, zLowerName.ToLowerInvariant(), ref xFunc, ref pArg ); sqlite3DbFree( db, ref zLowerName ); } if ( rc == 0 ) { return pDef; } /* Create a new ephemeral function definition for the overloaded ** function */ //sqlite3DbMallocZero(db, sizeof(*pNew) // + sqlite3Strlen30(pDef.zName) + 1); //if ( pNew == null ) //{ // return pDef; //} pNew = pDef.Copy(); pNew.zName = pDef.zName; //pNew.zName = (char )&pNew[1]; //memcpy(pNew.zName, pDef.zName, sqlite3Strlen30(pDef.zName)+1); pNew.xFunc = xFunc; pNew.pUserData = pArg; pNew.flags |= SQLITE_FUNC_EPHEM; return pNew; }