Exemplo n.º 1
0
        private static CollSeq[] FindCollSeqEntry(Context ctx, string name, bool create)
        {
            int nameLength = name.Length;

            CollSeq[] coll = ctx.CollSeqs.Find(name, nameLength, (CollSeq[])null);
            if (coll == null && create)
            {
                coll = new CollSeq[3]; //sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
                if (coll != null)
                {
                    coll[0]        = new CollSeq();
                    coll[0].Name   = name;
                    coll[0].Encode = TEXTENCODE.UTF8;
                    coll[1]        = new CollSeq();
                    coll[1].Name   = name;
                    coll[1].Encode = TEXTENCODE.UTF16LE;
                    coll[2]        = new CollSeq();
                    coll[2].Name   = name;
                    coll[2].Encode = TEXTENCODE.UTF16BE;
                    CollSeq[] del  = ctx.CollSeqs.Insert(coll[0].Name, nameLength, coll);
                    CollSeq   del2 = (del != null ? del[0] : null);
                    // If a malloc() failure occurred in sqlite3HashInsert(), it will return the pColl pointer to be deleted (because it wasn't added to the hash table).
                    Debug.Assert(del == null || del2 == coll[0]);
                    if (del2 != null)
                    {
                        ctx.MallocFailed = true;
                        C._tagfree(ctx, ref del2); del2 = null;
                        coll = null;
                    }
                }
            }
            return(coll);
        }
Exemplo n.º 2
0
 public static RC CheckCollSeq(Parse parse, CollSeq coll)
 {
     if (coll != null)
     {
         Context ctx = parse.Ctx;
         CollSeq p   = GetCollSeq(parse, Context.CTXENCODE(ctx), coll, coll.Name);
         if (p == null)
         {
             return(RC.ERROR);
         }
         Debug.Assert(p == coll);
     }
     return(RC.OK);
 }
Exemplo n.º 3
0
        private static RC SynthCollSeq(Context ctx, CollSeq coll)
        {
            string z = coll.Name;

            for (int i = 0; i < 3; i++)
            {
                CollSeq coll2 = Callback.FindCollSeq(ctx, _SynthCollSeq_TextEncodes[i], z, false);
                if (coll2.Cmp != null)
                {
                    coll     = coll2.memcpy();
                    coll.Del = null; // Do not copy the destructor
                    return(RC.OK);
                }
            }
            return(RC.ERROR);
        }
Exemplo n.º 4
0
 public static CollSeq FindCollSeq(Context ctx, TEXTENCODE encode, string name, bool create)
 {
     CollSeq[] colls;
     if (name != null)
     {
         colls = FindCollSeqEntry(ctx, name, create);
     }
     else
     {
         colls = new CollSeq[(int)encode];
         colls[(int)encode - 1] = ctx.DefaultColl;
     }
     Debug.Assert((int)TEXTENCODE.UTF8 == 1 && (int)TEXTENCODE.UTF16LE == 2 && (int)TEXTENCODE.UTF16BE == 3);
     Debug.Assert(encode >= TEXTENCODE.UTF8 && encode <= TEXTENCODE.UTF16BE);
     return(colls != null ? colls[(int)encode - 1] : null);
 }
Exemplo n.º 5
0
        public static CollSeq GetCollSeq(Parse parse, TEXTENCODE encode, CollSeq coll, string name)
        {
            Context ctx = parse.Ctx;
            CollSeq p   = coll;

            if (p == null)
            {
                p = FindCollSeq(ctx, encode, name, false);
            }
            if (p == null || p.Cmp == null)
            {
                // No collation sequence of this type for this encoding is registered. Call the collation factory to see if it can supply us with one.
                CallCollNeeded(ctx, encode, name);
                p = FindCollSeq(ctx, encode, name, false);
            }
            Debug.Assert(p == null || p.Cmp != null);
            if (p != null)
            {
                parse.ErrorMsg("no such collation sequence: %s", name);
            }
            return(p);
        }
