public override Null Visit(FuncDef node) { // Define the function node.symbol = new Symbol { kind = SymbolKind.Func, isStatic = node.isStatic, def = node, type = new ErrorType() }; scope.Define(node.symbol); // Visit the children differently than base.Visit(node) because we // want to define arguments in the body scope, not the parent scope. // Note that we don't visit the body, that's for ComputeTypesPass. node.returnType.Accept(this); if (node.block != null) { // Define arguments in the scope of the body node.block.scope = new Scope(scope, log, ScopeKind.Func); scope = node.block.scope; foreach (VarDef argDef in node.argDefs) argDef.Accept(this); scope = scope.parent; } else { // Define arguments in a temporary scope if no body is present scope = new Scope(scope, log, ScopeKind.Func); foreach (VarDef argDef in node.argDefs) argDef.Accept(this); scope = scope.parent; } return null; }
/* ** 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. */ 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; void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0; void *pArg = 0; FuncDef *pNew; int rc = 0; char *zLowerName; unsigned char *z; /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; pTab = pExpr->pTab; if( NEVER(pTab==0) ) return pDef; if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; /* Call the xFindFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ zLowerName = sqlite3DbStrDup(db, pDef->zName); if( zLowerName ){ for(z=(unsigned char*)zLowerName; *z; z++){ *z = sqlite3UpperToLower[*z]; } rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg); sqlite3DbFree(db, zLowerName); } if( rc==0 ){ return pDef; } /* Create a new ephemeral function definition for the overloaded ** function */ pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + sqlite3Strlen30(pDef->zName) + 1); if( pNew==0 ){ return pDef; } *pNew = *pDef; 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; }
static void CodeAttach(Parse parse, AUTH type, FuncDef func, Expr authArg, Expr filename, Expr dbName, Expr key) { Context ctx = parse.Ctx; NameContext sName; sName = new NameContext(); sName.Parse = parse; if (ResolveAttachExpr(sName, filename) != RC.OK || ResolveAttachExpr(sName, dbName) != RC.OK || ResolveAttachExpr(sName, key) != RC.OK) { parse.Errs++; goto attach_end; } #if !OMIT_AUTHORIZATION if (authArg != null) { string authArgToken = (authArg.OP == TK.STRING ? authArg.u.Token : null); ARC arc = Auth.Check(parse, type, authArgToken, null, null); if (arc != ARC.OK) { goto attach_end; } } #endif Vdbe v = parse.GetVdbe(); int regArgs = Expr.GetTempRange(parse, 4); Expr.Code(parse, filename, regArgs); Expr.Code(parse, dbName, regArgs + 1); Expr.Code(parse, key, regArgs + 2); Debug.Assert(v != null || ctx.MallocFailed); if (v != null) { v.AddOp3(OP.Function, 0, regArgs + 3 - func.Args, regArgs + 3); Debug.Assert(func.Args == -1 || (func.Args & 0xff) == func.Args); v.ChangeP5((byte)(func.Args)); v.ChangeP4(-1, func, Vdbe.P4T.FUNCDEF); // Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this statement only). For DETACH, set it to false (expire all existing statements). v.AddOp1(OP.Expire, (type == AUTH.ATTACH ? 1 : 0)); } attach_end: Expr.Delete(ctx, ref filename); Expr.Delete(ctx, ref dbName); Expr.Delete(ctx, ref key); }
public override Null Visit(FuncDef node) { // Don't visit the body, that's for ComputeTypesPass node.returnType.Accept(this); foreach (VarDef argDef in node.argDefs) { argDef.Accept(this); } // Construct a function type from the parsed return and argument types node.symbol.type = new FuncType { returnType = GetInstanceType(node.returnType, true), argTypes = node.argDefs.ConvertAll(arg => GetInstanceType(arg.type, false)) }; return null; }
public override Exit visitFuncDef(FuncDef func, Environment env) { Environment funcEnv = new Environment(); Exit exit = this.analyze(func.body, funcEnv); if (exit.HasFlag(Exit.NORMALLY)) { func.exitsNormally = true; if (!func.symbol.type.ReturnType.IsVoid) { log.error(func.Pos, messages.missingReturnStatement); } } return(0); }
public override object visitFuncDef(FuncDef func, WritableScope enclScope) { FuncSymbol fsym = makeFuncSymbol(func, enclScope); if (enclScope == symtab.topLevelSymbol.topScope && func.name == "main") { mainFuncFound = true; check.checkMainFunction(func.Pos, fsym); } if (check.checkUnique(func.Pos, fsym, enclScope)) { enclScope.enter(fsym); } return(null); }
/* The slow way of computing a sinc for the table. Should improve that some day */ private static short sinc(float cutoff, float x, int N, FuncDef window_func) { /*fprintf (stderr, "%f ", x);*/ float xx = x * cutoff; if (Math.Abs(x) < 1e-6f) { return(WORD2INT(32768.0f * cutoff)); } else if (Math.Abs(x) > .5f * N) { return(0); } /*FIXME: Can it really be any slower than this? */ return(WORD2INT(32768.0f * cutoff * (float)Math.Sin((float)Math.PI * xx) / ((float)Math.PI * xx) * (float)compute_func(Math.Abs(2.0f * x / N), window_func))); }
/* ** Called by the parser to compile an ATTACH statement. ** ** ATTACH p AS pDbname KEY pKey */ private static void sqlite3Attach(Parse pParse, Expr p, Expr pDbname, Expr pKey) { var attach_func = new FuncDef( 3, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ null, /* pUserData */ null, /* pNext */ attachFunc, /* xFunc */ null, /* xStep */ null, /* xFinalize */ "sqlite_attach", /* zName */ null /* pHash */ ); codeAttach(pParse, SQLITE_ATTACH, attach_func, p, p, pDbname, pKey); }
public override Null Visit(FuncDef node) { // Forbid default arguments for the moment foreach (VarDef arg in node.argDefs) { if (arg.value != null) { log.ErrorDefaultArgNotAllowed(arg.location); } } // Validate the presence of the function body if (node.info.inExternal != (node.block == null)) { log.ErrorFunctionBody(node.location, node.info.inExternal); } base.Visit(node); return null; }
public Object Functions(string name, IEval evaluator) { Object ret = BaseFunctions != null?BaseFunctions(name, evaluator) : new StringParser.ConvertError("() not recognised"); StringParser.ConvertError ce = ret as StringParser.ConvertError; if (ce != null && ce.ErrorValue.Contains("() not recognised")) { if (functions.ContainsKey(name)) { FuncDef fd = functions[name]; bool hasparas = fd.parameters.Length > 0; if (hasparas) { IEvalParaListType[] plist = new IEvalParaListType[fd.parameters.Length]; plist = Enumerable.Repeat(IEvalParaListType.All, fd.parameters.Length).ToArray(); List <Object> paras = evaluator.Parameters(name, fd.parameters.Length, plist); if (paras == null) // if error, stop and return error { return(evaluator.Value); } symbols.Push(); for (int i = 0; i < fd.parameters.Length; i++) // add to symbol list on next level the parameter names and values { System.Diagnostics.Debug.WriteLine(symbols.Levels + " " + name + " Push " + fd.parameters[i] + "=" + paras[i]); symbols.Add(fd.parameters[i], paras[i]); } } Eval evfunc = (Eval)evaluator.Clone(); // we need a fresh one just to evaluate this, but with the same configuration Object res = evfunc.Evaluate(fd.funcdef); // and evaluate if (hasparas) { symbols.Pop(); // clear back stack.. } return(res); } } return(ret); }
/* ** Called by the parser to compile a DETACH statement. ** ** DETACH pDbname */ private static void sqlite3Detach(Parse pParse, Expr pDbname) { var detach_func = new FuncDef( 1, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ null, /* pUserData */ null, /* pNext */ detachFunc, /* xFunc */ null, /* xStep */ null, /* xFinalize */ "sqlite_detach", /* zName */ null /* pHash */ ); codeAttach(pParse, SQLITE_DETACH, detach_func, pDbname, null, null, pDbname); }
public void AddFuncDef(string fname, string prms, long line) { fname = fname.Trim(); currentFunc = fname; if (funcDefs.ContainsKey(fname)) { funcDefs[fname].doubleDefined = true; funcDefs[fname].startingLine = line; } else { FuncDef fd = new FuncDef(); fd.name = fname; fd.paramNr = prms.Split(',').Length; fd.startingLine = line; funcDefs.Add(fname, fd); } }
public static void FuncDefInsert(FuncDefHash hash, FuncDef def) { int nameLength = def.Name.Length; int h = (char.ToLowerInvariant(def.Name[0]) + nameLength) % hash.data.Length; FuncDef other = FunctionSearch(hash, h, def.Name, nameLength); if (other != null) { Debug.Assert(other != def && other.Next != def); def.Next = other.Next; other.Next = def; } else { def.Next = null; def.Hash = hash[h]; hash[h] = def; } }
private FuncSymbol makeFuncSymbol(FuncDef func, WritableScope enclScope) { FuncSymbol fsym = new FuncSymbol(func.name, enclScope.owner, null); func.symbol = fsym; fsym.owner = enclScope.owner; // create scope for func parameters and local variables WritableScope funcScope = enclScope.subScope(fsym); fsym.scope = funcScope; fsym.parameters = new List <VarSymbol>(func.parameters.Count); FuncType ftype = signature(func.returnType, func.parameters, funcScope); ftype.symbol = fsym; fsym.type = ftype; return(fsym); }
/*8,24,40,56,80,104,128,160,200,256,320*/ private static double compute_func(float x, FuncDef func) { float y, frac; double interp0, interp1, interp2, interp3; int ind; y = x * func.oversample; ind = (int)Math.Floor(y); frac = (y - ind); /* CSE with handle the repeated powers */ interp3 = -0.1666666667 * frac + 0.1666666667 * (frac * frac * frac); interp2 = frac + 0.5 * (frac * frac) - 0.5 * (frac * frac * frac); /*interp[2] = 1.f - 0.5f*frac - frac*frac + 0.5f*frac*frac*frac;*/ interp0 = -0.3333333333 * frac + 0.5 * (frac * frac) - 0.1666666667 * (frac * frac * frac); /* Just to make sure we don't have rounding problems */ interp1 = 1.0f - interp3 - interp2 - interp0; /*sum = frac*accum[1] + (1-frac)*accum[2];*/ return(interp0 * func.table[ind] + interp1 * func.table[ind + 1] + interp2 * func.table[ind + 2] + interp3 * func.table[ind + 3]); }
public override Type visitStructDef(StructDef structDef, Environment env) { Environment newEnv = new Environment { scope = new CompoundScope(structDef.symbol.membersScope, env.scope), parent = env, enclStruct = structDef.symbol }; for (var i = 0; i < structDef.members.Count; i++) { Tree member = structDef.members[i]; if (member.Tag == Tag.FUNC_DEF) { FuncDef funcDef = (FuncDef)member; visitFuncDef(funcDef, newEnv); } } return(null); }
public string CheckForErrors() { string retval = ""; foreach (string fname in funcDefs.Keys) { FuncDef fd = funcDefs[fname]; if (fd.doubleDefined) { retval += "Line " + fd.startingLine + ": Function '" + fname + "' already defined\n"; } foreach (string vn in fd.varsUsage.Keys) { if (!fd.vars.ContainsKey(vn)) { retval += "Line " + fd.startingLine + ": Using undefined variable '" + vn + "'\n"; } else if (fd.vars[vn].line > fd.varsUsage[vn].line) { retval += "Line " + fd.startingLine + ": Using variable '" + vn + "' before it is actualy defined\n"; } } } foreach (FuncDef fd in funcCalls) { if (!funcDefs.ContainsKey(fd.name)) { retval += "Line " + fd.startingLine + ": Calling undefined function '" + fd.name + "'\n"; } else if (fd.paramNr != funcDefs[fd.name].paramNr) { retval += "Line " + fd.startingLine + ": Calling function '" + fd.name + "' with wrong number of parameters\n"; } } return(retval); }
public static RC MemFinalize(Mem mem, FuncDef func) { RC rc = RC.OK; if (C._ALWAYS(func != null && func.Finalize != null)) { Debug.Assert((mem.Flags & MEM.Null) != 0 || func == mem.u.Def); Debug.Assert(mem.Ctx == null || MutexEx.Held(mem.Ctx.Mutex)); //memset(&ctx, 0, sizeof(ctx)); FuncContext ctx = new FuncContext(); ctx.S.Flags = MEM.Null; ctx.S.Ctx = mem.Ctx; ctx.Mem = mem; ctx.Func = func; func.Finalize(ctx); // IMP: R-24505-23230 Debug.Assert((mem.Flags & MEM.Dyn) == 0 && mem.Del == null); C._tagfree(mem.Ctx, ref mem.Z_); //: mem->Malloc); ctx.S._memcpy(ref mem); rc = ctx.IsError; } return(rc); }
private void FuncHead(ref FuncDef function) { string first = "id int float"; this.SkipErrors(first); var lookaheadToken = this.TokenStream.Peek(); string lookahead = lookaheadToken.AToCCFormat(); if (first.HasToken(lookahead)) { this.ApplyDerivation("funcHead -> type optSR_AndID '(' fParams ')'"); function.ReturnType = Type(); var(scopeResolution, functionName) = OptSR_AndID(); function.ScopeResolution = scopeResolution; function.FunctionName = functionName; Match("("); function.Parameters = FParams(); Match(")"); } }
public override void Visit(FuncDef funcDef) { string funcName = funcDef.FunctionName; if (funcDef.ScopeResolution != null) { funcName = $"{funcDef.ScopeResolution.ID}::{funcName}"; } var entry = new TableEntry(funcName, Classification.Function, -1); entry.Link = new SymbolTable(); if (funcDef.Parameters != null) { foreach (var param in funcDef.Parameters) { entry.Link.Add(param.Entry, param.Location); } } if (funcDef.Implementation?.Table != null) { foreach (var varEntry in funcDef.Implementation.Table.GetAll()) { entry.Link.Add(varEntry, funcDef.Implementation.Location); } } entry.Type = funcDef.ReturnType + "-"; if (funcDef.Parameters != null) { entry.Type += string.Join(",", funcDef.Parameters.Where(val => val.Id != string.Empty).Select(val => val.Type + "[]".Repeat(val.Dimensions.Count))); } funcDef.Entry = entry; }
/* ** Insert a new FuncDef into a FuncDefHash hash table. */ static void sqlite3FuncDefInsert( FuncDefHash pHash, /* The hash table into which to insert */ FuncDef pDef /* The function definition to insert */ ) { FuncDef pOther; int nName = sqlite3Strlen30(pDef.zName); u8 c1 = (u8)pDef.zName[0]; int h = (sqlite3UpperToLower[c1] + nName) % ArraySize(pHash.a); pOther = functionSearch(pHash, h, pDef.zName, nName); if (pOther != null) { Debug.Assert(pOther != pDef && pOther.pNext != pDef); pDef.pNext = pOther.pNext; pOther.pNext = pDef; } else { pDef.pNext = null; pDef.pHash = pHash.a[h]; pHash.a[h] = pDef; } }
static void CodeAttach(Parse parse, AUTH type, FuncDef func, Expr authArg, Expr filename, Expr dbName, Expr key) { Context ctx = parse.Ctx; NameContext sName; sName = new NameContext(); sName.Parse = parse; if (ResolveAttachExpr(sName, filename) != RC.OK || ResolveAttachExpr(sName, dbName) != RC.OK || ResolveAttachExpr(sName, key) != RC.OK) { parse.Errs++; goto attach_end; } #if !OMIT_AUTHORIZATION if (authArg != null) { string authArgToken = (authArg.OP == TK.STRING ? authArg.u.Token : null); ARC arc = Auth.Check(parse, type, authArgToken, null, null); if (arc != ARC.OK) goto attach_end; } #endif Vdbe v = parse.GetVdbe(); int regArgs = Expr.GetTempRange(parse, 4); Expr.Code(parse, filename, regArgs); Expr.Code(parse, dbName, regArgs + 1); Expr.Code(parse, key, regArgs + 2); Debug.Assert(v != null || ctx.MallocFailed); if (v != null) { v.AddOp3(OP.Function, 0, regArgs + 3 - func.Args, regArgs + 3); Debug.Assert(func.Args == -1 || (func.Args & 0xff) == func.Args); v.ChangeP5((byte)(func.Args)); v.ChangeP4(-1, func, Vdbe.P4T.FUNCDEF); // Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this statement only). For DETACH, set it to false (expire all existing statements). v.AddOp1(OP.Expire, (type == AUTH.ATTACH ? 1 : 0)); } attach_end: Expr.Delete(ctx, ref filename); Expr.Delete(ctx, ref dbName); Expr.Delete(ctx, ref key); }
static int sqlite3VdbeMemFinalize (MemRef pMem, FuncDef pFunc) { return sqlite3VdbeMemFinalize(ref pMem.inner, pFunc); }
/* ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){ sqlite3DbFree(db, pDef); } }
/* ** Locate a user function given a name, a number of arguments and a flag ** indicating whether the function prefers UTF-16 over UTF-8. Return a ** pointer to the FuncDef structure that defines that function, or return ** NULL if the function does not exist. ** ** If the createFlag argument is true, then a new (blank) FuncDef ** structure is created and liked into the "db" structure if a ** no matching function previously existed. When createFlag is true ** and the nArg parameter is -1, then only a function that accepts ** any number of arguments will be returned. ** ** If createFlag is false and nArg is -1, then the first valid ** function found is returned. A function is valid if either xFunc ** or xStep is non-zero. ** ** If createFlag is false, then a function with the required name and ** number of arguments may be returned even if the eTextRep flag does not ** match that requested. */ static FuncDef sqlite3FindFunction( sqlite3 db, /* An open database */ string zName, /* Name of the function. Not null-terminated */ int nName, /* Number of characters in the name */ int nArg, /* Number of arguments. -1 means any number */ u8 enc, /* Preferred text encoding */ u8 createFlag /* Create new entry if true and does not otherwise exist */ ) { FuncDef p; /* Iterator variable */ FuncDef pBest = null; /* Best match found so far */ int bestScore = 0; int h; /* Hash value */ Debug.Assert( enc == SQLITE_UTF8 || enc == SQLITE_UTF16LE || enc == SQLITE_UTF16BE ); h = ( sqlite3UpperToLower[(u8)zName[0]] + nName ) % ArraySize( db.aFunc.a ); /* First search for a match amongst the application-defined functions. */ p = functionSearch( db.aFunc, h, zName, nName ); while ( p != null ) { int score = matchQuality( p, nArg, enc ); if ( score > bestScore ) { pBest = p; bestScore = score; } p = p.pNext; } /* If no match is found, search the built-in functions. ** ** If the SQLITE_PreferBuiltin flag is set, then search the built-in ** functions even if a prior app-defined function was found. And give ** priority to built-in functions. ** ** Except, if createFlag is true, that means that we are trying to ** install a new function. Whatever FuncDef structure is returned it will ** have fields overwritten with new information appropriate for the ** new function. But the FuncDefs for built-in functions are read-only. ** So we must not search for built-ins when creating a new function. */ if ( 0 == createFlag && ( pBest == null || ( db.flags & SQLITE_PreferBuiltin ) != 0 ) ) { #if SQLITE_OMIT_WSD FuncDefHash pHash = GLOBAL( FuncDefHash, sqlite3GlobalFunctions ); #else FuncDefHash pHash = sqlite3GlobalFunctions; #endif bestScore = 0; p = functionSearch( pHash, h, zName, nName ); while ( p != null ) { int score = matchQuality( p, nArg, enc ); if ( score > bestScore ) { pBest = p; bestScore = score; } p = p.pNext; } } /* If the createFlag parameter is true and the search did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ if ( createFlag != 0 && ( bestScore < 6 || pBest.nArg != nArg ) && ( pBest = new FuncDef() ) != null ) { //sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ //pBest.zName = (char *)&pBest[1]; pBest.nArg = (i16)nArg; pBest.iPrefEnc = enc; pBest.zName = zName; //memcpy(pBest.zName, zName, nName); //pBest.zName[nName] = 0; sqlite3FuncDefInsert( db.aFunc, pBest ); } if ( pBest != null && ( pBest.xStep != null || pBest.xFunc != null || createFlag != 0 ) ) { return pBest; } return null; }
/* During the search for the best function definition, this procedure ** is called to test how well the function passed as the first argument ** matches the request for a function with nArg arguments in a system ** that uses encoding enc. The value returned indicates how well the ** request is matched. A higher value indicates a better match. ** ** The returned value is always between 0 and 6, as follows: ** ** 0: Not a match, or if nArg<0 and the function is has no implementation. ** 1: A variable arguments function that prefers UTF-8 when a UTF-16 ** encoding is requested, or vice versa. ** 2: A variable arguments function that uses UTF-16BE when UTF-16LE is ** requested, or vice versa. ** 3: A variable arguments function using the same text encoding. ** 4: A function with the exact number of arguments requested that ** prefers UTF-8 when a UTF-16 encoding is requested, or vice versa. ** 5: A function with the exact number of arguments requested that ** prefers UTF-16LE when UTF-16BE is requested, or vice versa. ** 6: An exact match. ** */ static int matchQuality( FuncDef p, int nArg, int enc ) { int match = 0; if ( p.nArg == -1 || p.nArg == nArg || ( nArg == -1 && ( p.xFunc != null || p.xStep != null ) ) ) { match = 1; if ( p.nArg == nArg || nArg == -1 ) { match = 4; } if ( enc == p.iPrefEnc ) { match += 2; } else if ( ( enc == SQLITE_UTF16LE && p.iPrefEnc == SQLITE_UTF16BE ) || ( enc == SQLITE_UTF16BE && p.iPrefEnc == SQLITE_UTF16LE ) ) { match += 1; } } return match; }
public override Null Visit(FuncDef node) { // Don't initialize arguments node.block.Accept(this); return null; }
/* ** Invoke the destructor function associated with FuncDef p, if any. Except, ** if this is not the last copy of the function, do not invoke it. Multiple ** copies of a single function are created when create_function() is called ** with SQLITE_ANY as the encoding. */ static void functionDestroy( sqlite3 db, FuncDef p ) { FuncDestructor pDestructor = p.pDestructor; if ( pDestructor != null ) { pDestructor.nRef--; if ( pDestructor.nRef == 0 ) { //pDestructor.xDestroy( pDestructor.pUserData ); sqlite3DbFree( db, ref pDestructor ); } } }
public override Null Visit(FuncDef node) { // Make a new end node to start off the flow FlowNode root = new FlowNode(); nodeMap.Add(node, root); next.Set(root); node.block.Accept(this); for (int i = node.argDefs.Count - 1; i >= 0; i--) { node.argDefs[i].Accept(this); } roots.Add(next.Get()); return null; }
private double EvaluateBuiltInFunction(ref int position, FuncDef kind, int nbParams, double[] param, Stack <int> returnStack, Stack <double> valueStack) { switch (kind) { // each element equal to the first case FuncDef.Equal: if (nbParams < 2) { throw new Exception("equals ( = ) must have at least two things to compare"); } return(NanTags.EncodeBool(ListEquals(param))); // Each element smaller than the last case FuncDef.GreaterThan: if (nbParams < 2) { throw new Exception("greater than ( > ) must have at least two things to compare"); } return(NanTags.EncodeBool(FoldGreaterThan(param))); // Each element larger than the last case FuncDef.LessThan: if (nbParams < 2) { throw new Exception("less than ( < ) must have at least two things to compare"); } return(NanTags.EncodeBool(FoldLessThan(param))); // Each element DIFFERENT TO THE FIRST (does not check set uniqueness!) case FuncDef.NotEqual: if (nbParams < 2) { throw new Exception("not-equal ( <> ) must have at least two things to compare"); } return(NanTags.EncodeBool(!ListEquals(param))); case FuncDef.Assert: if (nbParams < 1) { return(NanTags.VoidReturn()); // assert nothing passes } var condition = param.ElementAt(0); if (_memory.CastBoolean(condition) == false) { var msg = ConcatList(param, 1); throw new Exception("Assertion failed: " + msg); } return(NanTags.VoidReturn()); case FuncDef.Random: if (nbParams < 1) { return(rnd.NextDouble()); // 0 params - any size } if (nbParams < 2) { return(rnd.Next(_memory.CastInt(param.ElementAt(0)))); // 1 param - max size } return(rnd.Next(_memory.CastInt(param.ElementAt(0)), _memory.CastInt(param.ElementAt(1)))); // 2 params - range case FuncDef.Eval: var reader = new SourceCodeTokeniser(); var statements = _memory.CastString(param.ElementAt(0)); var programTmp = reader.Read(statements, false); var bin = ToNanCodeCompiler.CompileRoot(programTmp, false); var interpreter = new ByteCodeInterpreter(); interpreter.Init(new RuntimeMemoryModel(bin, _memory.Variables), _input, _output, DebugSymbols); return(interpreter.Execute(false, _runningVerbose, false).Result); case FuncDef.Call: NanTags.DecodePointer(param.ElementAt(0), out var target, out var type); if (type != DataType.PtrString && type != DataType.PtrStaticString) { throw new Exception("Tried to call a function by name, but passed a '" + type + "' at " + position); } // this should be a string, but we need a function name hash -- so calculate it: var strName = _memory.DereferenceString(target); var functionNameHash = NanTags.GetCrushedName(strName); nbParams--; var newParam = param.Skip(1).ToArray(); return(EvaluateFunctionCall(ref position, functionNameHash, nbParams, newParam, returnStack, valueStack)); case FuncDef.LogicNot: if (nbParams != 1) { throw new Exception("'not' should be called with one argument"); } var bval = _memory.CastBoolean(param.ElementAt(0)); return(NanTags.EncodeBool(!bval)); case FuncDef.LogicOr: { bool more = nbParams > 0; int i = 0; while (more) { var bresult = _memory.CastBoolean(param.ElementAt(i)); if (bresult) { return(NanTags.EncodeBool(true)); } i++; more = i < nbParams; } return(NanTags.EncodeBool(false)); } case FuncDef.LogicAnd: { bool more = nbParams > 0; int i = 0; while (more) { var bresult = _memory.CastBoolean(param.ElementAt(i)); if (!bresult) { return(NanTags.EncodeBool(false)); } i++; more = i < nbParams; } return(NanTags.EncodeBool(true)); } case FuncDef.ReadKey: return(_memory.StoreStringAndGetReference(((char)_input.Read()).ToString())); case FuncDef.ReadLine: return(_memory.StoreStringAndGetReference(_input.ReadLine())); case FuncDef.Print: { string lastStr = null; foreach (var v in param) { lastStr = _memory.CastString(v); _output.Write(lastStr); } if (lastStr != "") { _output.WriteLine(); } } return(NanTags.VoidReturn()); case FuncDef.Substring: if (nbParams == 2) { var newString = _memory.CastString(param.ElementAt(0)).Substring(_memory.CastInt(param.ElementAt(1))); return(_memory.StoreStringAndGetReference(newString)); } else if (nbParams == 3) { int start = _memory.CastInt(param.ElementAt(1)); int length = _memory.CastInt(param.ElementAt(2)); string s = _memory.CastString(param.ElementAt(0)).Substring(start, length); return(_memory.StoreStringAndGetReference(s)); } else { throw new Exception("'Substring' should be called with 2 or 3 parameters"); } case FuncDef.Length: return(_memory.CastString(param.ElementAt(0)).Length); case FuncDef.Replace: if (nbParams != 3) { throw new Exception("'Replace' should be called with 3 parameters"); } string exp = _memory.CastString(param.ElementAt(0)); string oldValue = _memory.CastString(param.ElementAt(1)); string newValue = _memory.CastString(param.ElementAt(2)); exp = exp.Replace(oldValue, newValue); return(_memory.StoreStringAndGetReference(exp)); case FuncDef.Concat: var builder = new StringBuilder(); foreach (var v in param) { builder.Append(_memory.CastString(v)); } return(_memory.StoreStringAndGetReference(builder.ToString())); case FuncDef.UnitEmpty: { // valueless marker (like an empty object) return(NanTags.EncodeNonValue(NonValueType.Unit)); } case FuncDef.MathAdd: if (nbParams == 1) { return(param[0]); } return(param.ChainSum()); case FuncDef.MathSub: if (nbParams == 1) { return(-param[0]); } return(param.ChainDifference()); case FuncDef.MathProd: if (nbParams == 1) { throw new Exception("Uniary '*' is not supported"); } return(param.ChainProduct()); case FuncDef.MathDiv: if (nbParams == 1) { throw new Exception("Uniary '/' is not supported"); } return(param.ChainDivide()); case FuncDef.MathMod: if (nbParams == 1) { return(param[0] % 2); } return(param.ChainRemainder()); default: throw new Exception("Unrecognised built-in! Type = " + ((int)kind)); } }
public override Null Visit(FuncDef node) { inFunc = true; base.Visit(node); inFunc = false; // Check for a return value (flow must not reach the end of non-void functions) if (node.block != null && !(node.symbol.type.ReturnType() is VoidType) && builder.nodeMap[node].knowledge != null) { log.ErrorNotAllPathsReturnValue(node.location); } return null; }
public static FuncInfo Create(FuncDef fd, SolverAliases aliasOf) { return(CreateWithCachingInfo(fd, aliasOf, null)); }
FuncInfo(FuncDef fd, SolverAliases aliasOf, string cachingDomainParam = null) { name = fd.name; this.fd = fd; if (cachingDomainParam != null && fd.cachingExpiration != TimeSpan.Zero) { nCachingInps = 1; inputs = new string[fd.argsInfo.Length + nCachingInps]; int k = 0; inputs[k++] = cachingDomainParam; foreach (var arg in fd.argsInfo) { inputs[k++] = arg.ToString(); } } else { inputs = new string[fd.argsInfo.Length]; for (int i = 0; i < inputs.Length; i++) { var s = fd.argsInfo[i].ToString(); inputs[i] = aliasOf.GetRealName(s); } } int no = fd.resultsInfo.Length; outputs = new string[no]; var pureOuts = new List <string>(no); var inOuts = new List <string>(no); for (int i = 0; i < outputs.Length; i++) { var s = fd.resultsInfo[i].ToString(); var real = aliasOf.GetRealName(s); if (real != s && !inputs.Contains(real)) { if (fd.kind != FuncKind.Macro) { throw new SolverException(string.Format("Name conflict between alias '{0}' and output of function '{1}'", s, name)); } } outputs[i] = real; } foreach (var s in outputs) { if (Array.IndexOf <string>(inputs, s) < 0) { pureOuts.Add(s); } else { System.Diagnostics.Debug.Assert(ValueInfo.IsID(s), $"Only _ID parameters can be 'in/out' // {name}:{s}"); inOuts.Add(s); } } var pureIns = new List <string>(no); for (int i = 0; i < inputs.Length; i++) { var s = inputs[i]; if (Array.IndexOf <string>(outputs, s) < 0) { pureIns.Add(s); } } this.pureIns = pureIns.ToArray(); this.pureOuts = pureOuts.ToArray(); this.inOuts = inOuts.ToArray(); }
//FUNCDEF static int sqlite3VdbeAddOp4( Vdbe p, int op, int p1, int p2, int p3, FuncDef pP4, int p4type ) { union_p4 _p4 = new union_p4(); _p4.pFunc = pP4; int addr = sqlite3VdbeAddOp3( p, op, p1, p2, p3 ); sqlite3VdbeChangeP4( p, addr, _p4, p4type ); return addr; }
public void ChangeP4(int addr, CollSeq coll, int n) { ChangeP4(addr, new P4_t { Coll = coll }, n); } // P4_COLLSEQ public void ChangeP4(int addr, FuncDef func, int n) { ChangeP4(addr, new P4_t { Func = func }, n); } // P4_FUNCDEF
/* ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction( sqlite3 db, FuncDef pDef ) { if ( ALWAYS( pDef ) && ( pDef.flags & SQLITE_FUNC_EPHEM ) != 0 ) { pDef = null; sqlite3DbFree( db, ref pDef ); } }
/* ** Called by the parser to compile a DETACH statement. ** ** DETACH pDbname */ static void sqlite3Detach( Parse pParse, Expr pDbname ) { FuncDef detach_func = new FuncDef( 1, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ null, /* pUserData */ null, /* pNext */ detachFunc, /* xFunc */ null, /* xStep */ null, /* xFinalize */ "sqlite_detach", /* zName */ null /* pHash */ ); codeAttach( pParse, SQLITE_DETACH, detach_func, pDbname, null, null, pDbname ); }
/* ** 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; }
/* ** Called by the parser to compile an ATTACH statement. ** ** ATTACH p AS pDbname KEY pKey */ static void sqlite3Attach( Parse pParse, Expr p, Expr pDbname, Expr pKey ) { FuncDef attach_func = new FuncDef( 3, /* nArg */ SQLITE_UTF8, /* iPrefEnc */ 0, /* flags */ null, /* pUserData */ null, /* pNext */ attachFunc, /* xFunc */ null, /* xStep */ null, /* xFinalize */ "sqlite_attach", /* zName */ null /* pHash */ ); codeAttach( pParse, SQLITE_ATTACH, attach_func, p, p, pDbname, pKey ); }
public override void Visit(FuncDef funcDef) { // We don't need to handle free-functions. if (funcDef.ScopeResolution == null) { return; } // Make sure the class exists. var classScope = this.GlobalScope.Get($"{funcDef.ScopeResolution.ID}-{Classification.Class}"); if (classScope != null) { // Make sure the function exists. var function = classScope.Link.Get($"{funcDef.FunctionName}-{Classification.Function}"); if (function != null) { // Get the return type and the parameters. var types = function.Type.Split('-'); var returnType = types[0]; var parameters = types[1].Length == 0 ? new string[0] : types[1].Split(','); // Make sure the return type matches with the number of parameters if (funcDef.ReturnType == returnType) { if (funcDef.Parameters.Count == parameters.Count()) { bool valid = true; // Make sure each parameter matches. for (int i = 0; i < funcDef.Parameters.Count; i++) { string expectedType = parameters[i]; string receivedType = funcDef.Parameters[i].Type + "[]".Repeat(funcDef.Parameters[i].Dimensions.Count); if (expectedType == string.Empty) { expectedType = "no parameters"; } if (receivedType == string.Empty) { receivedType = "no parameters"; } // Apply pseudo type checking. if (expectedType != receivedType) { ErrorManager.Add($"Invalid parameter type: Expected {expectedType}, got {receivedType}", funcDef.Parameters[i].Location); valid = false; break; } } if (valid) { function.Link = funcDef.Entry.Link; } } else { ErrorManager.Add($"Invalid amount of parameters. Expected {parameters.Length}. Got {funcDef.Parameters.Count}.", funcDef.Location); } } else { ErrorManager.Add($"Invalid return type: Expected {returnType}, got {funcDef.ReturnType}", funcDef.Location); } } else { ErrorManager.Add($"The class {funcDef.ScopeResolution.ID} does not define a function {funcDef.FunctionName}.", funcDef.Location); } } else { ErrorManager.Add($"The class {funcDef.ScopeResolution.ID} could not be resolved to a type.", funcDef.ScopeResolution.Location); } }
public static BaseTree Parse(List <IElement> sourceTokens, ScriptFile sf, ScriptInfo scriptInfo) { BaseTree tree = new BaseTree(sourceTokens); tree._sf = sf; MoveInfo parser = new MoveInfo(tree, SearchTree.ChildrenBlock, 0, sf); ParsingInfo parsingInfo = new ParsingInfo(sf); // parse all groups MoveInfo groupInfo = new MoveInfo(tree, SearchTree.ContentTree, 0, sf); IElement cur = groupInfo.Find(SearchDirection.LeftToRight, SearchVisibility.Visible); while (cur != null) { Group.Check(groupInfo, parsingInfo, scriptInfo); cur = groupInfo.FindNextBlack(SearchDirection.LeftToRight); } // parse delegate call [[delegate]] MoveInfo delegateInfo = new MoveInfo(tree, SearchTree.ContentTree, 0, sf); cur = delegateInfo.Find(SearchDirection.LeftToRight, SearchVisibility.Visible); while (cur != null) { DelegateCallGroup.Check(delegateInfo, parsingInfo, scriptInfo); cur = delegateInfo.FindNextBlack(SearchDirection.LeftToRight); } // create parse tree MoveInfo contentInfo = new MoveInfo(parser); cur = contentInfo.Current; while (cur != null) { if (!cur.Visible) { XMLBlock.Check(contentInfo, parsingInfo, scriptInfo); cur = contentInfo.Move(SearchDirection.LeftToRight); } else { if (DevCode.Check(contentInfo, parsingInfo, scriptInfo) || PreProcessorInclude.Check(contentInfo, parsingInfo, scriptInfo) || PreProcessorRegion.Check(contentInfo, parsingInfo, scriptInfo) || AccessModifier.Check(contentInfo, parsingInfo, scriptInfo) || SealedModifier.Check(contentInfo, parsingInfo, scriptInfo) || UsingDef.Check(contentInfo, parsingInfo, scriptInfo) || OverwriteConstDef.Check(contentInfo, parsingInfo, scriptInfo) || FuncDef.Check(contentInfo, parsingInfo, scriptInfo) || ConstDef.Check(contentInfo, parsingInfo, scriptInfo) ) { cur = contentInfo.Move(SearchDirection.LeftToRight); } else { throw new SyntaxException("Unknown token", contentInfo.GetErrorInfo()); } } } tree.IncludeDefList = parsingInfo.IncludeDefList; tree.FuncDefList = parsingInfo.FuncDefList; tree.ConstDefList = parsingInfo.ConstDefList; tree.UsingDefList = parsingInfo.UsingDefList; tree.OverwriteConstDefList = parsingInfo.OverwriteConstDefList; return(tree); }
/* ** This procedure generates VDBE code for a single invocation of either the ** sqlite_detach() or sqlite_attach() SQL user functions. */ static void codeAttach( Parse pParse, /* The parser context */ int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ FuncDef pFunc, /* FuncDef wrapper for detachFunc() or attachFunc() */ Expr pAuthArg, /* Expression to pass to authorization callback */ Expr pFilename, /* Name of database file */ Expr pDbname, /* Name of the database to use internally */ Expr pKey /* Database key for encryption extension */ ) { int rc; NameContext sName; Vdbe v; sqlite3 db = pParse.db; int regArgs; sName = new NameContext();// memset( &sName, 0, sizeof(NameContext)); sName.pParse = pParse; if ( SQLITE_OK != ( rc = resolveAttachExpr( sName, pFilename ) ) || SQLITE_OK != ( rc = resolveAttachExpr( sName, pDbname ) ) || SQLITE_OK != ( rc = resolveAttachExpr( sName, pKey ) ) ) { pParse.nErr++; goto attach_end; } #if !SQLITE_OMIT_AUTHORIZATION if( pAuthArg ){ char *zAuthArg; if( pAuthArg->op==TK_STRING ){ zAuthArg = pAuthArg->u.zToken; }else{ zAuthArg = 0; } rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); if(rc!=SQLITE_OK ){ goto attach_end; } } #endif //* SQLITE_OMIT_AUTHORIZATION */ v = sqlite3GetVdbe( pParse ); regArgs = sqlite3GetTempRange( pParse, 4 ); sqlite3ExprCode( pParse, pFilename, regArgs ); sqlite3ExprCode( pParse, pDbname, regArgs + 1 ); sqlite3ExprCode( pParse, pKey, regArgs + 2 ); Debug.Assert( v != null /*|| db.mallocFailed != 0 */ ); if ( v != null ) { sqlite3VdbeAddOp3( v, OP_Function, 0, regArgs + 3 - pFunc.nArg, regArgs + 3 ); Debug.Assert( pFunc.nArg == -1 || ( pFunc.nArg & 0xff ) == pFunc.nArg ); sqlite3VdbeChangeP5( v, (u8)( pFunc.nArg ) ); sqlite3VdbeChangeP4( v, -1, pFunc, P4_FUNCDEF ); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). */ sqlite3VdbeAddOp1( v, OP_Expire, ( type == SQLITE_ATTACH ) ? 1 : 0 ); } attach_end: sqlite3ExprDelete( db, ref pFilename ); sqlite3ExprDelete( db, ref pDbname ); sqlite3ExprDelete( db, ref pKey ); }
static void FreeEphemeralFunction(Context ctx, FuncDef def) { if (C._ALWAYS(def != null) && (def.Flags & FUNC.EPHEM) != 0) C._tagfree(ctx, ref def); }
public override Null Visit(FuncDef node) { // Special-case void types for return types if (node.returnType is TypeExpr && ((TypeExpr)node.returnType).type is VoidType) { node.returnType.computedType = new MetaType { instanceType = ((TypeExpr)node.returnType).type }; } else { node.returnType.Accept(this); } VisitAll(node.argDefs); if (node.block != null) { node.block.Accept(this); } return null; }
static RantFuncs() { F = new Dictionary <string, FuncDef>(StringComparer.InvariantCultureIgnoreCase); // Repeaters, probability, and block attributes F["rep"] = F["r"] = new FuncSig(Repeat, ParamFlags.None); F["sep"] = F["s"] = new FuncSig(Separator, ParamFlags.Code); F["before"] = new FuncSig(Before, ParamFlags.Code); F["after"] = new FuncSig(After, ParamFlags.Code); F["chance"] = new FuncSig(Chance, ParamFlags.None); F["break"] = new FuncSig(Break); F["repnum"] = F["rn"] = new FuncSig(RepNum); F["repindex"] = F["ri"] = new FuncSig(RepIndex); F["repcount"] = F["rc"] = new FuncSig(RepCount); // Synchronizers F["sync"] = F["x"] = new FuncDef( new FuncSig(SyncCreateApply, ParamFlags.None, ParamFlags.None), new FuncSig(SyncApply, ParamFlags.None) ); F["xreset"] = new FuncSig(SyncReset, ParamFlags.None); F["xseed"] = new FuncSig(SyncReseed, ParamFlags.None, ParamFlags.None); F["xnone"] = new FuncSig(Desync); F["xnew"] = new FuncSig(SyncCreate, ParamFlags.None, ParamFlags.None); F["xpin"] = new FuncSig(Pin, ParamFlags.None); F["xunpin"] = new FuncSig(Unpin, ParamFlags.None); F["xstep"] = new FuncSig(Step, ParamFlags.None); // RNG manipulation F["branch"] = F["b"] = new FuncDef( new FuncSig(Branch, ParamFlags.None), new FuncSig(BranchScope, ParamFlags.None, ParamFlags.Code) ); F["merge"] = F["m"] = new FuncSig(Merge); F["generation"] = F["g"] = new FuncDef(new FuncSig(Generation), new FuncSig(GenerationSet, ParamFlags.None)); // Repeater conditionals F["first"] = new FuncSig(First, ParamFlags.Code); F["last"] = new FuncSig(Last, ParamFlags.Code); F["middle"] = new FuncSig(Middle, ParamFlags.Code); F["notfirst"] = new FuncSig(NotFirst, ParamFlags.Code); F["notlast"] = new FuncSig(NotLast, ParamFlags.Code); F["notmiddle"] = new FuncSig(NotMiddle, ParamFlags.Code); F["odd"] = new FuncSig(Odd, ParamFlags.Code); F["even"] = new FuncSig(Even, ParamFlags.Code); F["nth"] = new FuncDef( new FuncSig(Nth, ParamFlags.None, ParamFlags.None, ParamFlags.Code), new FuncSig(NthSimple, ParamFlags.None, ParamFlags.Code) ); // Quantifier conditionals F["alt"] = new FuncSig(Alt, ParamFlags.Code, ParamFlags.Code); F["any"] = new FuncSig(Any, ParamFlags.Code, ParamFlags.Code); // Replacers F["match"] = new FuncSig(ReplaceMatch); F["group"] = new FuncSig(ReplaceGroup, ParamFlags.None); // Subrotuine interaction F["arg"] = new FuncSig(Arg, ParamFlags.None); // Formatting F["numfmt"] = new FuncSig(NumFmt, ParamFlags.None); F["caps"] = F["case"] = new FuncSig(Caps, ParamFlags.None); // TODO: [caps] is deprecated. Remove it eventually. F["capsinfer"] = new FuncSig(CapsInfer, ParamFlags.None); // Channels F["out"] = new FuncSig(Out, ParamFlags.None, ParamFlags.None); F["close"] = new FuncSig(Close, ParamFlags.None); // External interaction F["extern"] = F["ext"] = new FuncSig(Extern, ParamFlags.None, ParamFlags.Multi); // Markers and targets F["mark"] = new FuncSig(Mark, ParamFlags.None); F["dist"] = new FuncSig(Dist, ParamFlags.None, ParamFlags.None); F["get"] = new FuncSig(Get, ParamFlags.None); F["send"] = new FuncSig(Send, ParamFlags.None, ParamFlags.None); F["osend"] = new FuncSig(SendOverwrite, ParamFlags.None, ParamFlags.None); F["clrt"] = new FuncSig(ClearTarget, ParamFlags.None); // String generation, manipulation, and analysis F["len"] = new FuncSig(Length, ParamFlags.None); F["char"] = new FuncDef( new FuncSig(Character, ParamFlags.None), new FuncSig(CharacterMulti, ParamFlags.None, ParamFlags.None)); F["num"] = F["n"] = new FuncSig(Number, ParamFlags.None, ParamFlags.None); F["dec"] = new FuncSig(NumberDec); // Flags F["define"] = new FuncSig(DefineFlag, ParamFlags.None | ParamFlags.Multi); F["undef"] = new FuncSig(UndefineFlag, ParamFlags.None | ParamFlags.Multi); F["ifdef"] = new FuncSig(IfDef, ParamFlags.None, ParamFlags.Code); F["ifndef"] = new FuncSig(IfNDef, ParamFlags.None, ParamFlags.Code); F["else"] = new FuncSig(Else, ParamFlags.Code); // Comparisons F["cmp"] = new FuncSig(Compare, ParamFlags.None, ParamFlags.None, ParamFlags.Code); F["is"] = new FuncSig(CmpIs, ParamFlags.None, ParamFlags.Code); // Misc F["src"] = new FuncSig(Src); }
/* ** Insert a new FuncDef into a FuncDefHash hash table. */ static void sqlite3FuncDefInsert( FuncDefHash pHash, /* The hash table into which to insert */ FuncDef pDef /* The function definition to insert */ ) { FuncDef pOther; int nName = sqlite3Strlen30( pDef.zName ); u8 c1 = (u8)pDef.zName[0]; int h = ( sqlite3UpperToLower[c1] + nName ) % ArraySize( pHash.a ); pOther = functionSearch( pHash, h, pDef.zName, nName ); if ( pOther != null ) { Debug.Assert( pOther != pDef && pOther.pNext != pDef ); pDef.pNext = pOther.pNext; pOther.pNext = pDef; } else { pDef.pNext = null; pDef.pHash = pHash.a[h]; pHash.a[h] = pDef; } }
public void Add(string name, string[] plist, string f) { functions[name] = new FuncDef(name, plist, f); }
/* ** This procedure generates VDBE code for a single invocation of either the ** sqlite_detach() or sqlite_attach() SQL user functions. */ static void codeAttach( Parse pParse, /* The parser context */ int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ FuncDef pFunc, /* FuncDef wrapper for detachFunc() or attachFunc() */ Expr pAuthArg, /* Expression to pass to authorization callback */ Expr pFilename, /* Name of database file */ Expr pDbname, /* Name of the database to use internally */ Expr pKey /* Database key for encryption extension */ ) { int rc; NameContext sName; Vdbe v; sqlite3 db = pParse.db; int regArgs; sName = new NameContext();// memset( &sName, 0, sizeof(NameContext)); sName.pParse = pParse; if ( SQLITE_OK != (rc = resolveAttachExpr(sName, pFilename)) || SQLITE_OK != (rc = resolveAttachExpr(sName, pDbname)) || SQLITE_OK != (rc = resolveAttachExpr(sName, pKey)) ) { pParse.nErr++; goto attach_end; } #if !SQLITE_OMIT_AUTHORIZATION if (pAuthArg) { char *zAuthArg = pAuthArg->u.zToken; if (NEVER(zAuthArg == 0)) { goto attach_end; } rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); if (rc != SQLITE_OK) { goto attach_end; } } #endif //* SQLITE_OMIT_AUTHORIZATION */ v = sqlite3GetVdbe(pParse); regArgs = sqlite3GetTempRange(pParse, 4); sqlite3ExprCode(pParse, pFilename, regArgs); sqlite3ExprCode(pParse, pDbname, regArgs + 1); sqlite3ExprCode(pParse, pKey, regArgs + 2); Debug.Assert(v != null /*|| db.mallocFailed != 0 */); if (v != null) { sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs + 3 - pFunc.nArg, regArgs + 3); Debug.Assert(pFunc.nArg == -1 || (pFunc.nArg & 0xff) == pFunc.nArg); sqlite3VdbeChangeP5(v, (u8)(pFunc.nArg)); sqlite3VdbeChangeP4(v, -1, pFunc, P4_FUNCDEF); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). */ sqlite3VdbeAddOp1(v, OP_Expire, (type == SQLITE_ATTACH) ? 1 : 0); } attach_end: sqlite3ExprDelete(db, ref pFilename); sqlite3ExprDelete(db, ref pDbname); sqlite3ExprDelete(db, ref pKey); }
/// <summary> /// This procedure generates VDBE code for a single invocation of either the /// sqlite_detach() or sqlite_attach() SQL user functions. /// </summary> /// <param name='pParse'> /// The parser context /// </param> /// <param name='type'> /// Either SQLITE_ATTACH or SQLITE_DETACH /// </param> /// <param name='pFunc'> /// FuncDef wrapper for detachFunc() or attachFunc() /// </param> /// <param name='pAuthArg'> /// Expression to pass to authorization callback /// </param> /// <param name='pFilename'> /// Name of database file /// </param> /// <param name='pDbname'> /// Name of the database to use internally /// </param> /// <param name='pKey'> /// Database key for encryption extension /// </param> static void codeAttach( Parse pParse, int type, FuncDef pFunc, Expr pAuthArg, Expr pFilename, Expr pDbname, Expr pKey ) { NameContext sName; Vdbe v; sqlite3 db = pParse.db; int regArgs; sName = new NameContext();// memset( &sName, 0, sizeof(NameContext)); sName.pParse = pParse; if ( SQLITE_OK != (resolveAttachExpr(sName, pFilename)) || SQLITE_OK != (resolveAttachExpr(sName, pDbname)) || SQLITE_OK != (resolveAttachExpr(sName, pKey)) ) { pParse.nErr++; goto attach_end; } #if !SQLITE_OMIT_AUTHORIZATION if( pAuthArg ){ char *zAuthArg; if( pAuthArg->op==TK_STRING ){ zAuthArg = pAuthArg->u.zToken; }else{ zAuthArg = 0; } rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); if(rc!=SQLITE_OK ){ goto attach_end; } } #endif //* SQLITE_OMIT_AUTHORIZATION */ v = sqlite3GetVdbe(pParse); regArgs = sqlite3GetTempRange(pParse, 4); sqlite3ExprCode(pParse, pFilename, regArgs); sqlite3ExprCode(pParse, pDbname, regArgs + 1); sqlite3ExprCode(pParse, pKey, regArgs + 2); Debug.Assert(v != null /*|| db.mallocFailed != 0 */ ); if (v != null) { sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs + 3 - pFunc.nArg, regArgs + 3); Debug.Assert(pFunc.nArg == -1 || (pFunc.nArg & 0xff) == pFunc.nArg); sqlite3VdbeChangeP5(v, (u8)(pFunc.nArg)); sqlite3VdbeChangeP4(v, -1, pFunc, P4_FUNCDEF); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). */ sqlite3VdbeAddOp1(v, OP_Expire, (type == SQLITE_ATTACH) ? 1 : 0); } attach_end: sqlite3ExprDelete(db, ref pFilename); sqlite3ExprDelete(db, ref pDbname); sqlite3ExprDelete(db, ref pKey); }
/* ** 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); }
public void Defun(FuncBase func) { FuncDef def; if (!m_func.TryGetValue(func.Name.ID, out def)) { def = new FuncDef(func); m_func.Add(def.ID, def); } else def.Overload(func); }
static WRC ResolveExprStep(Walker walker, Expr expr) { NameContext nc = walker.u.NC; Debug.Assert(nc != null); Parse parse = nc.Parse; Debug.Assert(parse == walker.Parse); if (E.ExprHasAnyProperty(expr, EP.Resolved)) { return(WRC.Prune); } E.ExprSetProperty(expr, EP.Resolved); #if !NDEBUG if (nc.SrcList != null && nc.SrcList.Allocs > 0) { SrcList srcList = nc.SrcList; for (int i = 0; i < nc.SrcList.Srcs; i++) { Debug.Assert(srcList.Ids[i].Cursor >= 0 && srcList.Ids[i].Cursor < parse.Tabs); } } #endif switch (expr.OP) { #if ENABLE_UPDATE_DELETE_LIMIT && !OMIT_SUBQUERY // The special operator TK_ROW means use the rowid for the first column in the FROM clause. This is used by the LIMIT and ORDER BY // clause processing on UPDATE and DELETE statements. case TK.ROW: { SrcList srcList = nc.SrcList; Debug.Assert(srcList != null && srcList.Srcs == 1); SrcList.SrcListItem item = srcList.Ids[0]; expr.OP = TK.COLUMN; expr.Table = item.Table; expr.TableId = item.Cursor; expr.ColumnIdx = -1; expr.Aff = AFF.INTEGER; break; } #endif case TK.ID: // A lone identifier is the name of a column. { return(LookupName(parse, null, null, expr.u.Token, nc, expr)); } case TK.DOT: // A table name and column name: ID.ID Or a database, table and column: ID.ID.ID { string columnName; string tableName; string dbName; // if (srcList == nullptr) break; Expr right = expr.Right; if (right.OP == TK.ID) { dbName = null; tableName = expr.Left.u.Token; columnName = right.u.Token; } else { Debug.Assert(right.OP == TK.DOT); dbName = expr.Left.u.Token; tableName = right.Left.u.Token; columnName = right.Right.u.Token; } return(LookupName(parse, dbName, tableName, columnName, nc, expr)); } case TK.CONST_FUNC: case TK.FUNCTION: // Resolve function names { ExprList list = expr.x.List; // The argument list int n = (list != null ? list.Exprs : 0); // Number of arguments bool noSuchFunc = false; // True if no such function exists bool wrongNumArgs = false; // True if wrong number of arguments bool isAgg = false; // True if is an aggregate function TEXTENCODE encode = E.CTXENCODE(parse.Ctx); // The database encoding C.ASSERTCOVERAGE(expr.OP == TK.CONST_FUNC); Debug.Assert(!E.ExprHasProperty(expr, EP.xIsSelect)); string id = expr.u.Token; // The function name. int idLength = id.Length; // Number of characters in function name FuncDef def = Callback.FindFunction(parse.Ctx, id, idLength, n, encode, false); // Information about the function if (def == null) { def = Callback.FindFunction(parse.Ctx, id, idLength, -2, encode, false); if (def == null) { noSuchFunc = true; } else { wrongNumArgs = true; } } else { isAgg = (def.Func == null); } #if !OMIT_AUTHORIZATION if (def != null) { ARC auth = Auth.Check(parse, AUTH.FUNCTION, null, def.Name, null); // Authorization to use the function if (auth != ARC.OK) { if (auth == ARC.DENY) { parse.ErrorMsg("not authorized to use function: %s", def.Name); nc.Errs++; } expr.OP = TK.NULL; return(WRC.Prune); } } #endif if (isAgg && (nc.NCFlags & NC.AllowAgg) == 0) { parse.ErrorMsg("misuse of aggregate function %.*s()", idLength, id); nc.Errs++; isAgg = false; } else if (noSuchFunc && !ctx.Init.Busy) { parse.ErrorMsg("no such function: %.*s", idLength, id); nc.Errs++; } else if (wrongNumArgs) { parse.ErrorMsg("wrong number of arguments to function %.*s()", idLength, id); nc.Errs++; } if (isAgg) { nc.NCFlags &= ~NC.AllowAgg; } walker.WalkExprList(list); if (isAgg) { NameContext nc2 = nc; expr.OP = TK.AGG_FUNCTION; expr.OP2 = 0; while (nc2 != null && !expr.FunctionUsesThisSrc(nc2.SrcList)) { expr.OP2++; nc2 = nc2.Next; } if (nc2 != null) { nc2.NCFlags |= NC.HasAgg; } nc.NCFlags |= NC.AllowAgg; } // FIX ME: Compute pExpr->affinity based on the expected return type of the function return(WRC.Prune); } #if !OMIT_SUBQUERY case TK.SELECT: case TK.EXISTS: { C.ASSERTCOVERAGE(expr.OP == TK.EXISTS); goto case TK.IN; } #endif case TK.IN: { C.ASSERTCOVERAGE(expr.OP == TK.IN); if (E.ExprHasProperty(expr, EP.xIsSelect)) { int refs = nc.Refs; #if !OMIT_CHECK if ((nc.NCFlags & NC.IsCheck) != 0) { parse.ErrorMsg("subqueries prohibited in CHECK constraints"); } #endif walker.WalkSelect(expr.x.Select); Debug.Assert(nc.Refs >= refs); if (refs != nc.Refs) { E.ExprSetProperty(expr, EP.VarSelect); } } break; } #if !OMIT_CHECK case TK.VARIABLE: { if ((nc.NCFlags & NC.IsCheck) != 0) { parse.ErrorMsg("parameters prohibited in CHECK constraints"); } break; } #endif } return(parse.Errs != 0 || parse.Ctx.MallocFailed ? WRC.Abort : WRC.Continue); }
//P4_FUNCDEF static void sqlite3VdbeChangeP4( Vdbe p, int addr, FuncDef pFunc, int n ) { union_p4 _p4 = new union_p4(); _p4.pFunc = pFunc; sqlite3VdbeChangeP4( p, addr, _p4, n ); }
public static RC MemFinalize(Mem mem, FuncDef func) { RC rc = RC.OK; if (C._ALWAYS(func != null && func.Finalize != null)) { Debug.Assert((mem.Flags & MEM.Null) != 0 || func == mem.u.Def); Debug.Assert(mem.Ctx == null || MutexEx.Held(mem.Ctx.Mutex)); //memset(&ctx, 0, sizeof(ctx)); FuncContext ctx = new FuncContext(); ctx.S.Flags = MEM.Null; ctx.S.Ctx = mem.Ctx; ctx.Mem = mem; ctx.Func = func; func.Finalize(ctx); // IMP: R-24505-23230 Debug.Assert((mem.Flags & MEM.Dyn) == 0 && mem.Del == null); C._tagfree(mem.Ctx, ref mem.Z_); //: mem->Malloc); ctx.S._memcpy(ref mem); rc = ctx.IsError; } return rc; }
public static FuncDef OverloadFunction(Context ctx, FuncDef def, int argsLength, Expr expr) { // Check to see the left operand is a column in a virtual table if (C._NEVER(expr == null)) { return(def); } if (expr.OP != TK.COLUMN) { return(def); } Table table = expr.Table; if (C._NEVER(table == null)) { return(def); } if ((table.TabFlags & TF.Virtual) == 0) { return(def); } IVTable ivtable = GetVTable(ctx, table).IVTable; Debug.Assert(ivtable != null); Debug.Assert(ivtable.IModule != null); ITableModule imodule = (ITableModule)ivtable.IModule; if (imodule.FindFunction == null) { return(def); } // Call the xFindFunction method on the virtual table implementation to see if the implementation wants to overload this function string lowerName = def.Name; RC rc = RC.OK; Action <FuncContext, int, Mem[]> func = null; object[] args = null; if (lowerName != null) { lowerName = lowerName.ToLowerInvariant(); rc = imodule.FindFunction(ivtable, argsLength, lowerName, func, args); C._tagfree(ctx, ref lowerName); } if (rc == RC.OK) { return(def); } // Create a new ephemeral function definition for the overloaded function FuncDef newFunc = new FuncDef();//: (FuncDef*)_tagalloc(ctx, sizeof(FuncDef) + _strlen30(def->Name) + 1, true); if (newFunc == null) { return(def); } newFunc = def._memcpy(); newFunc.Name = def.Name; newFunc.Func = func; newFunc.UserData = args; newFunc.Flags |= FUNC.EPHEM; return(newFunc); }
/* ** Locate a user function given a name, a number of arguments and a flag ** indicating whether the function prefers UTF-16 over UTF-8. Return a ** pointer to the FuncDef structure that defines that function, or return ** NULL if the function does not exist. ** ** If the createFlag argument is true, then a new (blank) FuncDef ** structure is created and liked into the "db" structure if a ** no matching function previously existed. When createFlag is true ** and the nArg parameter is -1, then only a function that accepts ** any number of arguments will be returned. ** ** If createFlag is false and nArg is -1, then the first valid ** function found is returned. A function is valid if either xFunc ** or xStep is non-zero. ** ** If createFlag is false, then a function with the required name and ** number of arguments may be returned even if the eTextRep flag does not ** match that requested. */ static FuncDef sqlite3FindFunction( sqlite3 db, /* An open database */ string zName, /* Name of the function. Not null-terminated */ int nName, /* Number of characters in the name */ int nArg, /* Number of arguments. -1 means any number */ u8 enc, /* Preferred text encoding */ u8 createFlag /* Create new entry if true and does not otherwise exist */ ) { FuncDef p; /* Iterator variable */ FuncDef pBest = null; /* Best match found so far */ int bestScore = 0; int h; /* Hash value */ Debug.Assert(enc == SQLITE_UTF8 || enc == SQLITE_UTF16LE || enc == SQLITE_UTF16BE); h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db.aFunc.a); /* First search for a match amongst the application-defined functions. */ p = functionSearch(db.aFunc, h, zName, nName); while (p != null) { int score = matchQuality(p, nArg, enc); if (score > bestScore) { pBest = p; bestScore = score; } p = p.pNext; } /* If no match is found, search the built-in functions. ** ** If the SQLITE_PreferBuiltin flag is set, then search the built-in ** functions even if a prior app-defined function was found. And give ** priority to built-in functions. ** ** Except, if createFlag is true, that means that we are trying to ** install a new function. Whatever FuncDef structure is returned it will ** have fields overwritten with new information appropriate for the ** new function. But the FuncDefs for built-in functions are read-only. ** So we must not search for built-ins when creating a new function. */ if (0 == createFlag && (pBest == null || (db.flags & SQLITE_PreferBuiltin) != 0)) { #if SQLITE_OMIT_WSD FuncDefHash pHash = GLOBAL(FuncDefHash, sqlite3GlobalFunctions); #else FuncDefHash pHash = sqlite3GlobalFunctions; #endif bestScore = 0; p = functionSearch(pHash, h, zName, nName); while (p != null) { int score = matchQuality(p, nArg, enc); if (score > bestScore) { pBest = p; bestScore = score; } p = p.pNext; } } /* If the createFlag parameter is true and the search did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ if (createFlag != 0 && (bestScore < 6 || pBest.nArg != nArg) && (pBest = new FuncDef()) != null) { //sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ //pBest.zName = (char *)&pBest[1]; pBest.nArg = (i16)nArg; pBest.iPrefEnc = enc; pBest.zName = zName; //memcpy(pBest.zName, zName, nName); //pBest.zName[nName] = 0; sqlite3FuncDefInsert(db.aFunc, pBest); } if (pBest != null && (pBest.xStep != null || pBest.xFunc != null || createFlag != 0)) { return(pBest); } return(null); }
/// <summary> /// Create definitions of loading functions from specified SQL query /// </summary> /// <param name="funcNamesPrefix">Optional prefix for functions names. If null or empty, first table from 'FROM' clause is used</param> /// <param name="actualityInDays">Used to restrict the minimum queried timestamp // :MIN_TIME = :BEG_TIME-actualityInDays</param> /// <param name="queryText">SQL query text. Only some subset of SQL is supported /// (all sources in FROM cluase must have aliases, all fields in SELECT must be specified with source aliases, subqueries is not tested, etc)</param> /// <returns>Enumeration of pairs (func_name, loading function definition)</returns> internal static IEnumerable <FuncDef> FuncDefsForSql(Preprocessing.SqlFuncPreprocessingCtx c) { var sql = SqlParse.Do(c.queryText, SqlExpr.Options.EmptyFromPossible); sql = c.PostProc(sql); if (sql == null) { yield break; } var actuality = TimeSpan.FromDays((c.actualityInDays < 0) ? Attr.defaultActualityDays : c.actualityInDays); if (string.IsNullOrEmpty(c.funcNamesPrefix)) { c.funcNamesPrefix = sql.sources[0].expr.ToString(); } // generate list of results bool timedQuery = false; bool withSeparator = false; ValueInfo[] resultsInfo; { int n = sql.results.Length; var lst = new List <ValueInfo>(n); for (int i = 0; i < n; i++) { var d = sql.results[i].alias;//.ToUpperInvariant(); if (d == nameof(START_TIME)) { timedQuery = timedQuery || i == 1; } else if (d == nameof(END_TIME) || d == nameof(END_TIME__DT)) { //if (d.Length == nameof(END_TIME).Length) // timedQuery = timedQuery || i == 2; } else if (d == nameof(INS_OUTS_SEPARATOR)) { withSeparator = true; } else { //if (d.Length > 30) // throw new Generator.Exception($"SQL identifier too long (max 30, but {d.Length} chars in \"{d}\")"); var vi = ValueInfo.Create(d, defaultLocation: c.DefaultLocationForValueInfo); int DL = vi.DescriptorLength(); if (DL > 30) { throw new Generator.Exception($"SQL identifier too long (max 30, but {DL} chars in \"{vi}\")"); } lst.Add(vi); } } resultsInfo = lst.ToArray(); } var dbConnName = c.tblAttrs.GetString(Attr.Tbl.DbConnName) ?? c.ldr.dbConnValueName; #region Some query with INS_OUTS_SEPARATOR column if (withSeparator || !timedQuery || (c.ldr.forKinds & DbFuncType.Raw) != 0) { // separator column present string[] inputs, outputs; var qt = SqlQueryNonTimed(sql, c.arrayResults, dbConnName, out inputs, out outputs); Fn func = FuncNonTimedQuery(qt); var colsNames = qt.colsNames.Where(s => s != nameof(START_TIME) && s != nameof(END_TIME) && s != nameof(END_TIME__DT)).ToList(); for (int i = inputs.Length - 1; i >= 0; i--) { if (!ValueInfo.IsID(inputs[i])) { colsNames.RemoveAt(i); } } var fd = new FuncDef(func, c.funcNamesPrefix /* + "_Values"*/, inputs.Length, inputs.Length, ValueInfo.CreateMany(inputs), ValueInfo.CreateMany(colsNames.ToArray()), FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain, c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value) ); fd.xtraAttrs.Add(nameof(QueryTemplate), qt); yield return(fd); yield break; } #endregion #region Range if ((c.ldr.forKinds & DbFuncType.TimeInterval) != 0) { var qt = SqlQueryTimed(sql, DbFuncType.TimeInterval, c.arrayResults, dbConnName); Fn func = FuncTimedRangeQuery(actuality, qt); var fd = new FuncDef(func, c.funcNamesPrefix + "_Range", 3, 3, ValueInfo.CreateMany(qt.colsNames[0], nameof(ValueInfo.A_TIME__XT), nameof(ValueInfo.B_TIME__XT)), resultsInfo, FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain, c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value) ); fd.xtraAttrs.Add(nameof(QueryTemplate), qt); yield return(fd); } #endregion #region Slice at AT_TIME if ((c.ldr.forKinds & DbFuncType.TimeSlice) != 0) { var qt = SqlQueryTimed(sql, DbFuncType.TimeSlice, c.arrayResults, dbConnName); Fn func = FuncTimedSliceQuery(actuality, qt); var fd = new FuncDef(func, c.funcNamesPrefix + "_Slice", 2, 2, ValueInfo.CreateMany(qt.colsNames[0], nameof(ValueInfo.At_TIME__XT)), resultsInfo, FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain, c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value) ); fd.xtraAttrs.Add(nameof(QueryTemplate), qt); yield return(fd); } #endregion #region Raw interval // START_TIME in range MIN_TIME .. MAX_TIME if ((c.ldr.forKinds & DbFuncType.TimeRawInterval) != 0) { var qt = SqlQueryTimed(sql, DbFuncType.TimeRawInterval, c.arrayResults, dbConnName); Fn func = FuncRawIntervalQuery(qt); var fd = new FuncDef(func, c.funcNamesPrefix + "_Raw", 3, 3, ValueInfo.CreateMany(qt.colsNames[0], "MIN_TIME__XT", "MAX_TIME__XT"), resultsInfo, FuncFlags.Defaults, 0, 0, c.ldr.cachingExpiration, c.ldr.cacheSubdomain, c.tblAttrs.ToDictionary(p => p.Key.ToString(), p => p.Value) ); fd.xtraAttrs.Add(nameof(QueryTemplate), qt); yield return(fd); } #endregion #region Insert rows function if ((c.ldr.forKinds & DbFuncType.Insert) != 0) { var qt = SqlCommandInsert(sql, dbConnName, c.DefaultLocationForValueInfo, out var outputs); //todo: Sql insert //Fn func = FuncInsert(qt); } #endregion }
/* ** Memory cell pMem contains the context of an aggregate function. ** This routine calls the finalize method for that function. The ** result of the aggregate is stored back into pMem. ** ** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK ** otherwise. */ private static int sqlite3VdbeMemFinalize(Mem pMem, FuncDef pFunc) { int rc = SQLITE_OK; if (ALWAYS(pFunc != null && pFunc.xFinalize != null)) { sqlite3_context ctx = new sqlite3_context(); Debug.Assert((pMem.flags & MEM_Null) != 0 || pFunc == pMem.u.pDef); Debug.Assert(pMem.db == null || sqlite3_mutex_held(pMem.db.mutex)); //memset(&ctx, 0, sizeof(ctx)); ctx.s.flags = MEM_Null; ctx.s.db = pMem.db; ctx.pMem = pMem; ctx.pFunc = pFunc; pFunc.xFinalize(ctx); /* IMP: R-24505-23230 */ Debug.Assert(0 == (pMem.flags & MEM_Dyn) && pMem.xDel == null); sqlite3DbFree(pMem.db, ref pMem.zBLOB);//zMalloc ); ctx.s.CopyTo(ref pMem);//memcpy(pMem, &ctx.s, sizeof(ctx.s)); rc = ctx.isError; } return rc; }
public int AddOp4(OP op, int p1, int p2, int p3, FuncDef p4, Vdbe.P4T p4t) // FUNCDEF { int addr = AddOp3(op, p1, p2, p3); ChangeP4(addr, new P4_t { Func = p4 }, p4t); return addr; }