PostgreSQL Source Code: src/backend/utils/adt/like_match.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73#ifdef MATCH_LOWER

74#define GETCHAR(t, locale) MATCH_LOWER(t, locale)

75#else

76#define GETCHAR(t, locale) (t)

77#endif

78

79static int

81{

82

83 if (plen == 1 && *p == '%')

85

86

88

89

90

91

92

93

94

95

96

97 while (tlen > 0 && plen > 0)

98 {

99 if (*p == '\\')

100 {

101

103

104 if (plen <= 0)

106 (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),

107 errmsg("LIKE pattern must not end with escape character")));

110 }

111 else if (*p == '%')

112 {

113 char firstpat;

114

115

116

117

118

119

120

121

122

123

124

125

126

127

129

130 while (plen > 0)

131 {

132 if (*p == '%')

134 else if (*p == '_')

135 {

136

137 if (tlen <= 0)

141 }

142 else

143 break;

144 }

145

146

147

148

149

150 if (plen <= 0)

152

153

154

155

156

157

158

159

160

161

162

163

164 if (*p == '\\')

165 {

166 if (plen < 2)

168 (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),

169 errmsg("LIKE pattern must not end with escape character")));

171 }

172 else

174

175 while (tlen > 0)

176 {

178 {

180

182 return matched;

183 }

184

186 }

187

188

189

190

191

193 }

194 else if (*p == '_')

195 {

196

199 continue;

200 }

202 {

203

204

205

206

207

208

209

210

211 const char *p1;

212 size_t p1len;

213 const char *t1;

214 size_t t1len;

215 bool found_escape;

216 const char *subpat;

217 size_t subpatlen;

218 char *buf = NULL;

219

220

221

222

223

224

225 p1 = p;

226 p1len = plen;

227 found_escape = false;

228 while (p1len > 0)

229 {

230 if (*p1 == '\\')

231 {

232 found_escape = true;

234 if (p1len == 0)

236 (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),

237 errmsg("LIKE pattern must not end with escape character")));

238 }

239 else if (*p1 == '_' || *p1 == '%')

240 break;

242 }

243

244

245

246

247

248 if (found_escape)

249 {

250 char *b;

251

253 for (const char *c = p; c < p1; c++)

254 {

255 if (*c == '\\')

256 ;

257 else

258 *(b++) = *c;

259 }

260

261 subpat = buf;

262 subpatlen = b - buf;

263 }

264 else

265 {

266 subpat = p;

267 subpatlen = p1 - p;

268 }

269

270

271

272

273

274 if (p1len == 0)

275 {

277

279

282 if (cmp == 0)

284 else

286 }

287

288

289

290

291

292

293 t1 = t;

294 t1len = tlen;

295 for (;;)

296 {

298

300

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319 if (cmp == 0)

320 {

322

324 {

327 return matched;

328 }

329 }

330

331

332

333

334

335 if (t1len == 0)

336 {

340 }

341 else

343 }

344 }

346 {

347

349 }

350

351

352

353

354

355

356

357

358

359

360

361

362

365 }

366

367 if (tlen > 0)

368 return LIKE_FALSE;

369

370

371

372

373

374 while (plen > 0 && *p == '%')

376 if (plen <= 0)

378

379

380

381

382

384}

385

386

387

388

389

390#ifdef do_like_escape

391

394{

395 text *result;

396 char *p,

397 *e,

398 *r;

399 int plen,

400 elen;

401 bool afterescape;

402

407

408

409

410

411

414

415 if (elen == 0)

416 {

417

418

419

420

421 while (plen > 0)

422 {

423 if (*p == '\\')

424 *r++ = '\\';

426 }

427 }

428 else

429 {

430

431

432

434 if (elen != 0)

436 (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),

437 errmsg("invalid escape string"),

438 errhint("Escape string must be empty or one character.")));

439

441

442

443

444

445 if (*e == '\\')

446 {

448 return result;

449 }

450

451

452

453

454

455

456 afterescape = false;

457 while (plen > 0)

458 {

459 if (CHAREQ(p, e) && !afterescape)

460 {

461 *r++ = '\\';

463 afterescape = true;

464 }

465 else if (*p == '\\')

466 {

467 *r++ = '\\';

468 if (!afterescape)

469 *r++ = '\\';

471 afterescape = false;

472 }

473 else

474 {

476 afterescape = false;

477 }

478 }

479 }

480

481 SET_VARSIZE(result, r - ((char *) result));

482

483 return result;

484}

485#endif

486

487#ifdef CHAREQ

488#undef CHAREQ

489#endif

490

491#undef NextChar

492#undef CopyAdvChar

493#undef MatchText

494

495#ifdef do_like_escape

496#undef do_like_escape

497#endif

498

499#undef GETCHAR

500

501#ifdef MATCH_LOWER

502#undef MATCH_LOWER

503

504#endif

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

#define CopyAdvChar(dst, src, srclen)

#define NextByte(p, plen)

#define NextChar(p, plen)

static int MatchText(const char *t, int tlen, const char *p, int plen, pg_locale_t locale)

#define GETCHAR(t, locale)

void pfree(void *pointer)

#define CHECK_FOR_INTERRUPTS()

int pg_strncoll(const char *arg1, ssize_t len1, const char *arg2, ssize_t len2, pg_locale_t locale)

static int cmp(const chr *x, const chr *y, size_t len)

void check_stack_depth(void)

#define SET_VARSIZE(PTR, len)

#define VARSIZE_ANY_EXHDR(PTR)