Exemplo n.º 6
0
        public static int MemCompare(Mem mem1, Mem mem2, CollSeq coll)
        {
            MEM f1 = mem1.Flags;
            MEM f2 = mem2.Flags;
            MEM cf = f1 | f2;
            Debug.Assert((cf & MEM.RowSet) == 0);

            // If one value is NULL, it is less than the other. If both values are NULL, return 0.
            if ((cf & MEM.Null) != 0)
                return (f2 & MEM.Null) - (f1 & MEM.Null);

            // If one value is a number and the other is not, the number is less. If both are numbers, compare as reals if one is a real, or as integers if both values are integers.
            if ((cf & (MEM.Int | MEM.Real)) != 0)
            {
                if ((f1 & (MEM.Int | MEM.Real)) == 0) return 1;
                if ((f2 & (MEM.Int | MEM.Real)) == 0) return -1;
                if ((f1 & f2 & MEM.Int) == 0)
                {
                    double r1 = ((f1 & MEM.Real) == 0 ? (double)mem1.u.I : mem1.R);
                    double r2 = ((f2 & MEM.Real) == 0 ? (double)mem2.u.I : mem2.R);
                    if (r1 < r2) return -1;
                    if (r1 > r2) return 1;
                    return 0;
                }
                Debug.Assert((f1 & MEM.Int) != 0);
                Debug.Assert((f2 & MEM.Int) != 0);
                if (mem1.u.I < mem2.u.I) return -1;
                if (mem1.u.I > mem2.u.I) return 1;
                return 0;
            }

            // If one value is a string and the other is a blob, the string is less. If both are strings, compare using the collating functions.
            int r;
            if ((cf & MEM.Str) != 0)
            {
                if ((f1 & MEM.Str) == 0) return 1;
                if ((f2 & MEM.Str) == 0) return -1;

                Debug.Assert(mem1.Encode == mem2.Encode);
                Debug.Assert(mem1.Encode == TEXTENCODE.UTF8 || mem1.Encode == TEXTENCODE.UTF16LE || mem1.Encode == TEXTENCODE.UTF16BE);
                // The collation sequence must be defined at this point, even if the user deletes the collation sequence after the vdbe program is
                // compiled (this was not always the case).
                Debug.Assert(coll == null || coll.Cmp != null);
                if (coll != null)
                {
                    if (mem1.Encode == coll.Encode)
                        return coll.Cmp(coll.User, mem1.N, mem1.Z, mem2.N, mem2.Z); // The strings are already in the correct encoding.  Call the comparison function directly
                    else
                    {
                        Mem c1 = C._alloc(c1); //: _memset(&c1, 0, sizeof(c1));
                        Mem c2 = C._alloc(c2); //: _memset(&c2, 0, sizeof(c2));
                        MemShallowCopy(c1, mem1, MEM.Ephem);
                        MemShallowCopy(c2, mem2, MEM.Ephem);
                        string v1 = ValueText(c1, coll.Encode);
                        int n1 = (v1 == null ? 0 : c1.N);
                        string v2 = ValueText(c2, coll.Encode);
                        int n2 = (v2 == null ? 0 : c2.N);
                        r = coll.Cmp(coll.User, n1, v1, n2, v2);
                        MemRelease(c1);
                        MemRelease(c2);
                        return r;
                    }
                }
                // If a NULL pointer was passed as the collate function, fall through to the blob case and use memcmp().
            }
            // Both values must be blobs.  Compare using memcmp().
            if ((mem1.Flags & MEM.Blob) != 0)
                if (mem1.Z_ != null) r = C._memcmp(mem1.Z_, mem2.Z_, (mem1.N > mem2.N ? mem2.N : mem1.N));
                else r = C._memcmp(mem1.Z, mem2.Z_, (mem1.N > mem2.N ? mem2.N : mem1.N));
            else r = C._memcmp(mem1.Z, mem2.Z, (mem1.N > mem2.N ? mem2.N : mem1.N));
            if (r == 0)
                r = mem1.N - mem2.N;
            return r;
        }
Exemplo n.º 7
0
        public static int MemCompare(Mem mem1, Mem mem2, CollSeq coll)
        {
            MEM f1 = mem1.Flags;
            MEM f2 = mem2.Flags;
            MEM cf = f1 | f2;

            Debug.Assert((cf & MEM.RowSet) == 0);

            // If one value is NULL, it is less than the other. If both values are NULL, return 0.
            if ((cf & MEM.Null) != 0)
            {
                return((f2 & MEM.Null) - (f1 & MEM.Null));
            }

            // If one value is a number and the other is not, the number is less. If both are numbers, compare as reals if one is a real, or as integers if both values are integers.
            if ((cf & (MEM.Int | MEM.Real)) != 0)
            {
                if ((f1 & (MEM.Int | MEM.Real)) == 0)
                {
                    return(1);
                }
                if ((f2 & (MEM.Int | MEM.Real)) == 0)
                {
                    return(-1);
                }
                if ((f1 & f2 & MEM.Int) == 0)
                {
                    double r1 = ((f1 & MEM.Real) == 0 ? (double)mem1.u.I : mem1.R);
                    double r2 = ((f2 & MEM.Real) == 0 ? (double)mem2.u.I : mem2.R);
                    if (r1 < r2)
                    {
                        return(-1);
                    }
                    if (r1 > r2)
                    {
                        return(1);
                    }
                    return(0);
                }
                Debug.Assert((f1 & MEM.Int) != 0);
                Debug.Assert((f2 & MEM.Int) != 0);
                if (mem1.u.I < mem2.u.I)
                {
                    return(-1);
                }
                if (mem1.u.I > mem2.u.I)
                {
                    return(1);
                }
                return(0);
            }

            // If one value is a string and the other is a blob, the string is less. If both are strings, compare using the collating functions.
            int r;

            if ((cf & MEM.Str) != 0)
            {
                if ((f1 & MEM.Str) == 0)
                {
                    return(1);
                }
                if ((f2 & MEM.Str) == 0)
                {
                    return(-1);
                }

                Debug.Assert(mem1.Encode == mem2.Encode);
                Debug.Assert(mem1.Encode == TEXTENCODE.UTF8 || mem1.Encode == TEXTENCODE.UTF16LE || mem1.Encode == TEXTENCODE.UTF16BE);
                // The collation sequence must be defined at this point, even if the user deletes the collation sequence after the vdbe program is
                // compiled (this was not always the case).
                Debug.Assert(coll == null || coll.Cmp != null);
                if (coll != null)
                {
                    if (mem1.Encode == coll.Encode)
                    {
                        return(coll.Cmp(coll.User, mem1.N, mem1.Z, mem2.N, mem2.Z)); // The strings are already in the correct encoding.  Call the comparison function directly
                    }
                    else
                    {
                        Mem c1 = C._alloc(c1); //: _memset(&c1, 0, sizeof(c1));
                        Mem c2 = C._alloc(c2); //: _memset(&c2, 0, sizeof(c2));
                        MemShallowCopy(c1, mem1, MEM.Ephem);
                        MemShallowCopy(c2, mem2, MEM.Ephem);
                        string v1 = ValueText(c1, coll.Encode);
                        int    n1 = (v1 == null ? 0 : c1.N);
                        string v2 = ValueText(c2, coll.Encode);
                        int    n2 = (v2 == null ? 0 : c2.N);
                        r = coll.Cmp(coll.User, n1, v1, n2, v2);
                        MemRelease(c1);
                        MemRelease(c2);
                        return(r);
                    }
                }
                // If a NULL pointer was passed as the collate function, fall through to the blob case and use memcmp().
            }
            // Both values must be blobs.  Compare using memcmp().
            if ((mem1.Flags & MEM.Blob) != 0)
            {
                if (mem1.Z_ != null)
                {
                    r = C._memcmp(mem1.Z_, mem2.Z_, (mem1.N > mem2.N ? mem2.N : mem1.N));
                }
                else
                {
                    r = C._memcmp(mem1.Z, mem2.Z_, (mem1.N > mem2.N ? mem2.N : mem1.N));
                }
            }
            else
            {
                r = C._memcmp(mem1.Z, mem2.Z, (mem1.N > mem2.N ? mem2.N : mem1.N));
            }
            if (r == 0)
            {
                r = mem1.N - mem2.N;
            }
            return(r);
        }
Exemplo n.º 8
0
 public void ChangeP4(int addr, CollSeq coll, int n) { ChangeP4(addr, new P4_t { Coll = coll }, n); } // P4_COLLSEQ 
Exemplo n.º 9
0
 public int AddOp4(OP op, int p1, int p2, int p3, CollSeq p4, Vdbe.P4T p4t) // CollSeq
 {
     int addr = AddOp3(op, p1, p2, p3);
     ChangeP4(addr, new P4_t { Coll = p4 }, p4t);
     return addr;
 }